关于Array.map.bind(Array)及Redux中compose相关代码的技术问询
让我一步步帮你拆解这两个问题,搞清楚背后的JavaScript绑定逻辑~
Array.map.bind(Array)的含义 首先得回忆下 JavaScript 里 bind 的核心作用:它会创建一个新函数,把原函数的 this 固定绑定到你传入的对象上,同时还能预设参数。
Array.map 本质上就是数组原型上的 Array.prototype.map(构造函数会继承原型上的方法),正常情况下我们都是通过数组实例调用它,比如 [1,2,3].map(x => x*2),这时候 map 内部的 this 就是这个数组实例。
当执行 Array.map.bind(Array) 时,相当于把 map 方法的 this 强制绑定到 Array 构造函数上,生成了一个新的绑定函数。这种写法最常见的实际用途是把数组的实例方法转换成函数式风格的工具函数——你可以直接把数组作为第一个参数传入,而不是通过数组实例调用:
const map = Array.prototype.map.bind(Array); // 现在可以这样用:map([1,2,3], x => x*2),效果等同于 [1,2,3].map(x => x*2)
简单说就是把实例.方法()的调用形式,转换成方法(实例, 参数)的函数式调用形式。
colors.map.bind(colors)的作用,以及注释后报错的原因 先明确 compose 的执行逻辑:它是从右到左依次执行函数的,所以这段代码的完整流程是:
- 最右边的
state => state.colors先执行,拿到state里的colors数组 - 接着执行
colors => colors.map.bind(colors),返回一个绑定好this的map函数 - 然后执行
map => map(c=>c.title),调用这个绑定好的map函数,传入回调得到所有title组成的数组 - 再执行
titles => titles.join(", "),把数组转成逗号分隔的字符串 - 最后执行
list => console.log(list)打印结果
为什么要用colors.map.bind(colors)?
compose的每一步都需要接收上一步的结果,返回一个值给下一步。这里第三步需要的是一个可调用的函数(因为第三步的逻辑是拿到map后直接调用它),而不是直接拿到处理后的数组。
colors.map.bind(colors)的作用就是:生成一个已经把this绑定到当前colors数组的map函数——这样第三步拿到的是一个可以直接调用的函数,传入回调c=>c.title时,map内部的this已经固定为colors数组,能正确执行数组的map逻辑。
注释掉该行为什么会报错“map is not a function”?
如果注释掉这一行,第二步的结果就直接是state.colors数组了。到第三步时,map => map(c=>c.title)里的map变量其实是这个数组,而不是map方法。你试图把数组当成函数去调用(相当于执行colors(c=>c.title)),但数组本身不是函数,自然就会抛出“map is not a function”的错误。
内容的提问来源于stack exchange,提问作者Vikram Babu Nagineni

