Javascript - это язык, имеющий форму наследования, которая называется прототип наследования .
Идея заключается в том, что для данного объекта он имеет скрытое свойство, называемое prototype , которое является ссылкой на другой объект, который называется объектом-прототипом.
Это отношение важно, когда вы запрашиваете у движка javascript значение свойства объекта, давайте назовем его foo просто чтобы исправить идею. Движок javascript сначала проверит ваш объект, чтобы увидеть, имеет ли он свойство с именем foo : если свойство определено для вашего объекта, его значение возвращается и поиск завершается. Если, в противном случае, у вашего объекта нет свойства с именем foo , то выполняется поиск объекта-прототипа, и тот же процесс повторяется снова.
Эта процедура повторяется до тех пор, пока не будет исследована вся так называемая цепочка прототипов . Корень цепочки прототипов - это встроенный объект javascript, на который можно ссылаться с помощью выражения Object.prototype , и это объект, из которого происходят все остальные объекты javascript. Обратите внимание, что если свойство foo отсутствует в всех объектах, составляющих всю цепочку прототипов, то возвращается значение undefined .
Это реальная форма наследования, встроенная в javascript, и это бизнес, который действительно стоит за клавиатурой ES6 class , это удобство, которое скрывает этот беспорядок и создает впечатление, что javascript имеет форму наследование классов (наследование классов более широко известно, и большинству программистов легче придумать, чем наследование прототипов).
Минимум, который вы можете сделать, чтобы взять объект и решить, что он должен вести себя как массив, следующий:
const myArray = [];
const myObject = { foo: "bar" }
Object.setPrototypeOf(myObject, myArray);
myObject.push("hello");
myObject.push("world");
console.log(myObject.length); // prints 2
Эта книга - лучший справочник, который я знаю по языку JavaScript. Это тоже хорошо , но в наши дни оно немного устарело, и следовать за ним не так просто, как в предыдущем.
Пример, несколько более сложный, чем предыдущий, можно реализовать с помощью функции в качестве конструктора. На самом деле это старый способ ES5 реализовать классовое наследование, то, что вы делали во время ES5 для имитации классов:
function SpecialArray(name) {
this.name = name;
}
SpecialArray.prototype = [];
// fix the constructor property mess (see the book linked above)
Object.defineProperty(SpecialArray.prototype, "constructor", {
value: SpecialArray,
enumerable: false,
writable: true
});
SpecialArray.prototype.getSalutation = function() {
return "Hello my name is " + this.name;
};
const mySpecialArray = new SpecialArray("enrico");
// you can call the methods and properties defined on Array.prototype
mySpecialArray.push("hello");
mySpecialArray.push("world");
console.log(mySpecialArray.length); // prints 2
// you can use the methods and properties defined on SpecialArray.prototype
console.log(mySpecialArray.name); // prints enrico
console.log(mySpecialArray.getSalutation()); // prints Hello my name is enrico
// important sanity checks to be sure that everything works as expected
console.log(mySpecialArray instanceof Array); // prints true
console.log(mySpecialArray instanceof SpecialArray); // prints true
console.log(mySpecialArray.constructor === SpecialArray); // prints true
// you can iterate over the special array content
for (item of mySpecialArray){
console.log(item);
}
// you can read special array entries
console.log(mySpecialArray[1]); // prints world