Javascript 如果从存储的变量调用jquery函数,则绑定不正确
我用两种方法调用jQuery函数,一种有效,另一种无效,因为Javascript 如果从存储的变量调用jquery函数,则绑定不正确,javascript,jquery,closures,this,Javascript,Jquery,Closures,This,我用两种方法调用jQuery函数,一种有效,另一种无效,因为这的绑定不正确 $('#我的div').fadeOut() 正如预期的那样工作,fadeOut函数中的this的值是jQuery对象 var fadeOutFn = $('#my-div').fadeOut; fadeOutFn(); 由于此的值现在是窗口 下面是两个示例的JSFIDLE 编辑:添加一些关于我为什么发布这个问题的澄清,我真的不想知道如何解决这个问题。这不是问题所在。我想了解它发生的原因。是的,它不知道它正在应用fad
这
的绑定不正确
$('#我的div').fadeOut()代码>
正如预期的那样工作,fadeOut
函数中的this
的值是jQuery对象
var fadeOutFn = $('#my-div').fadeOut;
fadeOutFn();
由于此
的值现在是窗口
下面是两个示例的JSFIDLE
编辑:添加一些关于我为什么发布这个问题的澄清,我真的不想知道如何解决这个问题。这不是问题所在。我想了解它发生的原因。是的,它不知道它正在应用fadeOut
动画的元素,并且在这种情况下,
上下文主要是窗口,而不是jquery对象。您可以使用函数传递上下文。调用
试试这个:
var fadeOutFn = $('#my-div').fadeOut;
fadeOutFn.call($('#my-div'));
或者干脆这样做:
使用function.bind将上下文绑定到函数引用,并调用它
var fadeOutFn = $().fadeOut.bind($('#my-div'));
fadeOutFn();
阅读
对于不受支持的浏览器,您可以将其添加到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;
};
}
是的,它不知道它正在应用fadeOut
动画的元素,并且在这种情况下,这个上下文主要是窗口,而不是jquery对象。您可以使用函数传递上下文。调用
试试这个:
var fadeOutFn = $('#my-div').fadeOut;
fadeOutFn.call($('#my-div'));
或者干脆这样做:
使用function.bind将上下文绑定到函数引用,并调用它
var fadeOutFn = $().fadeOut.bind($('#my-div'));
fadeOutFn();
阅读
对于不受支持的浏览器,您可以将其添加到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;
};
}
是的,当您获得一个方法作为函数引用时,您将其与对象断开连接。函数仅在对象上下文中调用时作为方法使用,这通常是通过
操作符完成的,例如obj.method()
如果在没有对象上下文的情况下调用函数,则会以全局范围作为上下文调用它,即窗口
对象。例如:
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);
您可以使用创建一个函数,该函数使用正确的上下文调用该函数:
var obj = $('#my-div');
var fadeOutFn = $.proxy(obj.fadeOut, obj);
fadeOutFn();
是的,当您获得一个方法作为函数引用时,您将其与对象断开连接。函数仅在对象上下文中调用时作为方法使用,这通常是通过
操作符完成的,例如obj.method()
如果在没有对象上下文的情况下调用函数,则会以全局范围作为上下文调用它,即窗口
对象。例如:
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);
您可以使用创建一个函数,该函数使用正确的上下文调用该函数:
var obj = $('#my-div');
var fadeOutFn = $.proxy(obj.fadeOut, obj);
fadeOutFn();
我认为关键是调用时不必重复#my div
。@Barmar第二个如何使用bind。在这种情况下就不会重复了。bind
mehod在一些稍旧的浏览器中不起作用,比如IE8。请改用jQuery.proxy
方法。@PSL:既然已经包含jQuery,为什么还要添加另一个库?它不是库。。只是本机javascript ecmascript标准。但我不知道jquery是否已经包含了它…:)但你的解决方案也很好。我总是忘记$。Proxy我想关键是调用它时不必重复#我的div
。@Barmar第二个如何使用bind。在这种情况下就不会重复了。bind
mehod在一些稍旧的浏览器中不起作用,比如IE8。请改用jQuery.proxy
方法。@PSL:既然已经包含jQuery,为什么还要添加另一个库?它不是库。。只是本机javascript ecmascript标准。但我不知道jquery是否已经包含了它…:)但你的解决方案也很好。对于$.proxy,我总是忘记$.proxyMy+1。我总是忘记这件事。但是我认为我们可以避免对象的消失。我对这个问题补充了一些解释。我不是在寻找解决方法,我只是想了解它发生的原因以及如何解释。@Keivan:我添加了一个更具描述性的解释来解释原因。My+1代表$.proxy。我总是忘记这件事。但是我认为我们可以避免对象的消失。我对这个问题补充了一些解释。我不是在寻找解决办法,我只是想了解为什么会发生这种情况以及如何解释。@Keivan:我为原因添加了更具描述性的解释。