2014-04-08 3 views
0

на MDN-х page for Call есть пример 3 конструкторов: Продукт, Продукты питание и игрушкиВ чем разница между этими двумя конструкторами в JavaScript?

function Product(name, price) { 
    this.name = name; 
    this.price = price; 

    if (price < 0) 
     throw RangeError('Cannot create product "' + name + '" with a negative price'); 
    return this; 
} 

function Food(name, price) { 
    Product.call(this, name, price); 
    this.category = 'food'; 
} 
Food.prototype = Object.create(Product.prototype); 

Почему эта линия нужна?

Food.prototype = Object.create(Product.prototype); 

Не могу я просто это сделать?

function Food (name, price) { 
    var me = Product.call(this, name, price); 
    me.category = 'food'; 
    return me; 
} 
+0

в ваших «просто» вариант, после инициализации изменений прототипа продукта не будет отображаться на случаях еды , это может быть хорошо, в зависимости от ваших потребностей. и да, есть много способов настроить такие вещи, и все они имеют незначительные отличия. используйте то, что работает для вас. – dandavis

+0

@ dandavis, что вы сказали, правда. Можете ли вы сказать это как ответ? – tholapz

ответ

1

Одно отличие - синтаксис. На мой взгляд, это лучше в первом фрагменте.

В основном это:

Food.prototype = Object.create(Product.prototype); 

, а затем на этом

Toy.prototype = Object.create(Product.prototype); 

означает, что они имеют один и тот же прототип продукта, что приятно. Но в примере, который вы нам показываете, они действительно не используют концепцию class, которая на самом деле не присутствует в JavaScript, но активна в обязательном языке (например, PHP).

Вы можете иметь функции или свойство прилагаются только к игрушке или пищи:

Food.prototype = Object.create(Product.prototype); 
Food.prototype.eat = function(){ //Toy object can't call that function 
    alert('Om Nom Nom') 
} 

Конечно, вы могли бы сделать это так:

function Food (name, price) { 
    var me = Product.call(this, name, price); 
    me.category = 'food'; 
    me.eat = function(){ 
     alert('Om Nom Nom'); 
    }; 
    return me; 
} 

Но это приведет к ненужному использованию памяти и может повлиять на производительность.

И последнее: использование instanceof будет неправильным. При втором способе, вы будете не знать, если вы возражаете является продуктом:

//Method1 
alert(foodObj instanceof Food); //true 
alert(foodObj instanceof Product); //true 

//Method2 
alert(foodObj instanceof Food); //true 
alert(foodObj instanceof Product); //false 

Live example

+0

+1 для поднятия instanceof. Однако я использую node.js и пытаюсь проверить ваш результат. Это то, что я получаю: [код фрагмента] (https://gist.github.com/tholapz/10160289) – tholapz

+0

@ user3349705 Я был совершенно не прав в отношении экземпляра вещи. С «просто» вы теряете ссылку на «Продукт», а не на «Продовольствие». Что касается вашего примера, одним из объектов является «Food2», поэтому «instanceof Food» возвращает false, см. Скрипку в конце ответа! –

+0

Я вижу, что это была моя ошибка, чтобы проверить экземпляр Foods вместо Food2. Однако, что вы подразумеваете под именем объекта, будет другим? – tholapz

1

Разница заключается в том, что ваш объект Food не наследуют методы прототипа Product. Он возвращает то, что похоже на экземпляр Product, но есть различия.

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