数组 forEach 将“push”作为参数传递

Posted

技术标签:

【中文标题】数组 forEach 将“push”作为参数传递【英文标题】:Array forEach pass "push" as argument 【发布时间】:2016-12-31 12:57:05 【问题描述】:

在 JS 中遇到奇怪的问题。我收到错误:

let a = []
let b = [1,2,3]
b.forEach(a.push)
TypeError: Array.prototype.push called on null or undefined
    at Array.forEach (native)
    at repl:1:3
    at REPLServer.defaultEval (repl.js:262:27)
    at bound (domain.js:287:14)
    at REPLServer.runBound [as eval] (domain.js:300:12)
    at REPLServer.<anonymous> (repl.js:431:12)
    at emitOne (events.js:82:20)
    at REPLServer.emit (events.js:169:7)
    at REPLServer.Interface._onLine (readline.js:211:10)
    at REPLServer.Interface._line (readline.js:550:8)

当然,我提出了一个建议,即上下文丢失了。所以,我尝试通过这种方式来实现:

b.forEach([].push.bind(a))

结果变得不可预测:

[ 1, 0, [ 1, 2, 3 ], 2, 1, [ 1, 2, 3 ], 3, 2, [ 1, 2, 3 ] ]

什么? =) 0 来自哪里?好吧,也许是它的“故障”索引,但为什么不先呢? :)

为了清楚起见,这是一种经典的方式,这不是问题:

b.forEach(el => a.push(el) )

有人能解释一下这种奇怪的行为吗?

【问题讨论】:

【参考方案1】:

基本上按照forEach 的标准语法,它有3 个不同的参数,current itemindex 和调用forEach 的array。因此,与a 绑定的push 函数将在每次使用这些参数时被调用。这就是这里的问题。

iteration 1 : a.push(1,0,[1,2,3]) //since a was bound with push
iteration 2 : a.push(2,1,[1,2,3])
iteration 3 : a.push(3,2,[1,2,3])

您的代码将像上面一样执行。

【讨论】:

长话短说:OP 在试图编写“智能”代码时开枪打死了自己。教训:避免编写“智能”代码。 :) 谢谢,我不应该错过这个。【参考方案2】:

因为.forEach() 为您的回调提供了 3 个参数。

使用三个参数调用回调:

    元素值 元素索引 被遍历的数组

.push() 可以接受任意数量的参数。因此,在每次迭代中,.push() 将这三个参数添加到您的数组中。

【讨论】:

感谢您的回答,现在更清楚了。

以上是关于数组 forEach 将“push”作为参数传递的主要内容,如果未能解决你的问题,请参考以下文章

数组作为函数参数

c语言 字符串传参问题

深入理解带参方法-----对象作为参数的方法

C语言中如何将二维字符数组作为函数参数引用传递

C语言中,数组名作为函数参数,属于啥传递,为啥?

WebApi 接口参数不再困惑:传参详解