我正在处理每个都绑定(bind)到特定上下文的函数。在代码的其他地方,我必须用可变数量的参数调用它们。通常,我会用 apply 来做,但这会改变上下文( this )。

我可以在不改变函数中apply( null, args )的现有绑定(bind)值的情况下实现this的效果吗?

(当调用需要发生时,我手头没有函数 this 的值在变量中。)

顺便说一句,这里的问题不是 that one 的重复,尽管标题很有希望,但 OP 只是试图将语法糖添加到方法调用中。

最佳答案

令人惊讶的是,事实证明这不是问题。如果函数绑定(bind)到上下文,则可以使用 apply 安全地调用它,而无需更改上下文。
apply 的第一个参数可以设置为任何值 - undefinednullwindow ,另一个对象。如果函数被绑定(bind),它没有任何影响。

例子:

var o = { id: "foo" },
    args = [ "bar", "baz" ],
    f = function () {
      var args = Array.prototype.slice.call( arguments ).join( ", ");
      return "Called in the context of " + this.id + " with args " + args;
    },

    // Binding f to o with ES5 bind
    boundNative = f.bind( o ),

    // Binding f to o with a closure
    boundWithClosure = ( function ( context ) {
        return function () {
            return f.apply( context, arguments );
        }
    } )( o );

// Does boundNative.apply( whatever, args ) change the context?
console.log( boundNative.apply( undefined, args ) );
console.log( boundNative.apply( null, args ) );
console.log( boundNative.apply( window, args ) );
console.log( boundNative.apply( { id: "quux" }, args ) );

// Same test with the closure
console.log( boundWithClosure.apply( undefined, args ) );
console.log( boundWithClosure.apply( null, args ) );
console.log( boundWithClosure.apply( window, args ) );
console.log( boundWithClosure.apply( { id: "quux" }, args ) );

所有调用都返回“在 foo 的上下文中使用 args bar, baz 调用”,所以没问题。

我不得不承认这个结果起初让我感到惊讶。毕竟,apply 强制执行上下文——怎么会被忽略?但事实上,这是完全有道理的。

是的,原始函数 ( f ) 引用 this ,用 apply 调用它会改变它的值。但是我们没有调用原始函数。

绑定(bind)函数是一个完全独立的实体,它不再引用 this。 ES5 bind 并不是那么明显,但是闭包结构却暴露了它。 this 关键字不会出现在 IIFE 返回的函数中的任何地方。调用它,apply 没有什么可以改变的。

关于javascript - 如何在不改变上下文的情况下将参数数组传递给函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30163073/

10-12 12:25
查看更多