如果从存储的变量调用jquery函数,则绑定不正确

时间:2013-06-26 19:37:47

标签: javascript jquery closures this

我以两种方式调用jQuery函数,一种是另一种方法,因为this绑定不正确。

$('#my-div').fadeOut();

按预期工作,this函数中fadeOut的值是jQuery对象。

var fadeOutFn = $('#my-div').fadeOut;
fadeOutFn();

不起作用,因为this的值现在是Window

这是两个例子的jsfiddle。

http://jsfiddle.net/XCAdP/

编辑:对我发布问题的原因进行一些澄清,我真的不想知道如何解决这个问题。那不是问题。我想知道为什么会这样。

2 个答案:

答案 0 :(得分:2)

是的,它不知道它正在应用fadeOut动画的元素,而this上下文主要是窗口而不是jquery对象。您可以使用function.call

传递上下文

试试这个:

var fadeOutFn = $('#my-div').fadeOut;
fadeOutFn.call($('#my-div'));

或者只是这样做:

使用function.bind将上下文绑定到函数引用,然后调用它。

var fadeOutFn = $().fadeOut.bind($('#my-div'));
fadeOutFn();

阅读function.bind

对于不受支持的浏览器,您可以在js文件中添加它以获得支持,如文档中所述:

if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5 internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1), 
        fToBind = this, 
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                                 ? this
                                 : oThis,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

答案 1 :(得分:2)

是的,当您将方法作为函数引用时,将其与对象断开连接。当您在对象的上下文中调用函数时,函数仅用作方法,这通常使用.运算符来完成,例如, obj.method()

如果在没有对象上下文的情况下调用函数,则使用全局作用域作为上下文调用它,即window对象。例如:

var obj = {
  name: "obj",
  method: function() { alert(this.name); }
};

obj.method(); // shows the name "obj"
var m = obj.method;
m(); // shows the name of window
m.call(obj); // shows the name "obj"

var obj2 = {
  name: "obj2"
};
m.call(obj2); // shows the name "obj2" (using the method from obj)

如果你想让它作为一个方法工作,你必须用对象作为上下文来调用它:

var obj = $('#my-div');
var fadeOutFn = obj.fadeOut;
fadeOutFn.call(obj);

您可以使用proxy method创建一个使用正确的上下文调用函数的函数:

var obj = $('#my-div');
var fadeOutFn = $.proxy(obj.fadeOut, obj);
fadeOutFn();