鉴于以下示例(如果您使用的是jsfiddle链接,请单击右侧的“内容”),为什么self
在达到clickHelper()
时会超出范围?
我可以想出两种方法来解决它...(1)我可以将其作为参数传递,或者(2)我可以在插件内部定义var self;
(function clickHelper()
以上)。
我不想做#1,因为在我的实际实现中,我已经有一堆参数和一堆辅助函数......我希望使用范围来避免传递self
到处都是。
我不想使用#2,因为看起来如果这个插件用于页面上的多个元素,可能会有竞争条件......我的假设是jQuery有1个插件实例,并且因此var self
只会存在一次。
我基本上都在寻找将this
保留在为jQuery插件引发的click事件范围内的最佳实践。
<div id="a1">
content
</div>
<script type="text/javascript">=
function info(n, s) {
var id = (typeof (s.id) == "undefined") ? '' : ': ' + s.id;
alert(n + ': ' + s + ': ' + typeof (s) + id);
}
(function ($) {
$.fn.myPlugin = function () {
function clickHelper() {
info('self in the Helper...', self);
self.innerHTML += '2';
}
function clickHandler() {
var self = this;
info('self in the Handler', self);
self.innerHTML += '1';
clickHelper();
}
this.bind('click', clickHandler);
};
}(jQuery));
$(function () {
$('#a1').myPlugin();
});
</script>
ETA:#1可能是最好的选择,如果你不介意额外的参数,因为#2会出现竞争条件/线程安全问题,如所示here(点击内容1 ,好的,然后内容2真的很快)。你可以通过在处理程序方法中定义你的帮助器方法来解决问题{2},这可能适用于你的所有帮助方法都支持你的处理程序方法。我想,#3,而不是像通常clickHelper()
那样调用JavaScript函数,只需使用正确的闭包function(this) { var self = this; clickHelper() };
。
答案 0 :(得分:1)
<强> Guide on closures and scoping 强>
变量仅适用于创建它们的函数。因此,通过在self
内创建clickHelper
,您只能将其作为clickHelpers
函数的局部变量。
将其移动到myPlugins
范围内,现在可以访问嵌套函数。
<强> Live Demo 强>
$.fn.myPlugin = function () {
var self = {}; // self declared here instead can be used within this scope now
function clickHelper() {
info('self in the Helper...', self);
self.innerHTML += '2';
}
function clickHandler() {
self = this;
info('self in the Handler', self);
self.innerHTML += '1';
clickHelper();
}
this.bind('click', clickHandler);
};