jQuery 插件范围问题

发布于 2024-12-26 22:32:21 字数 1802 浏览 0 评论 0原文

鉴于下面的示例(如果您使用 jsfiddle 链接,请单击右侧的“内容”),为什么 self 在到达 clickHelper() 时会超出范围?

我可以想到两种方法来修复它......(1)我可以将它作为参数传递,或者(2)我可以在插件内部定义 var self; (上面 函数 clickHelper())。

但我不想做#1,因为在我的实际实现中,我已经有一堆参数和一堆辅助函数......我希望使用作用域来避免传递 self周围到处都是。

我不想使用#2,因为如果这个插件用于页面上的多个元素,可能会出现竞争条件...我的假设是 jQuery 有 1 个插件实例,因此 var self 只会存在一次。

我基本上正在寻找将 this 保留在为 jQuery 插件引发的单击事件范围内的最佳实践。

http://jsfiddle.net/QZc9v/

<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.

http://jsfiddle.net/QZc9v/

<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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

享受孤独 2025-01-02 22:32:21

闭包和作用域指南

变量仅适用于创建它们的函数。因此,通过在 clickHelper 内部创建 self,您可以将其设为仅 clickHelpers 函数的局部变量。

通过将其移至 myPlugins 范围,现在可以通过嵌套函数访问它。

现场演示

 $.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);
    };

Guide on closures and scoping

Variables are only available to the functions in which they are created. So by creating self inside of clickHelper you are making it a local variable only to the clickHelpers function.

By moving it into myPlugins scope its now accessible to the nested functions.

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);
    };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文