Как заменить функцию конструктор на класс с закрытыми полями?
Нужно решить задачку. Условия следующие:
Замените функцию конструктор на класс. Все свойства класса Car поменяйте на закрытые поля и для каждого поля добавьте getter и setter по необходимости. Для поля html предусмотрите возможность только получения значения, организуйте код таким образом, чтобы не допустить редактирование значения свойства html напрямую.
Ниже приведена функция конструктор и то как сделал я. В моем варианте выдает вот такое в консоль
Uncaught SyntaxError: Private field '#html' must be declared in an enclosing class
Возможно из-за закрытых полей у меня проблема с доступом. В общем надеюсь на подсказку где я проморгал. Спасибо.
function Car(image, manufacturer) {
this.image = image;
this.manufacturer = manufacturer;
this.html = `<img src="images/${this.image}" /><br />Производитель: ${this.manufacturer}<br />`;
}
let car1 = new Car("audi-a6-250.jpg", "Audi");
let car2 = new Car("jaguar-x-type-250.jpg", "Jaguar");
let car3 = new Car("porsche-carrera-911-250.jpg", "Porsce");
let placeholder1 = document.querySelector("#placeholder1");
let placeholder2 = document.querySelector("#placeholder2");
let placeholder3 = document.querySelector("#placeholder3");
placeholder1.innerHTML = car1.html;
placeholder2.innerHTML = car2.html;
placeholder3.innerHTML = car3.html;
/* <-------Мой вариант--------> */
class Car {
#image;
#manufacture;
constructor(image, manufacture, html) {
this.#image = image;
this.#manufacture = manufacture;
this.#html = `<img src="images/${this.#image}" /><br />Производитель: ${this.#manufacturer}<br />`;
}
set html (value) {
if (value = "") {
alert('Ошибка')
} else {
this.#html = value
}
}
get html () {
if (this.#html === undefined) {
this.#html = 0;
}
return this.#html;
}
}
let car1 = new Car("audi-a6-250.jpg", "Audi");
let car2 = new Car("jaguar-x-type-250.jpg", "Jaguar");
let car3 = new Car("porsche-carrera-911-250.jpg", "Porsce");
let placeholder1 = document.querySelector("#placeholder1");
let placeholder2 = document.querySelector("#placeholder2");
let placeholder3 = document.querySelector("#placeholder3");
placeholder1.innerHTML = car1.html;
placeholder2.innerHTML = car2.html;
placeholder3.innerHTML = car3.html;
Ответы (2 шт):
Могу ошибаться, но возможно ошибка из-за нейминга полей с решеткой. Это новшество, которое еще поддерживают не все движки, нужен полифил. Раньше защищенные свойства начинались с _, но они конечно же попадут в дочерние классы. Подробнее вот здесь можете почитать, тут всё описано https://learn.javascript.ru/private-protected-properties-methods
const placeholder1 = document.querySelector('#placeholder1');
const placeholder2 = document.querySelector('#placeholder2');
const placeholder3 = document.querySelector('#placeholder3');
class Car {
_image;
_manufacturer;
_html;
constructor(image, manufacturer) {
this._image = image;
this._manufacturer = manufacturer;
this._html = `<img src="images/${this._image}" /><br />Производитель: ${this._manufacturer}<br />`;
}
set html(val) {
throw new Error("You can't edit private fields");
}
get html() {
return this._html;
}
}
const car1 = new Car('audi-a6-250.jpg', 'Audi');
const car2 = new Car('jaguar-x-type-250.jpg', 'Jaguar');
const car3 = new Car('porsche-carrera-911-250.jpg', 'Porsce');
placeholder1.innerHTML = car1.html;
placeholder2.innerHTML = car2.html;
placeholder3.innerHTML = car3.html;
Вариант с новым синтаксисом
const placeholder1 = document.querySelector('#placeholder1');
const placeholder2 = document.querySelector('#placeholder2');
const placeholder3 = document.querySelector('#placeholder3');
class Car {
#image;
#manufacturer;
#html;
constructor(image, manufacturer) {
this.#image = image;
this.#manufacturer = manufacturer;
this.#html = `<img src="images/${this.#image}" /><br />Производитель: ${
this.#manufacturer
}<br />`;
}
set html(val) {
throw new Error("You can't edit private fields");
}
get html() {
return this.#html;
}
}
const car1 = new Car('audi-a6-250.jpg', 'Audi');
const car2 = new Car('jaguar-x-type-250.jpg', 'Jaguar');
const car3 = new Car('porsche-carrera-911-250.jpg', 'Porsce');
placeholder1.innerHTML = car1.html;
placeholder2.innerHTML = car2.html;
placeholder3.innerHTML = car3.html;
Uncaught SyntaxError: Private field '#html' must be declared in an enclosing class
Перевод:
частное поле '#html' должно быть объявлено во включающем классе
Вы не объявили приватную переменную #html
class Car {
#image = null;
#manufacture = null;
#html = null;
constructor(image, manufacture, html) {
this.#image = image;
this.#manufacture = manufacture;
this.#html = `<img src="images/${this.#image}" /><br />Производитель: ${this.#manufacture}<br />`;
}
set html(value) {
if (value === "") {
throw new Error('Ошибка, html не может быть равен пустой строке');
} else {
this.#html = value;
}
}
get html() {
return this.#html;
}
}
let car1 = new Car("audi-a6-250.jpg", "Audi");
let car2 = new Car("jaguar-x-type-250.jpg", "Jaguar");
let car3 = new Car("porsche-carrera-911-250.jpg", "Porsce");
let placeholder1 = document.querySelector("#placeholder1");
let placeholder2 = document.querySelector("#placeholder2");
let placeholder3 = document.querySelector("#placeholder3");
placeholder1.innerHTML = car1.html;
placeholder2.innerHTML = car2.html;
placeholder3.innerHTML = car3.html;
<div id="placeholder1">placeholder1</div>
<div id="placeholder2">placeholder2</div>
<div id="placeholder3">placeholder3</div>