【问题标题】:MDN bind why concat arguments when calling applyMDN绑定为什么调用apply时concat参数
【发布时间】:2012-10-11 19:02:10
【问题描述】:

MDN 为那些没有原生绑定方法的浏览器指定了一个 polyfill 绑定方法:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind

这段代码有以下一行:

aArgs.concat(Array.prototype.slice.call(arguments))

作为参数传递给函数的apply方法:

fToBind.apply(this instanceof fNOP && oThis
                             ? this
                             : oThis,
                           aArgs.concat(Array.prototype.slice.call(arguments)));

但是,这一行实际上重复了参数,所以如果我将绑定方法称为:

fnX.bind({value: 666}, 1, 2, 3)

传递给 fnX 的参数是:

[1, 2, 3, Object, 1, 2, 3] 

运行以下示例,查看控制台输出http://jsfiddle.net/dtbkq/

但是 fnX 报告的参数是 [1, 2, 3] 这是正确的。有人可以解释为什么 args 在传递给 apply 调用时重复但没有出现在函数参数变量中吗?

【问题讨论】:

    标签: javascript bind apply


    【解决方案1】:

    arguments 有两个不同的上下文。每次调用一个函数时,除其他外,一个arguments 对象被设置为所有传递的参数(如果arguments 被访问)。

    第一次提到argumentsbind() 的参数,它将成为初始参数。

    第二次提到的是在绑定代理函数上调用的下一组参数。因为arguments 名称会影响其父arguments(以及需要分离的this 上下文),所以它们存储在名称aArgs 下。

    这允许部分函数应用(有时称为currying)。

    var numberBases = parseInt.bind(null, "110");
    
    console.log(numberBases(10));
    console.log(numberBases(8));
    console.log(numberBases(2));
    

    jsFiddle.

    【讨论】:

    • @Matt 那么你对时间的定义一定很有趣;)
    • 是的,没有意识到显示顺序不是基于时间的,你去吧
    【解决方案2】:

    没有。当您从 x 登录时,x() arguments:[1, 2, 3]

    来自bind2console.log(aArgs.concat(Array.prototype.slice.call(arguments)));,其中aArgs = Array.prototype.slice.call(arguments, 1)。那么除了 [1, 2, 3, {value: 666}, 1, 2, 3] 你还能期待什么呢?这些不是传递给 fnX 的 arguments,而是传递给 bind 的:[{value: 666}, 1, 2, 3]

    在绑定函数内部,aArgs 变量仍包含 [1, 2, 3],而 arguments 现在为空 - 您确实调用了 x()

    【讨论】:

    • 见上文,console.log 调用超出范围
    • 是的,正如我所说 - 你记录了bind 的参数加上aArgs,它们是bind 的切片参数。
    【解决方案3】:

    如果您改为从fBound 中检查aArgs.concat(Array.prototype.slice.call(arguments)) 的值,您会看到您所期望的。关键是 arguments 是指在已经绑定的函数上调用的附加参数。

    【讨论】:

    • 谢谢你想通了——你显然可以像 x(4) 一样将参数传递给 x(),这是连接到绑定 args 的额外 args。
    猜你喜欢
    • 2014-05-30
    • 2021-09-09
    • 2014-12-02
    • 2015-03-27
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多