2015-07-30 4 views
1

я чего-то не понимаю> Давайте посмотрим на примере MDN в:Javascript- наследование прототипов

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

    if (price < 0) { 
    throw RangeError('Cannot create product ' + 
         this.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.constructor = Food; // Reset the constructor from Product to Food 

Почему я должен написать эту часть:

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

это не Product.call(this, name, price); уже скопировано это свойство (прототип) от продукта к пище?

+0

Возможный дубликат [Как работает JavaScript .prototype?] (Http://stackoverflow.com/questions/572897/how-does-javascript-prototype-work) –

+0

Нет, это 'Product.call (...)' не имеет ничего общего с прототипом. Он только инициализирует свойства 'name' и' price' экземпляра – Bergi

+0

Почему? Потому что прототип не аргументирован? – Alexa

ответ

1

Это как раз то, как вы выполняете псевдоклассическое создание экземпляра класса в JavaScript. Давайте сначала посмотрим, что происходит, когда вы просто делаете первую часть, но позволяет добавить немного разъяснений:

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

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

    return this; 
} 

Product.prototype.declare = function() { 
    console.log('I like ' + this.name); 
} 

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

Запустить в консоли и и запустить console.dir(Product) против console.dir(Food). Пища имеет некоторые свойства, такие как Продукт. Однако Food не имеет доступа к методу «объявить», который находится на прототипе Product. Таким образом, нам нужно установить прототип Food. Запустить в консоли после кода выше:

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

запустить console.dir для Food снова. Теперь у Питера есть прототип, который имеет те же свойства/методы, что и Product. Однако конструктор прототипа теперь «Продукт». Последним шагом для исправления этого является установка Food.prototype.constructor, так что конструктор Food еще раз Food, но со всеми свойствами/методами Product.

Food.prototype.constructor = Food; 

Это странно, но логический процесс достижения полного наследования с псевдоклассической конкретизации в JavaScript.

+0

Благодарю вас за ответ. Я не понимаю, почему метод Call не копировал прототип продукта. Ведь прототип - это еще одно свойство объекта Product, и оно должно скопировать это свойство. – Alexa

+0

Я не вижу, как метод объявляет в Food.prototype, когда я все это делаю. – Alexa

+0

Это должно быть под свойством __proto__ Food (потому что оно наследуется от Продукта). Попробуйте инстанцирование нового 'Food' объект: ' уаг бифштекса = новая еда ('стейк', 50); ' Затем запустите: ' steak.declare(); ' – eddyjs