JavaScript函数/方法上下文检查

时间:2013-06-22 13:33:20

标签: javascript

我知道如何使用这些方法来改变函数/方法调用的上下文: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

我想我已经知道了答案,但我想无论如何我会问,如果没有其他原因:1。确认我的假设,或2.学到一些东西。我确信我不是第一个提出这个问题的人,但我不知道如何找到答案,因为我得到的是对如何使用的回应:.apply(),. call()或。绑定()。

3 个答案:

答案 0 :(得分:2)

没有

实际上,将绑定称为“更改”上下文是不正确的。它的作用是将一个函数转换为另一个函数,该函数使用特定的上下文调用第一个函数。

可以通过多种方式绑定函数。例如,我可以自己绑定它:

function bind(fn,ctxt){
    return function(){
        fn.apply(ctxt,arguments);
    };
}

或者,我可以将它与Function.prototype.bind绑定,或者用同样的东西绑定它,或者用下划线的_.bind绑定它。除了上下文之外,我还可以将它绑定到初始参数。在每种情况下,没有办法在没有实际执行函数的情况下判断发生了什么。

绑定只是将一个函数转换为另一个函数的众多方法之一。我也可以将函数转换为从现在开始执行一秒,或者执行两次。绑定没有什么魔力;它只是创建一个基于旧功能的新功能。在您可能能够检查的函数上没有设置名为[[bound_to]]的特殊变量(除非您使用自己的自定义bind实现,如另一个答案所示)。事后没有办法确定函数的转换方式。

我能想象到的最接近的是检查未绑定版本的可能绑定函数,看看它们是否相等。

function log_this(){console.log(this);}
var bound_func=log_this.bind(my_var);
console.log(log_this===bound_func); // FALSE

答案 1 :(得分:0)

可以做的是这样的事情:

function f(context, whatever) {
    if(this !== context) {
        //context has been changed
    }
}

var y = f.bind(thingy);
y(otherThingy, something);

你也可以有一个自定义绑定功能,并且有一种这样的黑客攻击:

function bind(func, context) {     
    var newFunc = func.bind(context);
    newFunc._this = context;
    return newFunc;
}

function checkContext(func, context) {
    return func._this !== context;
}

答案 2 :(得分:-1)

我认为对于那些喜欢JavaScirpt的人来说这是一个有趣的问题,我希望这是对你所寻找的回应:


var isContextSet = function (fn) {
   var testThis = {}; //unique object for testing what is this inside fn
   return fn.call(testThis) !== testThis;
}

我尝试在 fn fn.call(testThis);内“设置”这个,如果该函数返回对新创建的对象的引用( testThis )然后它没有绑定。我希望你明白:)

修改: fn 重新调整时(如所示),这是有效的。否则你无法正确定义isContextSet。