Я изо всех сил пытаюсь понять различие следующих 2 наборов кода. Исходный код из известного учебного руководства Ниндзя, и я упростил немного для меня.
Вопрос: Я думаю, что понимаю, как CodeA работает. Ninja.prototype.swung = false
присваивает новое свойство в function Ninja()
, и ninjiaA.swung
оценивает ко лжи из-за этого. Однако в CodeB, когда мы объявляем function Ninja()
с this.swung = true
в начале, более позднем присвоении Ninja.prototype.swung = false
не берет эффект, и ninjaA.swung
остается быть оцененным к истинному. Мне не удается понять, почему это более позднее присвоение не работает в 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
Большое спасибо заранее.
Когда вы объявляете свойство с помощью 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 он никогда не достигает свойства прототипа.
При вызове Ninja
в качестве конструктора вы присваиваете значение true
для swung
. До выполнения конструктора объект будет выглядеть так:
{
prototype : {
swung : false
}
}
После выполнения конструктора:
{
prototype : {
swung : false
},
swung : true
}
Когда вы запросите свойство swung
, цепочка прототипов будет проверяться на каждом уровне на предмет его существования. Если оно не существует, будет возвращено значение undefined
.
В JavaScript метод, добавленный к прототипу, вызывается только в том случае, если метод не найден в экземпляре первым.