2013-03-19 3 views
9

Я хотел бы знать, в чем разница между переопределяющими методами с прототипами и без прототипов. Рассмотрим:Переопределение методов в 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 класс Переопределение метода есть от Animal класс. Или есть что-то другое?

+2

Вы должны использовать 'this' ключевое слово при определении свойств объекта в конструкторе. – ShuklaSannidhya

+0

@Sann sorry пропустил это ключевое слово. Отредактировал вопрос сейчас. – codingsplash

+7

Это почти всегда хорошая идея, чтобы поместить методы в прототип, поскольку тогда они распределяются между всеми экземплярами. Помещение их в ваш конструктор копирует их по всем экземплярам, ​​и это потребляет больше памяти. – Rik

ответ

10

В первом методе каждый экземпляр Animal получит свою собственную реализацию методов sleep и eat.

В то время как во второй модели все экземпляры будут иметь один и тот же экземпляр методов sleep и eat.

Вторая модель лучше, поскольку мы можем использовать методы.

5

Как отметил Арун в первом примере, вы создаете функции 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

0

В первом примере каждый новый Dog экземпляр будет иметь свой собственный eat метод и во втором примере там будет только один метод eat на Dog.prototype, которые будут распределены между всеми будущими экземплярами Dog как упоминалось Arun.

Это только «сложный» разница между этими двумя. Но всегда лучше определять методы на prototype, чтобы избежать чрезмерного потребления памяти и утечек.

0

Методы в первом примере определены в экземпляре объекта.

Вы установка Dog прототип нового Animal, например, таким образом, Dog наследуют sleep и eat функции от Animal. Тогда вы ОПРЕДЕЛЯЮЩИЕ (НЕ Переопределение) eat метод в Dog конструктор как метод экземпляра, и это будет HIDE унаследованный eat метод в Dog случаях.

Рассмотрим следующий пример:

function LittleDog() { } 
LittleDog.prototype = Object.create(Dog.prototype); 
(new LittleDog()).eat(); 

Код выше предупредит animal eating с вашим кодом в первом примере.

И предупредит Dog eating с кодом на второй.

Смежные вопросы