jQuery 样板 - 失去对“this”作用域的访问权限

jQuery Boilerplate - Losing Access to "this" Scope

本文关键字:作用域 访问 访问权 权限 this 样板 失去 jQuery      更新时间:2023-09-26

我正在尝试使用jQuery样板编写我的第一个插件。我遇到的问题是,一旦我尝试处理事件,我就会失去对this范围的访问权限,我认为这是由于可变阴影。这似乎是jQuery样板的一个常见用例,所以我猜我做错了。

我在SO上发现了两个类似的问题:

  1. jQuery插件对象:通过.on((附加了一个事件处理程序,现在有一个范围问题。(主插件对象( - 没有答案
  2. 使用 JQuery 样板的 Javascript 范围界定问题 - 没有回答我的问题

我创建了一个最小的示例来演示该问题。

.HTML

<ul>
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
</ul>

.PLUGIN

(function($, window, document, undefined) {
    'use strict';
    var pluginName = 'elementValueLog',
            defaults = {};
    function Plugin(element, options) {
        this.element = element;
        this.$element = $(element);
        this.settings = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        this.init();
    }
    $.extend(Plugin.prototype, {
        init: function() {
            this.$element.on('click', this.doLog);
        },
        doLog: function() {
            // HERE: I can't figure out how to access the Plugin "this" scope
            // I want to be able to use "element", "$element", "settings", etc.
            console.log(this.$element.val().trim());
        }
    });
    $.fn[pluginName] = function(options) {
        this.each(function() {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Plugin(this, options));
            }
        });
        return this;
    };
}(jQuery, window, document, undefined));

使用插件

$(document).ready(function() {
    $('li').elementValueLog();
});

溶液

我更愿意将其添加为答案,但被标记为"重复"会阻止这一点。在尝试了另一篇文章答案中显示的几种方法后,我找到了解决方案。我个人认为我的问题足够具体,可以独立存在,因为另一个帖子的"规范"答案相当广泛。

对于支持 bind 的浏览器,可以像这样更改init函数:

init: function() {
    this.$element.on('click', this.doLog.bind(this));
},

因为我需要支持IE 8,所以我将使用jQuery.proxy:

init: function() {
    this.$element.on('click', $.proxy(this.doLog, this));
},

然后doLog函数可以引用this.elementthis.$elementthis.settings等。

根据杰夫·沃特金斯的回答:

init: function() {
    var plugin = this;
    var doLog = function() {
        console.log(plugin.$element.val().trim());
    };
    this.$element.on('click', doLog);
},

此解决方案的优点是保留this上下文,同时允许访问插件的this上下文。

">

this"与你在堆栈中的位置相关,所以事件中的"this"实际上是事件,如果这有意义的话。这是一个常见的编程概念。

我经常使用缓存版本的"this"(即调用者(来使用,如果你需要调用它的东西。

$.fn[pluginName] = function(options) {
    var caller = this;
    this.each(function() {
        if (!$.data(caller, "plugin_" + pluginName)) {