简体   繁体   中英

Reference to an object's array from within the object in Javascript

I would like to create a new object of the type InvertedPeninsula:

var invertedPeninsula = new InvertedPeninsula();

To create this object type, I use an object constructor function:

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

In summary, the constructor creates an object with an array called "inhabitants" which itself contains 4 object literals. The InvertedPeninsula object type constructor then goes on to add four function expressions to the inhabitants array. In other words, the inhabitants array contains 4 objects and 4 methods aswell which one may confirm by printing the contents of the array using a "for-in" iterator.

Everything is behaving like I want, but what I am trying to understand is why on earth this constructor can get away with referencing the inhabitants array without mentioning it's name. In particular:

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

Should that code above not be:

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

Instead?

Similarly, the human, elves and specter array properties all return:

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

respectively. However, should it not rather be:

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

I made these suggested changes but when trying to call any one of the functions, for example:

invertedPeninsula.inhabitants.humans();

I get these errors:

Uncaught TypeError: Cannot read property 'getRace' of undefined

Uncaught TypeError: Cannot read property 'length' of undefined

I am using Google Chrome 55.0.2883.87 m

Any possible explanations as to what is happening under the hood here?

It works because the context when you do this:

invertedPeninsula.inhabitants.humans();

... is not invertedPeninsula , but invertedPeninsula.inhabitants and so any reference to this in the method is to invertedPeninsula.inhabitants .

Note also that you define only one property in the constructor: inhabitants .

All the other methods you define in that constructor are not created on this , but on this.inhabitants , and it is that array object that is getting extended with more methods, not the object being constructed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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