jQuery 插件范围问题
鉴于下面的示例(如果您使用 jsfiddle 链接,请单击右侧的“内容”),为什么 self
在到达 clickHelper()
时会超出范围?
我可以想到两种方法来修复它......(1)我可以将它作为参数传递,或者(2)我可以在插件内部定义 var self;
(上面 函数 clickHelper()
)。
但我不想做#1,因为在我的实际实现中,我已经有一堆参数和一堆辅助函数......我希望使用作用域来避免传递 self
周围到处都是。
我不想使用#2,因为如果这个插件用于页面上的多个元素,可能会出现竞争条件...我的假设是 jQuery 有 1 个插件实例,因此 var self
只会存在一次。
我基本上正在寻找将 this
保留在为 jQuery 插件引发的单击事件范围内的最佳实践。
<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>
预计到达时间:此处(单击内容 1,好的,然后快速单击内容 2)。您可以通过在处理程序方法中定义辅助方法来摆脱#2,如此处所示,这可能如果您的所有辅助方法所做的都是支持您的处理程序方法,那么对您来说效果很好。 #3,我想,不要像通常那样调用 JavaScript 函数 clickHelper()
,而只需使用适当的闭包 function(this) { var self = this; } clickHelper() };
.
Given the example below (click "content" on the right if you're using the jsfiddle link), why does self
fall out of scope when it reaches the clickHelper()
?
I can think of two ways to fix it... (1) I can pass it in as an argument, or (2) I can define var self;
inside of the plugin (above function clickHelper()
).
I don't want to do #1 though, because in my real implementation, I have a bunch of arguments already and a bunch of helper functions... I was hoping to use scope to avoid passing self
around everywhere.
And I don't want to use #2 because it seems like if this plugin was used for multiple elements on the page, there could be race conditions... my assumption is that jQuery has 1 instance of the plugin, and therefore var self
would only exist once.
I'm basically looking for the best practice of keeping this
in scope inside of click event raised for a jQuery plugin.
<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 is probably the best bet if you don't mind the extra arguments, because #2 does race condition/thread safe issues as demonstrated here (click content 1, ok, and then content 2 really quick). You can get away with #2 by defining your helper methods inside your handler method as demonstrated here, which might work well for your if all your helper methods do is support your handler method. And #3, I suppose, instead of calling JavaScript functions like you normally would clickHelper()
, just use a proper closure function(this) { var self = this; clickHelper() };
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
闭包和作用域指南
变量仅适用于创建它们的函数。因此,通过在
clickHelper
内部创建self
,您可以将其设为仅clickHelpers
函数的局部变量。通过将其移至 myPlugins 范围,现在可以通过嵌套函数访问它。
现场演示
Guide on closures and scoping
Variables are only available to the functions in which they are created. So by creating
self
inside ofclickHelper
you are making it a local variable only to theclickHelpers
function.By moving it into
myPlugins
scope its now accessible to the nested functions.Live Demo