5

I know how to use the methods for changing the context of a function/method call: apply, bind, call. My question is this, is there a way to check if a function/method has already had its context set?

// 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

I think I know the answer to this already but thought I would ask anyway, if for no other reasons than: 1. confirm my assumption, or 2. learn something. I'm sure that I am not the first to ask this question but I have had no idea on how to actually find an answer since all I get are responses to how to use: .apply(), .call(), or .bind().

4

3 回答 3

3

不。

实际上,将绑定称为“改变”上下文是不正确的。它所做的是将一个函数转换为另一个调用具有特定上下文的第一个函数的函数。

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

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

或者,我可以将它与 Function.prototype.bind 或执行相同操作的 shim 或下划线的 _.bind 绑定。除了上下文之外,我还可以将它绑定到初始参数。在每种情况下,如果不实际执行函数,就无法判断发生了什么。

绑定只是将一个函数转换为另一个函数的众多方法之一。我还可以将函数转换为从现在开始执行一秒钟,或者执行两次。绑定没有什么神奇之处。它只是在旧函数的基础上创建一个新函数。在您可能能够检查的函数上没有设置名为 [[bound_to]] 的特殊变量(除非您使用自己的自定义绑定实现,正如另一个答案所暗示的那样)。没有事后的方法来确定函数是如何转换的。

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

function log_this(){console.log(this);}
var bound_func=log_this.bind(my_var);
console.log(log_this===bound_func); // FALSE
于 2013-06-22T13:52:29.603 回答
0

可以做的是这样的:

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

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

你也可以有一个自定义的绑定函数,并有一种像这样的 hack:

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

function checkContext(func, context) {
    return func._this !== context;
}
于 2013-06-22T13:50:55.710 回答
-1

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


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

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

编辑: 这在fn重新调整时有效(如问题所示)。否则无法正确定义 isContextSet。

于 2013-06-22T13:52:54.033 回答