如何创建具有不可变属性的 javascript class

How do you create a javascript class with immutable properties

这个问题专门是关于防止将不需要的属性添加到 javascript "class"。我有一个叫 Animal 的 class。

function Animal(){
this.name="";
this.type="";
//20 other properties
}

用户创建自己的 Animal 并添加 20 个属性的最简单方法是什么。我还想防止用户意外添加不正确的属性。

我目前的方法:

    var myAnimal= new Animal();
    myAnimal.name="fluffy";
    myAnimal.type="cat";
    myAnimal.typo="cat";

//再添加 20 个属性需要再输入 myAnimal 20 次 另外,如果用户输入错误,它会将其添加为新的 属性.

我希望有这样的东西:

myAnimal=new Animal{
name:"fluffy",
type:"cat";
typo:"cat" //would throw an error
}

我调查了 Object.freeze Object.seal、Object.preventExtensions,但不确定它们如何适用于 classes。

你可以在构造函数的末尾Object.seal(this)来防止添加新的属性:

function Animal() {
    this.name = "";
    this.type = "";
    // 20 other properties
    Object.seal(this);
}

并且您可以在构造函数中获取具有初始值的对象:

function Animal(initial) {
    this.name = "";
    this.type = "";
    // 20 other properties
    Object.seal(this);
    Object.assign(this, initial);
}

像这样使用:

myAnimal = new Animal({
    name: "fluffy",
    type: "cat",
    typo: "cat",
});

缺点是错误不会像使用多个赋值语句那样直接指向 typo

您可以使用 Proxy 为此。 您可以设置自定义 setter,当 obj 没有 属性 时抛出错误。 你也可以对 get 做同样的事情,在那种情况下不再有 undefined 打字错误的原因。

function Animal() {
    this.name = "";
    this.type = "";
    
    return new Proxy(this, {
        set: function(obj, prop, value) {
            if (!obj.hasOwnProperty(prop))
            {
                throw Error("I don`t have this property: " + prop);
            }
            obj[prop] = value;
        }
    });
}

var cat = new Animal();
console.log(cat);
cat.name = "Rita";
console.log(cat);
cat.nama = "Rata";
console.log(cat);