Подтвердить что ты не робот

Попытка понять суть прототипов в JavaScript

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

Как и многие другие люди, стремящиеся сделать JavaScript повседневным языком, который я использую, я использую обычный стиль класса ООП, поскольку я играл в Java (и использовал классы в ActionScript, а также PHP). Однако, хотя я думаю, что понимаю, как работают прототипы, я не могу понять, почему они нужны.

Вот мой пример script того, как я сейчас понимаю прототипы в JavaScript:

var Apple = function() {
    // An apple?
};

Apple.prototype.color = "red";

Apple.prototype.changeColor = function(new_color) {
    this.color = new_color;
};
Apple.prototype.getColor = function() {
    alert('color: '+this.color);
};

var apple1 = new Apple();
var apple2 = new Apple();
apple2.changeColor("green");
apple1.getColor();
apple2.getColor();

... Я предположил, что, возможно, прототип означал, что он разделяет один и тот же объект, а не просто создает новый объект каждый раз - однако это явно не так, поскольку и apple1, и apple2 имеют разные цвета, все еще ( после запуска указанного script).

Затем я написал его в том, что больше объектно-ориентированного script:

var Apple = function() {
    this.color = "red";

    this.changeColor = function(new_color) {
        this.color = new_color;
    };
    this.getColor = function() {
        alert('color: '+this.color);
    };
};

var apple1 = new Apple();
var apple2 = new Apple();
apple2.changeColor("green");
apple1.getColor();
apple2.getColor();

С точно такими же результатами (как и ожидалось).... Почему последний код не рекомендуется? У меня нет проблем с использованием прототипов (если я правильно их использовал), но мне нужно понять концепцию "почему".

... Любая помощь?

4b9b3361

Ответ 1

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

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

... однако, это явно не так, поскольку и apple1, и apple2 имеют разные цвета, все еще (после запуска script).

Для определенных типов (например, number, boolean, null, undefined или string), когда вы изменяете свойство, которое существует в объекте прототипа через this.color, например, оно создаст свойство color в экземпляр. Прототип остается незатронутым, так что новые экземпляры будут иметь цвет по умолчанию, определенный в прототипе.

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

... Почему последний код не рекомендуется?

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


Чтобы развернуть немного больше, я бы отметил, что когда ваша функция вызывается как конструктор с помощью ключевого слова new, <конструктор this в конструкторе - это новый экземпляр. Поэтому в экземпляр добавляется любое свойство, добавляемое в this.

var Apple = function() {
      // Here "this" is the object being constructed. As such, we're adding
      //   a property "rotten" to every instance created
    this.rotten = false;
};

   // adding a "color" property to the prototype object
Apple.prototype.color = "red";

   // set the property "color" on the instance to the value of "new_color"
Apple.prototype.changeColor = function(new_color) {
    this.color = new_color;
};
   // first check to see if this instance has its own "color" property. If so,
   //    use it. If not, look at the prototype object to see if it exists.
Apple.prototype.getColor = function() {
    alert('color: '+this.color);
};

// two new instances each have their own "rotten" property, and don't have a
//    "color" property. Both share the prototype object, so if "color" is 
//    requested, it will come from there
var apple1 = new Apple(); 
var apple2 = new Apple();

// This will add an "color" property to the "apple2" instance
apple2.changeColor("green");

// Doesn't have a "color" property, so it looks to the prototype object
apple1.getColor();

// Has a "color" property, so it uses that instead of the "color" on the prototype
apple2.getColor();

Ответ 2

Прототип

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