我正在尝试保护对象的属性以免被控制台覆盖。例如我有一个人对象,并带有过敏列表。过敏列表应该可以修改,但是它应该始终是列表,如果用户尝试编写“ person.allergies =“ unsense”'
,则应该抛出错误我已经尝试研究Object.freeze()和Object.seal(),但是无法将它们用于此目的,因为我不相信有一种解冻对象的方法。
class Person {
constructor(name){
this.name = name
this.allergies = []
}
addAllergy(allergy){
this.allergies.push(allergy)
return allergy
}
}
ben = new Person('Ben') // Creating a new Object
ben.addAllergy('Dairy') // Giving the object a new allergy
ben.allergies // Should output ['Dairy']
ben.allergies = 'Soy' // Should make no changes to ben object.
答案 0 :(得分:3)
您可以使用Object.defineProperty
将allergies
设为不可写属性:
class Person {
constructor(name){
this.name = name
Object.defineProperty(this, 'allergies', {
value: [],
writable: false
});
}
addAllergy(allergy){
this.allergies.push(allergy)
return allergy
}
}
ben = new Person('Ben') // Creating a new Object
ben.addAllergy('Dairy') // Giving the object a new allergy
console.log(ben.allergies) // Should output ['Dairy']
ben.allergies = 'Soy' // Should make no changes to ben object.
ben.addAllergy('Peanutes')
console.log(ben.allergies) // still array
writable
默认为false
,因此您不需要显式设置它,但是我认为它使意图更清晰。 configurable
也默认为false
,这意味着您无法通过再次调用Object.defineProperty()
重新定义属性。
答案 1 :(得分:1)
使用私有属性:
class Person {
#allergies;
constructor(name){
this.name = name
this.#allergies = []
}
addAllergy(allergy){
this.#allergies.push(allergy)
return allergy
}
get allergies() {
// you might want to deep clone it here
// to fully protect from changes the array behind
return this.#allergies;
}
set allergies(value) {
throw new Error('haha, I got you!');
}
}
私有字段正在ECMA标准中实现。您可以 今天就开始使用Babel 7和Stage 3预设