简体   繁体   English

对象文字jQuery事件作用域

[英]Object literal jquery event scoping

What is the best way to solve this scoping problem? 解决此范围界定问题的最佳方法是什么?

NAMESPACE.myObject = {
  foo: 'foo',
  init: function() {
    $('.myBtn').on('click', this.myMethod);
  },
  myMethod: function() {
    console.log($(this), foo);
  }
};
NAMESPACE.myObject.init();

The result of the console.log should be the jQuery object that was clicked and the propertie foo of myObject. console.log的结果应该是单击的jQuery对象和myObject的属性foo。 How would I achieve this? 我将如何实现?

Basically you can't have more than one this , so need to work around it. 基本上你不能有一个以上的this ,所以需要解决它。

As a general rule, create a scoped variable ( THIS in the example below) to hold the scope you want to retain/access from inside any other scope. 通常,创建一个范围变量(在下面的示例中为THIS )以保存您要从其他范围内保留/访问的范围。

You need to retain the this on the call to the myMethod though, inside the click handler, so you can't just pass myMethod as it loses the myObject instance. 不过,您需要在单击处理程序内的myMethod调用中保留this ,因此您不能仅传递myMethod因为它会丢失myObject实例。

NAMESPACE.myObject = {
  this.foo: 'foo',
  init: function() {
    var THIS = this;
    $('.myBtn').on('click', function(){
        // "this" here is the button clicked
        // "THIS" is still the myObject instance
        THIS.myMethod(this);
    });
  },
  myMethod: function(element) {
    // "this" here is myObject
    // The clicked element was passed as parameter "element" instead
    console.log($(element), this.foo);
  }
};
NAMESPACE.myObject.init();

I hope I explained this clearly enough :) 我希望我解释显然不够:)

As jfriend00 points out, you can also use bind to basically create a function call with this scope on-the-fly (very cute), but that does not work on IE8 or older. 正如jfriend00所指出的,您还可以使用bind来动态地(在this范围内)动态创建一个函数调用(非常可爱),但这不适用于IE8或更旧的版本。

You can use .bind() like this: 您可以像这样使用.bind()

NAMESPACE.myObject = {
  foo: 'foo',
  init: function() {
    $('.myBtn').on('click', this.myMethod.bind(this));
  },
  myMethod: function() {
    console.log($(this), foo);
  }
};
NAMESPACE.myObject.init();

Or, for older versions of IE, since you already have jQuery you can use jQuery's $.proxy() : 或者,对于较旧版本的IE,由于您已经拥有jQuery,因此可以使用jQuery的$.proxy()

NAMESPACE.myObject = {
  foo: 'foo',
  init: function() {
    $('.myBtn').on('click', $.proxy(this.myMethod, this));
  },
  myMethod: function() {
    console.log($(this), foo);
  }
};
NAMESPACE.myObject.init();

When you pass this.myMethod to the event listener, it loses its binding to this (as you've noticed) because the event listener doesn't save that reference or call the method with it. 当您将this.myMethod传递给事件侦听器时,它会失去this绑定(如您所注意到的),因为事件侦听器不会保存该引用或调用该方法。 One way to keep that binding is to use .bind() (requires IE9 or a polyfill for earlier versions of IE). 保持该绑定的一种方法是使用.bind() (对于早期版本的IE,需要IE9或polyfill)。

Since I see you tagged jQuery, you can also use this approach, I know it is different from what you posted in the question, but I still an option. 由于我看到您标记了jQuery,因此您也可以使用这种方法,我知道它与您在问题中发布的内容不同,但是我仍然可以选择。

working example 工作实例

var NAMESPACE = NAMESPACE || {};  

$(function() {
    "use strict"
    $.extend(NAMESPACE, true, {
        getMyObject: function() {
             function myObject() {
                var self = this;
                self.foo = 'foo';
                self.init = function() {
                                $('.myBtn').click(self.myMethod); 
                };
                self.myMethod = function() {
                                console.log($(this), self.foo);
                };
            }
            return new myObject(); 
        }
    }); 

    var myObject = NAMESPACE.getMyObject();
    myObject.init();
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM