我正在处理每个绑定到特定上下文的函数。在代码中的其他地方,我必须使用可变数量的参数来调用它们。通常,我会使用apply
执行此操作,但这会更改上下文(this
)。
我可以在不更改函数中apply( null, args )
的现有绑定值的情况下实现this
的效果吗?
(当调用需要发生时,我没有变量中函数this
的值。)
顺便提一下,这里的问题不是that one的重复,尽管有很好的标题,OP只是试图将语法糖添加到方法调用中。
答案 0 :(得分:1)
令人惊讶的是,事实证明这不是问题。如果函数绑定到上下文,则可以使用apply
安全地调用它,而不会更改上下文。
apply
的第一个参数可以设置为任何内容 - undefined
,null
,window
,另一个对象。如果函数绑定,它没有任何效果。
示例:
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 ) );
所有调用返回“使用args bar,baz在foo的上下文中调用”,所以没问题。
我必须承认这个结果一开始让我感到惊讶。毕竟,apply
强制执行一个上下文 - 怎么被忽略?但实际上它很有道理。
是的,原始函数(f
)引用this
,并使用apply
调用它会更改其值。但我们并没有调用原来的功能。
绑定函数是一个完全独立的实体,它不再引用this
。 ES5 bind
并不是那么明显,但是闭包构造将它放弃了。 this
关键字不会出现在IIFE返回的函数中的任何位置。调用它,apply
无法改变。
答案 1 :(得分:0)
上下文始终存在,它可以是全局对象(窗口)或某个特定对象的上下文。当你调用一个函数时,它会使用一些上下文。你也一定要访问它。该函数存在于可见范围内(上下文和范围不同)
var text = "Current context is ";
function A() {
this.test = "A";
this.print = function(msg) {
return msg + this.test;
}
};
function B() {
this.test = "B";
}
var testObj = {
test: "testObj"
};
test = "window";
var msgFn = function (msg) {
return msg + "msgFn";
}
var a = new A();
var b = new B();
a.print.apply(a, [text]); // Current context is A
a.print.apply(b, [text]); // Current context is B
a.print.apply(null, [text]); // Current context is window
a.print.apply(testObj, [text]); // Current context is testObj
msgFn.apply(msgFn, [text]); // // Current context is msgFn