Прототип против Нет, каковы преимущества? - PullRequest
8 голосов
/ 23 августа 2009

Здесь я сделал два объекта; один имеет методы доступа, созданные в конструкторе, другой - в прототипе. Почему один выбирает один из них перед другим?

function spy1(name){
  this.name = name;
  var secret;
  this.setSecret = function(message){
    secret = message;
  };
  this.getSecret = function(){
   return secret;
  };
}

function spy2(name){
  this.name = name;
  this.secret;
  /* (see comment) was:
  var secret;
  */
}
spy2.prototype.setSecret = function(message){
  this.secret = message;
  /*was:
  secret = message;
  */
};
spy2.prototype.getSecret = function(){
  return this.secret;

  /*was:
  return secret;
  */
};

bond = new spy1("007");
smart = new spy2("86");

bond.setSecret("CONTROL is a joke.");
smart.setSecret("The British Secret Service is for sissies.");

Ответы [ 3 ]

8 голосов
/ 23 августа 2009

Изначальное различие заключается в том, что в вашем первом примере без прототипа реализация функций getSecret и setSecret будет находиться на каждом экземпляре spy1.

Во втором примере функции определены в прототипе, и все экземпляры ссылаются на них напрямую, вы можете проверить это:

var bond = new spy1("007"),
    bond2 = new spy1("007");

bond.getSecret === bond2.getSecret; // <-- false since they are two functions

var smart = new spy2("86"),
    smart2 = new spy2("86");


smart.getSecret === smart2.getSecret; // <-- true since is the same function
                                      // on all instances

Также обратите внимание, что @ T.J. прокомментировал, во втором примере, используя прототип, у вас нет доступа к закрытию функции конструктора, и для этого вы делаете глобальную переменную window.secret.

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

См. Также: Затворы .

5 голосов
/ 23 августа 2009

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

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

Кстати, ваш второй пример не будет работать так, как написано. переменная secret в spy2 является локальной для конструктора. В функциях setSecret и getSecret в прототипе вы получаете доступ к одной глобальной переменной.

1 голос
/ 23 августа 2009

Со второй версией вы получите более чистый "конструктор".

...