JavaScript: назначение свойства через прототип - PullRequest
8 голосов
/ 28 июля 2010

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

Вопрос: Мне кажется, я понимаю, как работает CodeA.Ninja.prototype.swung = false назначает новое свойство в function Ninja(), и ninjiaA.swung оценивается как ложное из-за этого.Однако в CodeB, когда мы объявляем function Ninja() с this.swung = true в начале, последующее присвоение Ninja.prototype.swung = false не дает эффекта, и ninjaA.swung остается оцененным как true.Я не понимаю, почему это более позднее назначение не работает в CodeB.Может ли кто-нибудь, пожалуйста, просветить меня об этом?

CodeA:

function Ninja(){}  
Ninja.prototype.swung = false; 
var ninjaA = new Ninja();
ninjaA.swung; //evaluates to false

CodeB:

function Ninja(){ 
  this.swung = true; 
}  
Ninja.prototype.swung = false; //I'm expecting this changes swung to false, 
                               //but it doesn't.
var ninjaA = new Ninja();      
ninjaA.swung; //evaluates to true

Большое спасибо заранее.

Ответы [ 3 ]

15 голосов
/ 28 июля 2010

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

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

Подумайте, как свойство оценивается в цепочке прототипов.что может прояснить ситуацию.

CodeA:

ninjaA.swung

1. Is swung a property of the current object - No
2. Is swung a property of the current object's prototype - Yes
    2.1. Return it

CodeB:

ninjaA.swung

1. Is swung a property of the current object? - Yes
    1.1 Return it

В коде B,он никогда не попадет в собственность по прототипу.

6 голосов
/ 28 июля 2010

При вызове Ninja в качестве конструктора вы присваиваете значение true для swung.Перед выполнением конструктора объект будет выглядеть следующим образом:

{
    prototype : {
        swung : false
    }
}

После выполнения конструктора:

{
    prototype : {
        swung : false
    },
    swung : true
}

Когда вы запрашиваете свойство swung, цепочка прототипов будетпроверил на каждом уровне, чтобы увидеть, если он существует.Если он не существует, будет возвращено значение undefined.

3 голосов
/ 28 июля 2010

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

...