【问题标题】:jQuery Boilerplate - Losing Access to "this" Scope [duplicate]jQuery Boilerplate - 失去对“this”范围的访问 [重复]
【发布时间】:2014-12-01 14:18:25
【问题描述】:

我正在尝试使用jQuery Boilerplate 编写我的第一个插件。我遇到的问题是,一旦我尝试处理一个事件,我就无法访问this 范围,我认为是variable shadowing。这似乎是jQuery Boilerplate 的常见用例,所以我猜我做错了。

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

  1. jQuery plugin object: attached an event handler via .on() and now have a scope issue of this. (the main plugin object) - 没有答案
  2. Javascript scoping Issue using JQuery Boilerplate - 不回答我的问题

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

HTML

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

插件

(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();
});

解决方案

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

对于browsers that support bindinit 函数可以这样更改:

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 等。

根据Jeff Watkins的回答:

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

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

【问题讨论】:

  • 所以这已被标记为另一个帖子的副本,但我不明白如何应用该帖子中提供的解决方案。

标签: javascript jquery jquery-boilerplate


【解决方案1】:

“this”与您在堆栈中的位置有关,因此如果有意义的话,事件中的“this”实际上就是事件。这是一个常见的编程概念。

如果您需要在其上调用某些内容,我经常使用“this”(即调用者)的缓存版本。

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

【讨论】:

  • 如何更改doLog 函数?这就是我无法访问Pluginelement$elementsettings 属性的地方。
  • 与上述相同的方式......尽管您的代理答案也适用于 IIRC。
  • 因为你给出了一个有效的答案,我会接受它。我还将您的答案添加为可能的解决方案之一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 2015-08-12
相关资源
最近更新 更多