我知道如何使用这些方法来改变函数/方法调用的上下文:apply,bind,call.我的问题是,有没有办法检查一个函数/方法是否已经设置了它的上下文?
// given
var beta;
function alpha () {
return this;
}
function isContextSet (fn) {
/* check for context binding on fn */
}
beta = alpha.bind("hello");
isContextSet(alpha); // returns false
isContextSet(beta); // returns true
Run Code Online (Sandbox Code Playgroud)
我想我已经知道了答案,但我想无论如何我会问,如果没有其他原因:1.确认我的假设,或2.学到一些东西.我确信我不是第一个提出这个问题的人,但我不知道如何找到答案,因为我得到的是对如何使用的回应:.apply(),. call()或.绑定().
小智 3
不。
实际上,将绑定称为“改变”上下文是不正确的。它的作用是将一个函数转换为另一个函数,该函数在特定上下文中调用第一个函数。
函数可以通过多种方式绑定。例如,我可以自己绑定它:
function bind(fn,ctxt){
return function(){
fn.apply(ctxt,arguments);
};
}
Run Code Online (Sandbox Code Playgroud)
或者,我可以使用 Function.prototype.bind 或执行相同操作的垫片或下划线的 _.bind 来绑定它。除了上下文之外,我还可以将它绑定到初始参数。在每种情况下,如果不实际执行该函数,就无法判断发生了什么。
绑定只是将一种功能转换为另一种功能的多种方法之一。我还可以将函数转换为从现在起一秒后执行,或者执行两次。绑定并没有什么神奇之处。它只是在旧函数的基础上创建一个新函数。您可以检查的函数上没有设置名为 [[bound_to]] 的特殊变量(除非您使用自己的自定义绑定实现,如另一个答案所示)。没有事后方法可以确定函数是如何转换的。
我能想象到的最接近的结果是检查可能绑定的函数与未绑定的版本,看看它们是否相等。
function log_this(){console.log(this);}
var bound_func=log_this.bind(my_var);
console.log(log_this===bound_func); // FALSE
Run Code Online (Sandbox Code Playgroud)