2014-04-04 3 views
1

Является ли наследование прототипов по-разному основанным на типе? Является ли контекстная ссылка ЭТО, работающая по-разному в этих двух случаях? Почему в этих примерах один обращается к прототипу, а другой создает новое свойство для объекта?Js Прототип простых типов и объектов

var Player = function(){}; 

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

var p1 = new Player(); 
var p2 = new Player(); 

p1.set_name('Johanna'); 

Значение возвращение этих два:

// Checking object properties 
>p1 
Player {name: "Johanna", set_name: function} 

>p2 
Player {name: "", set_name: function} 

// Checking prototypes 
>p1.__proto__ 
Object {name: "", set_name: function} 

>p2.__proto__ 
Object {name: "", set_name: function} 

Но если я Игрок с именем свойства объекта, функция set_name модифицирует прототип.

var Player = function(){}; 

Player.prototype.name = {}; 
Player.prototype.set_name = function(name){this.name['first_name'] = name;} 

var p1 = new Player(); 
var p2 = new Player(); 

p1.set_name('Andrew'); 

Значение возвращение этих двух:

// Checking object properties 
>p1.name 
Object {first_name: "Andrew"} 

>p2.name 
Object {first_name: "Andrew"} 

// Checking prototypes 
>p1.__proto__.name 
Object {first_name: "Andrew"} 

>p2.__proto__.name 
Object {first_name: "Andrew"} 

Почему это происходит? Какую концепцию мне не хватает?

+0

Когда вы добавляете свойство в прототип, оно делится с другими экземплярами. Добавьте уникальные свойства конструктору. – elclanrs

+0

Не является Player.prototype.name = ''; и Player.prototype.name = {}; оба используют прототип? Почему использование функции set_name действует над прототипом в одном случае и добавляет свойство к объекту в другом случае? – kitimenpolku

ответ

2

Наследование цепь

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

  1. Текущий объект будет искать.

  2. Будет исследован прототип родителя.

  3. Будет исследован прототип родительского родителя.

    ...

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

Примечание: Задания не будут продвигаться по цепочке наследования. Если вы присваиваете значение атрибуту объекта (если его нет, он будет создан), то этому атрибуту присваивается значение.

Первый случай:

Вы делаете

this.name = name; 

Так,

p1.set_name('Andrew'); 

создает новый атрибут name в p1 и сохраняет Andrew в нем. И когда вы попытались распечатать p1, имя было просмотрено p1 и было найдено в p1.Итак, Andrew был возвращен. Но, когда вы напечатали p2, имя не найдено в p2. Он поднимается в иерархии и находит name в прототипе родителя. Таким образом, он возвращает пустую строку.

Второй случай:

Вы делаете

this.name['first_name'] = name; 

Так,

p1.set_name('Andrew'); 

смотрит name в p1. Потому что вы пытаетесь получить доступ к 'first_name' по адресу this.name. Таким образом, он пытается получить атрибут name. Он не находит его в p1, поэтому идет вверх и находит его в прототипе родителя. Это пустой объект, а name присваивается атрибуту first_name этого объекта.

Мы знаем, что прототип p2 аналогичен прототипу p1. Мы можем подтвердить, что как этот

console.log(p1.__proto__ === p2.__proto__); 
# true 

Итак, когда вы смотрите «прототип S, который является таким же, как p1» p2 s прототип, название Andrew найден.

+0

Я читал о цепочке наследования, о которой вы говорили в начале. Я знал это, но комментарий, который вы опубликовали, является ключевым. благодаря – kitimenpolku

0

В качестве общего случая переменные и такие параметры задаются в конструкторе. Для получения дополнительной информации по этому вопросу и лучшего объяснения, чем я могу сделать ссылку здесь: http://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/

// Constructor 
function Player() { 
    this.names = ''; 
}; 

// Public Method 
Player.prototype.set_name = function(name){ 
    this.name = name; 
} 

// Static method 
Player.walk = function() {} 

var player1 = new Player(); 
player1.set_name('John Doe'); // fires the public method 
Player.walk(); // fires the static method 
Смежные вопросы