JS对象文字,此上下文更改

JS object literal, this context changing

本文关键字:上下文 对象 文字 JS      更新时间:2023-09-26

我正在改进我的Javascript结构并试图找出我喜欢的模式,我有以下内容:

var aThing = (function() {
  var module;
  return {
    init: function() {
      module = this;
      console.log(module);
    },
  };
})();

当我运行aThing.init();它记录Object {init: function}时,这就是我想要的,当我做这样的事情时出现问题:

document.addEventListener('click', aThing.init, false);

这将记录#document 。当我运行没有括号的函数时,似乎this正在发生变化,我不知道为什么。

这一切都与执行上下文有关。虽然你的 init 方法位于 aThing 模块中,但你在其他地方执行它,所以你对"this"关键字的使用将引用执行上下文。

与其在模块外部编写事件处理程序,不如考虑利用模块来处理它。它可以从模块的 init 方法内部完成,这将为您提供一个更干净的结构,因为您将有关模块的所有内容都存储在模块本身内,而不是在模块外部和内部执行其他操作。

见下文:

var aThing = (function() {
  var module;
  return {
    
    init: function() {
      module = this;
      // Handle event binding from somewhere within your module
      document.addEventListener('click', module.doSomething, false);
    },
    
    doSomething: function () {
      console.log('Doing something.');
    }
  };
})();
// Initialize your module
aThing.init();

您正在获得'document'引用,因为init()函数在文档上下文中调用。您可以将函数绑定到您想要的任何对象。

aThing.init.bind(aThing)

或者你可以引用模块,如果它喜欢,

var aThing = (function() {
    var module = {
        name  : 'My module',
        init : function() {
          alert(module.name);
        }
   };
  return module;
})();

当然,因为事件处理程序中的上下文将document .使用以下任一用途:

document.addEventListener('click', function() {
    aThing.init();
}, false);

document.addEventListener('click', aThing.init.bind(aThing), false);