Это немного улучшенная версия примера Джимми.Во-первых, я бы добавил дополнительную функцию, которая поможет вам более удобно определять цепочку прототипов.Вы также можете использовать Object.create()
, но это еще не поддерживается во всех браузерах, поэтому эта функция должна быть более пуленепробиваемой:
// A convenient function to define prototype chain
function inheritPrototype(child, parent) {
function F(){}
F.prototype = parent.prototype;
child.prototype = new F();
// set the constructor back to the original, explained later
child.prototype.constructor = child;
}
Затем определите объекты.Обратите внимание на дополнительную функцию setName
, которая позволяет нам установить имя человека.(не говоря уже о том, что в JS обычно нет необходимости в методах получения / установки).Также обратите внимание на дополнительный вызов inheritPrototype
после определения функции Pirate.
function Person(name) {
this.name = name;
}
Person.prototype.say = function (message) {
return this.name + ": " + message;
};
Person.prototype.setName = function(name) {
this.name = name;
};
function Pirate(name) {
this._super = Person.prototype;
this._super.constructor.apply(this, arguments);
}
inheritPrototype(Pirate, Person);
Pirate.prototype.say = function (message) {
return this._super.say.apply(this, arguments) + ", yarr!";
};
var john = new Pirate("Long John");
john.say("ahoy matey");
Этот стиль позволяет автоматически вызывать функции родителя, и вам не нужно переопределять каждую из них, еслиони такие же, как их родители.Также это не мешает вам переопределить функции, которые уже существуют для родителя (в этом случае say
переопределяется).И помните, что все функции односторонние, что означает, что если вы переопределите функцию в дочерних элементах, то функция родителя останется неизменной.Пример:
// Should result in John "The Pirate" Long: ahoy matey, yarr!
// instead of how it was defined in Person
john.setName('John "The Pirate" Long');
john.say('ahoy matey');
// Notice that even though Pirate redefined say function, it
// still works as defined in Person, if it's called on a Person object
var president = new Person("Obama");
president.say('Vote for me!');
Также использование этого стиля позволяет проверять типы объектов, если child.prototype.construtor
был переопределен для child (замена прототипа устанавливает его в функцию конструктора parent).Джон - это Человек и Пират (потому что Пират наследует от Человека).Пример:
john instanceof Person
> true
john instanceof Pirate
> true
Поскольку президент является непосредственно объектом Person, а не пиратом, результаты будут следующими:
president instanceof Person
> true
president instanceof Pirate
> false