【问题标题】:Scope of object literal methods对象字面量方法的范围
【发布时间】:2016-04-19 23:27:33
【问题描述】:

我目前正在学习 javascript 并试图理解“this”。在以下代码中,为什么我无法在我的渲染方法中访问 this.ul? (它说它是未定义的)。我被引导相信 cacheDOM 方法会将 this.ul 绑定到 people 对象,然后该对象的其余部分可以访问该对象。

(function(){

  var people = {
    people: ['Tom', 'Sean'],

    init: function() {
      this.cacheDOM();
      this.render();
    },

    cacheDOM: function() {
      this.input = window.document.querySelector('.input');
      this.button = window.document.querySelector('.button');
      this.ul = window.document.querySelector('.ul');
    },

    render: function() {
      var data = this.people;

      data.map(function(person){
        var li = document.createElement('li');
        li.textContent = person;
        this.ul.appendChild(li);
      });
    }
  };

  people.init();

})();

已修复。在我的渲染函数顶部添加了var ul = this.ul,然后允许地图函数正确访问!

【问题讨论】:

  • This(没有双关语),可能有助于了解您的情况。
  • 啊,都修好了 :) 谢谢!
  • @Thomas_Hoadley 它是如何修复的?
  • 在我的渲染函数顶部定义了var ul = this.ul...它允许内部映射函数正确访问! @hudsond7
  • map 正在创建一个闭包,因此 this 内的 map 将是 undefined 或在某些实现(jQuery)中引用 data 而不是您的外部对象。一些实现,例如 Lodash 的 map,允许将 this 作为附加参数传递给 map

标签: javascript binding scope this object-literal


【解决方案1】:

this参数的值由调用模式决定。

在 JavaScript 中有四种调用模式: 方法调用模式、函数调用模式、构造函数调用 模式和应用调用模式。 查看this link 了解这些模式。

检查render函数的以下实现;

render: function() {
  var data = this.people;
  var that = this;
  data.map(function(person){
    var li = document.createElement('li');
    li.textContent = person;
    that.ul.appendChild(li);
  });
}

或者您可以将 this 的值作为参数传递给 ma​​p() 函数:

  render: function() {
  var data = this.people;
  data.map(function(person){
    var li = document.createElement('li');
    li.textContent = person;
    this.ul.appendChild(li);
  },this);
}

【讨论】:

    【解决方案2】:

    Array.prototype.map 方法创建了自己的闭包,这样它就不会在这里引用 people 对象。您需要将“this”绑定为:

    render: function() {
      var data = this.people;
    
      data.map(function(person){
        var li = document.createElement('li');
        li.textContent = person;
        this.ul.appendChild(li);
      }.bind(this));
    }
    

    【讨论】:

      【解决方案3】:

      您可以将传递给map 的函数绑定到对象字面量的上下文:

      data.map(function(person){
        var li = document.createElement('li');
        li.textContent = person;
        this.ul.appendChild(li);
      }.bind(this));
      

      或者更透明:

      var iteratee = function(person){
        var li = document.createElement('li');
        li.textContent = person;
        this.ul.appendChild(li);
      }
      data.map(iteratee.bind(this));
      

      【讨论】:

        【解决方案4】:

        在匿名函数 this 内部不引用对象字面量。 this 是对所引用范围的所有者的引用。在匿名函数中,我很确定 this 是对全局/窗口对象的引用。

        要访问对象的 ul 成员,您可以使用 JavaScript 的闭包功能,类似这样。

        render: function() {
          var self = this; // here this points to the object literal
          var data = this.people;
        
          data.map(function(person){
            var li = document.createElement('li');
            li.textContent = person;
            self.ul.appendChild(li);
          });
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-10-15
          • 2022-07-06
          • 2019-11-16
          • 2016-06-23
          • 2013-06-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多