Какова цель прототипа? [дубликат]


Возможные Дубликаты:
понимание прототипного наследования в JavaScript

хорошо, так что я несколько новичок в идее ООП в JS.

в чем разница между этими двумя фрагментами кода, написанного ниже:

function animal(){
    this.name = 'rover';
    this.set_name = function(name){
         this.name = name;
    }
}
function animal(){
    this.name = 'rover';
}
animal.prototype.set_name = function(name){
    this.name = name;
}

Они оба делают одно и то же, так в чем разница?

3 208

3 ответа:

использование прототипа позволяет ускорить создание объекта, так как эта функция не должна быть повторно создана каждый раз, когда создается новый объект.

при этом:

function animal(){
    this.name = 'rover';
    this.set_name = function(name){
         this.name = name;
    }
}

The создана de novo каждый раз, когда вы создаете животное. Но когда вы делаете это

animal.prototype.set_name = function(name){
    this.name = name;
}

функция не должна быть воссоздана каждый раз; она существует в одном месте в прототипе. Поэтому, когда вы звоните someAnimal.set_name("Ubu"); the this контекст будет установлен в someAnimal и (единственный и неповторимый)set_name функция будет вызвана.


однако есть одно преимущество использования первого синтаксиса: функции, созданные таким образом, будут иметь доступ к личным данным:

function animal(){
    var privateData = 'foo'

    this.name = 'rover';
    this.set_name = function(name){
         this.name = name;
         alert(privateData); //will alert 'foo'
    }
}

Дуглас Крокфорд называет созданные таким образом функции "привилегированными" по этой причине: они имеют доступ как к публичным, так и к частным данным.

разница появляется, когда вы создаете новый объект из этих функций

var animal1 = new animal();

все объекты, созданные первой функцией, будут иметь разные name и set_name свойства. Однако все объекты, созданные второй функцией, будут совместно использовать set_name собственность.

в первом примере каждое отдельное животное имеет собственное свойство для функции set_name, в то время как во втором примере они используют одну и ту же функцию через свой прототип.

преимущество первой версии заключается в том, что методы могут обращаться к локальным (частным) переменным, объявленным внутри конструктора.

преимущество второго метода заключается в том, что он требует меньше памяти (так как вы храните метод только один раз, а не миллион раз) и является более производительным в ток двигателей Яш.

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