2

我想创建一个 InvertedPeninsula 类型的新对象:

var invertedPeninsula = new InvertedPeninsula();

为了创建这个对象类型,我使用了一个对象构造函数:

var InvertedPeninsula = function() {
  this.inhabitants = [
    {
      name: 'Flanery',
      race: 'Human'
    },
    {
      name: 'Sir Charles',
      race: 'Human'
    },
    {
      name: 'Ealei',
      race: 'Elf'
    },
    {
      name: 'Orado',
      race: 'Spector'
    }
  ];

  this.inhabitants.getRace = function(race) {
    var members = [];
    for (var i=0, l = this.length; i < l; i++) {
      if (this[i].race === race) {
        members.push(this[i]);
      }
    }

    return members;
  };

  this.inhabitants.humans = function() {
    return this.getRace('Human');
  };

  this.inhabitants.elves = function() {
    return this.getRace('Elf');
  };

  this.inhabitants.spectors = function() {
    return this.getRace('Spector');
  };
};

总之,构造函数创建了一个对象,其中包含一个名为“inhabitants”的数组,该数组本身包含 4 个对象字面量。InvertedPeninsula 对象类型构造函数接着将四个函数表达式添加到居住者数组中。换句话说,居民数组包含 4 个对象和 4 个方法,可以通过使用“for-in”迭代器打印数组的内容来确认。

一切都按照我想要的方式运行,但我试图理解的是为什么这个构造函数可以在不提及它的名字的情况下引用居民数组。尤其是:

for (var i=0, l = this.length; i < l; i++) 

如果上面的代码不是:

for (var i=0, l = this.inhabitants.length; i < l; i++) 

反而?

同样,人类、精灵和幽灵数组属性都返回:

return this.getRace('Human');
return this.getRace('Elf');
return this.getRace('Specter');

分别。但是,不应该是:

return this.inhabitants.getRace('Human');
return this.inhabitants.getRace('Elf');
return this.inhabitants.getRace('Specter');

我做了这些建议的更改,但是在尝试调用任何一个函数时,例如:

invertedPeninsula.inhabitants.humans();

我收到这些错误:

未捕获的类型错误:无法读取未定义的属性“getRace”

未捕获的类型错误:无法读取未定义的属性“长度”

我正在使用谷歌浏览器 55.0.2883.87 m

关于这里发生的事情的任何可能的解释?

4

1 回答 1

4

它之所以有效,是因为您执行此操作时的上下文:

invertedPeninsula.inhabitants.humans();

... is not invertedPeninsula,但是方法中的invertedPeninsula.inhabitants任何引用this都是 to invertedPeninsula.inhabitants

另请注意,您在构造函数中只定义了一个属性:inhabitants.

您在该构造函数中定义的所有其他方法都不是在 上创建的this,而是在 上创建的this.inhabitants,并且使用更多方法扩展的是数组对象,而不是正在构造的对象。

于 2016-12-23T15:51:58.457 回答