Переопределение методов в Javascript
Я хотел бы знать, в чем разница между переопределением методов с прототипами и без прототипов. Подумайте:
Пример 1:
function Animal() {
this.sleep = function () {
alert("animal sleeping");
};
this.eat = function () {
alert("animal eating");
};
}
function Dog() {
this.eat = function () {
alert("Dog eating");
};
}
Dog.prototype = new Animal;
var dog = new Dog;
dog.eat();
Пример 2:
function Animal() { }
function Dog() { }
Animal.prototype.sleep = function () {
alert("animal sleeping");
};
Animal.prototype.eat = function () {
alert("animal eating");
};
Dog.prototype = new Animal;
Dog.prototype.eat = function () {
alert("Dog eating");
};
var dog = new Dog;
dog.eat();
Я чувствую, что оба примера производят тот же эффект, что и Dog
класс переопределяет метод eat Animal
класса. Или происходит что-то другое?
4 ответов
в первом методе каждый из Animal
экземпляр получит свою собственную реализацию sleep
и eat
методы.
в то время как во второй модели все экземпляры будут иметь один и тот же экземпляр sleep
и eat
методы.
вторая модель лучше, так как мы можем поделиться методами.
как упоминал Арун в первом примере, который вы создаете sleep
и eat
функции для каждого нового экземпляра. Во втором примере есть только один sleep
и eat
функция, которая является общей для всех экземпляров.
в этом случае второй метод лучше, но хорошо знать, когда использовать первый метод и когда использовать второй. Сначала немного теории:
Примечание: в JavaScript есть четыре типа переменных - private
, public
, shared
и static
.
частные переменные недоступны вне функции, в которой они определены. Например:
function f() {
var x; // this is a private variable
}
открытые переменные определяются на this
объект внутри функции. Например:
function f() {
this.x; // this is a public variable
}
общие переменные являются общими для prototype
функции. Например:
function f() {}
f.prototype.x; // this is a shared variable
статические переменные являются свойствами самой функции. Для пример:
function f() {}
f.x; // this is a static variable
чаще всего лучше всего объявлять методы функции конструктора как общие методы, так как все экземпляры конструктора разделяют их. Однако, если ваш метод должен получить доступ к частной переменной, он должен быть объявлен как сам открытый метод.
Примечание: это моя собственная номенклатура. Не многие программисты JavaScript придерживаются его. Другие, похоже, следуют номенклатуре Дугласа Крокфорда: http://javascript.crockford.com/private.html
чтобы узнать больше о прототипном наследовании в JavaScript, прочитайте следующий ответ:https://stackoverflow.com/a/8096017/783743
в вашем первом примере каждый новый Dog
экземпляр будет иметь свой собственный eat
способ и во втором примере будет только один eat
метод on Dog.prototype
, который будет разделен между всеми будущими экземплярами Dog
Как Арун говорил.
это только "хитрый" разница между этими двумя. Но всегда лучше определять методы на prototype
для избежания высоких потребления и утечек памяти.
методы в первом примере определяются в экземпляре объекта.
настройки Dog
прототип нового Animal
например, таким образом Dog
наследование sleep
и eat
функции Animal
. Тогда ты определение (не переопределение) eat
метод Dog
конструктор как метод экземпляра, и это скрыть унаследовала eat
метод Dog
экземпляров.
рассмотреть следующий пример:
function LittleDog() { }
LittleDog.prototype = Object.create(Dog.prototype);
(new LittleDog()).eat();
код выше будет предупреждать animal eating
С вашим кодом в первом примере.
и уведомления Dog eating
С кодом во втором.