2016-08-09 5 views
0

Я изучаю Javascript OOP и у меня проблемы с пониманием наследования. Не могли бы вы объяснить мне, почему результаты этих двух кодов отличаются? :Наследование JavaScript, присваивающее значение конструктору

Код 1

function a(){} 

function b(){ 
    this.uno = "hello"} 

b.prototype = new a(); 

function c(){ 
    this.dos = "bye"} 

c.prototype= new b(); 

var obj = new c(); 

console.log(obj.uno); 
console.log(obj.dos); 
console.log(obj.constructor); 

Выход 1

hello 
bye 
[function: a] 

Код 2

function a(){} 


function b(){ 
    this.uno = "hola"} 


b.prototype = new a(); 


function c(){ 
    this.dos = "bye"} 

c.prototype = {constructor:b} 

var obj = new c(); 

console.log(obj.uno); 
console.log(obj.dos); 
console.log(obj.constructor); 

Ouput 2

undefined 
bye 
[function: b] 

Я по-настоящему ценю любое руководство по этому вопросу.

+1

Он отличается тем, что 'new b()' не возвращает '{constructor: b}', так что это не то же самое – adeneo

+1

Вопрос в следующем: почему именно вы ожидали, что они будут вести себя одинаково? Они явно отличаются друг от друга. – Oriol

+0

, даже если вы назначаете объект своему прототопию, это не имеет смысла. – Redu

ответ

0

В фрагменте кода

function a() {} 
 

 
function b() { 
 
    this.uno = "hello" 
 
} 
 

 
b.prototype = new a(); 
 

 
function c() { 
 
    this.dos = "bye" 
 
} 
 

 
c.prototype = new b(); 
 

 
var obj = new c(); 
 

 
console.log(obj.uno); 
 
console.log(obj.dos); 
 
console.log(obj.constructor);

Позволяет понять, Что происходит. Когда вы делаете

b.prototype = new a();

Новый экземпляр a создается и непосредственно присваивается прототип b. Так на данный момент, если var obj = new b(); obj.uno будет равен hello.

Теперь, когда оператор

c.prototype = новый б();

выполняется, OBJ (а экземпляр класса b) теперь назначен прототип c. Так что прямо в этот момент, если один делает var obj = new c();

  • obj.dos = bye как ее установленное в классе c конструктора.
  • obj.uno = 'hello' как это когда-то осматривалось, а instanciating b конструктор.
  • Поскольку свойство конструктора не переустанавливается, оно все равно укажет на исходный родитель a. Итак, obj.constructor = function a().

Во втором фрагменте

function a() {} 
 

 

 
function b() { 
 
    this.uno = "hola" 
 
} 
 

 

 
b.prototype = new a(); 
 

 

 
function c() { 
 
    this.dos = "bye" 
 
} 
 

 
c.prototype = { 
 
    constructor: b 
 
} 
 

 
var obj = new c(); 
 

 
console.log(obj.uno); 
 
console.log(obj.dos); 
 
console.log(obj.constructor);

c.prototype = { конструктор: б }

не наследует b или его прототипную цепочку. В каждом конструкторе s prototype chain there is a конструктор property which points to the constructor class. In the avobe statement, it just reassings it to the function b`.

UPDATE: Constructor это свойство, определенное в цепочке прототипов в любом объекте и, как функции first-class-objects в JS, они тоже имеют это свойство вписан.

Итак, когда вы выполняете указанную выше строку, она в основном меняет значение c.prototype.constructor. И ничего больше.

Если бы вы делали это

c.prototype = { 
    constructor: 5 
} 
... 
console.log(obj.constructor); // 5. 
//Its like setting a value for a property in a JS object. 

Так что, когда вы делаете:

console.log (obj.constructor);

Он указывает на вновь назначенный конструктор, то есть function b().

Но нет никакого наследования,

console.log (obj.uno);

определенно не определено.

Однако

console.log (obj.dos);

будет bye, когда вы создаете новый экземпляр функции c:

вар OBJ = новый C();

Надеюсь, что это поможет лучше понять прототипное наследование JS.

+0

Большое спасибо за ваш выделенный ответ Аян. Я думал, что свойство «конструктор» объекта-прототипа отвечает за наследование класса функции. Итак, что вы имели в виду, когда говорили, что ** c.prototype = {constructor: b} ** не наследует, а переназначает? –

+0

Эй @maxfraguas Обновили эту часть ответа, представив для этого пример. Дайте мне знать, если это звучит лучше – Ayan

-1

Потому что new b() !== {constructor:b} (as adeneo mentioned). Прототип ожидает a lot more, чем просто свойство {constructor}, поэтому просто предоставление объекта (литерала) с этим не принесет больших результатов.

Смежные вопросы