保护对象属性以防止被控制台覆盖

时间:2019-01-05 19:08:00

标签: javascript node.js oop

我正在尝试保护对象的属性以免被控制台覆盖。例如我有一个人对象,并带有过敏列表。过敏列表应该可以修改,但是它应该始终是列表,如果用户尝试编写“ 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.

2 个答案:

答案 0 :(得分:3)

您可以使用Object.definePropertyallergies设为不可写属性:

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预设

Source