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:
... is not
invertedPeninsula
, butinvertedPeninsula.inhabitants
and so any reference tothis
in the method is toinvertedPeninsula.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 onthis.inhabitants
, and it is that array object that is getting extended with more methods, not the object being constructed.