Javascript 对象文字方法的作用域

Javascript 对象文字方法的作用域,javascript,binding,scope,this,object-literal,Javascript,Binding,Scope,This,Object Literal,我目前正在学习javascript并试图理解“这个”。在下面的代码中,为什么我不能在渲染方法中访问this.ul?(它说它没有定义)。我相信cacheDOM方法会将this.ul绑定到people对象,然后该对象的其余部分可以访问该对象 (function(){ var people = { people: ['Tom', 'Sean'], init: function() { this.cacheDOM(); this.render();

我目前正在学习javascript并试图理解“这个”。在下面的代码中,为什么我不能在渲染方法中访问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
添加到我的渲染函数的顶部,然后允许贴图函数正确访问

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

您可以将要传递到
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));

在匿名函数中,它不引用对象文本。这是对所引用范围的所有者的引用。在匿名函数中,我非常确定这是对全局/窗口对象的引用

要访问对象的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);
  });
}

参数的值由调用模式确定

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

检查渲染功能的以下实现

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的值作为参数传递给map()函数:

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

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