function Rectangle(width,height) {
this.width = width;
this.height = height;
let self = this;
Rectangle.prototype.getArea = function() {
return this.height * this.width;
}
Object.defineProperty(this, 'getArea',
{
enumerable:true,
value: function() {
return self.height * self.width;
}
}
);
// this.getArea = function() {
// return self.height * self.width;
// }
}
function fromJSON(proto, json) {
let inp = JSON.parse(json);
return Object.assign(Object.create(proto),inp);
}
let o = new Rectangle(33,2);
console.log(o);
console.log(o.getArea());
console.log(fromJSON(Rectangle.prototype,'{"width":10,"height":6}'));
В итоге при копировании объекта я получаю два свойства, но метод не передаётся. Что делать, где я не прав? Где почитать?
Я так понимаю, метод получается наследуемым и поэтому не копируется? Его нужно ручками дублировать?
В Вашем коде зачем-то создаются две функции getArea
, одна для объекта, который создаётся конструктором, а другая для прототипа.
Первый объект создаётся через конструктор, поэтому имеет и свою функцию, и функцию от прототипа (которая не используется из-за перекрытия первой). Второй объект не создавался через конструктор, а скопировали в него только поля ширины и высоты, поэтому имеет функцию через свой прототип. Вот Ваш код с выводом вызываемых функций:
function Rectangle(width,height) {
this.width = width;
this.height = height;
let self = this;
Rectangle.prototype.getArea = function() {
console.log("getArea proto");
return this.height * this.width;
}
console.log('Ctor');
Object.defineProperty(this, 'getArea',
{
enumerable:true,
value: function() {
console.log("getArea property");
return self.height * self.width;
}
}
);
}
function fromJSON(proto, json) {
let inp = JSON.parse(json);
return Object.assign(Object.create(proto),inp);
}
let o = new Rectangle(35,2);
let p = fromJSON(Rectangle.prototype,'{"width":8,"height":6}');
console.log(o.getArea());
console.log(p.getArea());
На выходе имеем подтверждение вышеописанной трактовки:
В качестве улучшения, я бы избавился от дублирующего метода, а описание прототипа перенёс бы за пределы конструктора (нам же незачем пересоздавать метод прототипа при каждом вызове конструктора).
function Rectangle(width,height) {
this.width = width;
this.height = height;
}
Rectangle.prototype.getArea = function() {
return this.height * this.width;
};
function fromJSON(proto, json) {
let inp = JSON.parse(json);
return Object.assign(Object.create(proto),inp);
}
let o = new Rectangle(35,2);
let p = fromJSON(Rectangle.prototype,'{"width":8,"height":6}');
console.log(o.getArea());
console.log(p.getArea());
Вывод по-сути такой же, а магии в коде меньше:
Можно обойтись и без использования прототипа. Но тогда нужно будет при копировании всегда отталкиваться от какого-то полноценного объекта, который станет аналогом прототипа:
function Rectangle(width,height) {
this.width = width;
this.height = height;
this.getArea = function() {
return this.width * this.height;
};
}
function fromJSON(proto, json) {
let inp = JSON.parse(json);
return Object.assign(Object.create(proto),inp);
}
let o = new Rectangle(35, 2);
let p = fromJSON(o, '{"width":8,"height":6}');
console.log(o.getArea());
console.log(p.getArea());
Вывод такой же:
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Одно фото попадает в слайдер, все остальные выводятся отдельноПодскажите пожалуйста