Вопрос о наследовании
Изучаю js, пытаюсь понять наследование.
function Product(name) { this.name = name; } Product.prototype = { getName: function() { return this.name; } } function Apple(name) { Product.call(this, name); } extend(Apple.prototype, Product.prototype); function extend(child, parent) { for (var i in parent) { child[i] = parent[i]; } } var apple = new Apple("яблоко"); console.log(apple.getName()); Что плохого в использовании extend? То, что это копирование метода из одного прототипа в другой? То есть скопированный метод getName будет ссылаться не на Product.prototype, а на Apple.prototype? В этом проблема или в чём? Поясните, плз. |
Проблема в том, что это копирование, а не наследование. Это разные вещи. Если в Apple.prototype и Product.prototype будут одноименные методы, копирование перезапишет метод ребенка методом предка, наследование - нет. Наследование реализуется так:
function extend(Child, Parent) { Child.prototype = Object.create(Parent.prototype, { constructor: { value: Child, enumerable: false, writable: true, configurable: true } }); }; То есть, в итоге должно получиться, что (new Child()).__proto__.__proto__ == (new Parent()).__proto__ |
Твой вариант будет работать, но он кривой:) надо хотя бы так
function Product() {} Product.prototype = { getName: function() { return this.name; } } function Apple(name) { this.name=name } Apple.prototype=Object.create(Product.prototype) var apple = new Apple("apple"); alert(apple.getName()); Но лучше восстановить связи: function Product() {} Product.prototype.getName=function() { return this.name; } function Apple(name) { this.name=name } Apple.prototype=Object.create(Product.prototype) Apple.prototype.constructor=Apple var apple = new Apple("apple"); alert(apple.getName()) alert(apple.constructor); Тут, собчтвенно, класс product вообще не нужен. Ну ладно, пусть будет:) По сабжу. В копировании плохо то, что оно засирает память, и, в некотором смысле, нарушает модульность. |
krutoy,
Опять забыл восстановить ребенку ссылку на его конструктор. Ну и вариант от Erolast ничем не кривой. Еще в копировании плохо то что мы не сможем проверять принадлежность к классу через instaceof |
Цитата:
|
tsigel,
Кстати, вариант того клоуна тоже крив, потому что он избыточен. Вся эта параша, которую он подает вторым параметром Object.create -- не нужна. А пишет эту всю парашу поциэнт, потому что он джаваскрипт не понимает, а этот говнопаттерн где-то увидел и копирует бездумно. Из песни слов не выкинешь, боится клоун, что-то изменить, боится, что-нибудь сломается в коде.:) |
То есть выходит, что все экземпляры "класса" Apple будут иметь свой личный метод getName, в то время как если наследовать через прототип все экземпляры будут ссылаться на один и тот же прототип . Теперь стало понятно. Спасибо всем
|
krutoy,
Вторым аргументом он восстанавливает ссылку на конструктор. |
javacrypt,
Кстати, можно и изящней написать, с сахарком:) function Product() {} Object.defineProperty(Product.prototype, "name", {get: function(){return this.name_}}) function Apple(name) { this.name_=name } Apple.prototype=Object.create(Product.prototype) Apple.prototype.constructor=Apple var apple = new Apple("apple"); alert(apple.name) |
Цитата:
Apple.prototype.constructor=Apple А он написал невнятную, нечитаемую, и непонятно зачем нужную парашу. |
Часовой пояс GMT +3, время: 09:59. |