jQuery 在 setTimeout 中使用 "this" 的多实例插件
jQuery multiple instance plugin using "this" in setTimeout
我正在尝试编写一个新插件,它可以在同一页面内的多个元素上初始化,每次都有不同的选项,例如:
$('#id').plugin({ option:true });
$('#id2').plugin({ option:false });
我正在使用来自 jqueryboilerplate.com (https://github.com/jquery-boilerplate/jquery-boilerplate) 的样板文件。我理解(至少我认为我理解!)问题是在匿名函数的范围内(这里,在 setTimeout 内)'this' 指的是 window。所以在下面,第一次记录输出,而不是第二次:
// Avoid Plugin.prototype conflicts
$.extend(Plugin.prototype, {
init: function () {
console.log(this.settings.propertyName);
setTimeout(function(){
console.log(this.settings.propertyName);
}, 1000);
}
});
其他地方 this.settings.propertyName 设置为 'value'。 Console.log 结果是:
value
Uncaught TypeError: Cannot read property 'propertyName' of undefined
例如,如果我设置 window.prop = this.settings.propertyName 和 console.log window.prop,那是可行的,但问题是可能有很多实例 运行 同时.
我已经阅读了很多与此主题相关的问题,但 none 似乎确实解决了这种特殊情况。如果有人能给我一个清楚的例子,说明如何在 jQuery 插件的上下文中使用样板或类似的东西来做到这一点,我将不胜感激。请原谅我的笨拙,谢谢!!
捕获 this
上的闭包:
$.extend(Plugin.prototype, {
init: function () {
var _this = this;
console.log(this.settings.propertyName);
setTimeout(function(){
console.log(_this.settings.propertyName);
}, 1000);
}
});
setTimeout
作为 window.setTimeout
执行,因此 setTimeout
处理程序的上下文设置为 window
对象。如果你想改变它的上下文,你可以使用 bind()
.
setTimeout(function () {
// this.xyz
// use this here
}.bind(this), 1000);
bind
会将 setTimeout 外部的上下文绑定到其中的上下文。
引用https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
您还可以缓存上下文并在 setTimeout
.
中使用它
// Avoid Plugin.prototype conflicts
$.extend(Plugin.prototype, {
init: function () {
var self = this; // Cache context
setTimeout(function () {
console.log(self.settings.propertyName); // Use cached context instead of `this`
}, 1000);
}
});
这是因为超时中的this
引用了window对象。通过在函数外部保留一个引用可以很容易地修复它:
// Avoid Plugin.prototype conflicts
$.extend(Plugin.prototype, {
init: function () {
console.log(this.settings.propertyName);
var self = this;
setTimeout(function(){
console.log(self.settings.propertyName); //Use your reference here.
}, 1000);
}
});
如果出于某种原因您不希望引用带有变量,您始终可以在使用它之前使用 Function.prototype.bind
. Be sure to check the compatibility。 .bind
所做的只是在更改 this
值和参数的同时返回一个新函数。你可以这样使用它:
// Avoid Plugin.prototype conflicts
$.extend(Plugin.prototype, {
init: function () {
console.log(this.settings.propertyName);
setTimeout(function(){
console.log(this.settings.propertyName);
}.bind(this), 1000);
}
});
我正在尝试编写一个新插件,它可以在同一页面内的多个元素上初始化,每次都有不同的选项,例如:
$('#id').plugin({ option:true });
$('#id2').plugin({ option:false });
我正在使用来自 jqueryboilerplate.com (https://github.com/jquery-boilerplate/jquery-boilerplate) 的样板文件。我理解(至少我认为我理解!)问题是在匿名函数的范围内(这里,在 setTimeout 内)'this' 指的是 window。所以在下面,第一次记录输出,而不是第二次:
// Avoid Plugin.prototype conflicts
$.extend(Plugin.prototype, {
init: function () {
console.log(this.settings.propertyName);
setTimeout(function(){
console.log(this.settings.propertyName);
}, 1000);
}
});
其他地方 this.settings.propertyName 设置为 'value'。 Console.log 结果是:
value
Uncaught TypeError: Cannot read property 'propertyName' of undefined
例如,如果我设置 window.prop = this.settings.propertyName 和 console.log window.prop,那是可行的,但问题是可能有很多实例 运行 同时.
我已经阅读了很多与此主题相关的问题,但 none 似乎确实解决了这种特殊情况。如果有人能给我一个清楚的例子,说明如何在 jQuery 插件的上下文中使用样板或类似的东西来做到这一点,我将不胜感激。请原谅我的笨拙,谢谢!!
捕获 this
上的闭包:
$.extend(Plugin.prototype, {
init: function () {
var _this = this;
console.log(this.settings.propertyName);
setTimeout(function(){
console.log(_this.settings.propertyName);
}, 1000);
}
});
setTimeout
作为 window.setTimeout
执行,因此 setTimeout
处理程序的上下文设置为 window
对象。如果你想改变它的上下文,你可以使用 bind()
.
setTimeout(function () {
// this.xyz
// use this here
}.bind(this), 1000);
bind
会将 setTimeout 外部的上下文绑定到其中的上下文。
引用https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
您还可以缓存上下文并在 setTimeout
.
// Avoid Plugin.prototype conflicts
$.extend(Plugin.prototype, {
init: function () {
var self = this; // Cache context
setTimeout(function () {
console.log(self.settings.propertyName); // Use cached context instead of `this`
}, 1000);
}
});
这是因为超时中的this
引用了window对象。通过在函数外部保留一个引用可以很容易地修复它:
// Avoid Plugin.prototype conflicts
$.extend(Plugin.prototype, {
init: function () {
console.log(this.settings.propertyName);
var self = this;
setTimeout(function(){
console.log(self.settings.propertyName); //Use your reference here.
}, 1000);
}
});
如果出于某种原因您不希望引用带有变量,您始终可以在使用它之前使用 Function.prototype.bind
. Be sure to check the compatibility。 .bind
所做的只是在更改 this
值和参数的同时返回一个新函数。你可以这样使用它:
// Avoid Plugin.prototype conflicts
$.extend(Plugin.prototype, {
init: function () {
console.log(this.settings.propertyName);
setTimeout(function(){
console.log(this.settings.propertyName);
}.bind(this), 1000);
}
});