#javascript #class
Вопрос:
У меня есть class File
конструктор и, который принимает fullname
параметр. Как я могу предотвратить это изменение? Я пробовал это с сеттером и геттером, но это не работает
class File {
constructor(fullName) {
this.fullName = fullName;
}
get fullname() {
return this.fullname;
}
set fullname(newValue) {
if (newValue) {
newValue = this.fullName;
}
}
}
let example = new File("example.txt");
example.fullName = "modified.txt";
console.log(example.fullName); // should be example.txt
Комментарии:
1. Опечатка :
return this.fullName
2. не связано с проблемой, но внутри сеттера:
newValue = this.fullName;
—> >this.fullName = newValue;
и вам нужно исправить имя сеттера:fullname
—> >fullName
. Также переименуйте геттер.3. @TusharShahi, @Yousaf: Это не очень помогло бы, потому что геттер/сеттер
fullname
не запускается при доступеfullName
.4. @FelixKling правильно; Я предложил оператору исправить имя сеттера.
Ответ №1:
Вы можете создать свойство только для чтения с помощью Object.defineProperty
:
class File {
constructor(fullName) {
Object.defineProperty(this, 'fullName', {
enumerable: true,
writable: false, // not necessary (because default) but more explicit,
value: fullName,
});
}
}
let example = new File("example.txt");
example.fullName = "modified.txt";
console.log(example.fullName);
Обратите внимание, что присвоение свойства приведет к ошибке в строгом режиме.
Если вы хотите быть в строгом режиме, но также хотите молча игнорировать назначение, вы можете воспользоваться этим getter/setter
подходом, но вам все равно придется хранить реальное значение где-то на объекте, а это означает, что к нему все еще можно получить доступ и изменить, если знать, к какому свойству обращаться.~ но это немного более развито. Вы бы в основном создали средство получения и настройки для каждого экземпляра, тем самым избежав необходимости хранить исходное значение в самом объекте:
"use strict";
class File {
constructor(fullName) {
Object.defineProperty(this, 'fullName', {
enumerable: true,
set: value => {}, // ignore
get: () => fullName,
});
}
}
let example = new File("example.txt");
example.fullName = "modified.txt";
console.log(example.fullName);
Частные свойства, которые являются относительно новой функцией JavaScript, могут сделать это немного «приятнее» (субъективно):
class File {
#fullName;
constructor(fullName) {
this.#fullName = fullName;
}
get fullName() {
return this.#fullName;
}
set fullName(newValue) {
// ignore new value
}
}
let example = new File("example.txt");
example.fullName = "modified.txt";
console.log(example.fullName);
Комментарии:
1. Использование частных свойств помогло мне, но я задаюсь вопросом, почему у меня ошибка
Cannot assign to read only property 'fullName' of object '#<File>
в первом методе? Спасибо за помощь2. Ах, когда вы находитесь в строгом режиме, попытка присвоить свойство только для чтения выдает ошибку вместо того, чтобы молча игнорировать ее.
Ответ №2:
Использование синтаксиса ES2020 :
class File {
#fullName = null;
constructor(fullName) {
this.fullName = fullName;
}
get fullName() {
return this.#fullName;
}
set fullName(newValue) {
this.#fullName ??= newValue;
}
}
let example = new File("example.txt");
example.fullName = "modified.txt";
console.log(example.fullName); // should be example.txt
Есть несколько мест , в которых вы написали fullName
с fullname
ошибкой, обратите внимание на случаи, когда это важно в JavaScript.
Комментарии:
1. FWIW, частная собственность не является частью ES6. Я думаю, что они были частью выпуска этого года?
2. @FelixKling Да, спасибо, что указал.
class
Ключевое слово является частью синтаксиса ES6, но личные поля и логическое присвоение??=
значения null появились намного позже.