7

This question is specifically about preventing unwanted properties from being added to a javascript "class". I have a class called Animal.

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

What would be the easiest way for a user to create their own Animal and add 20 properties. I want to also prevent the user from accidentally adding incorrect properties.

my current method:

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

//adding 20 more properties would require typing myAnimal 20 more times Plus if a user makes a typo it would add it as a new property.

I was hoping there would be something like this:

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

I've looked into Object.freeze Object.seal, Object.preventExtensions but not sure how they apply to classes.

2 Answers 2

11

You can Object.seal(this) at the end of the constructor to prevent new properties from being added:

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

and you can take an object with initial values in the constructor:

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

used like so:

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

with the downside that the error doesn’t point directly at typo like it would if you used multiple assignment statements.

Sign up to request clarification or add additional context in comments.

3 Comments

In your second example, I am surprised that you can call Object.assign() after Object.seal().
@kevinarpe: Object.seal() stops new properties from being added while keeping existing ones writable. You might be thinking of Object.freeze(), which makes the object entirely read-only.
Hat tip! I was confused. Thank you for the reminder.
3

You can use Proxy For this. You can set custom setter, what throw an Error when obj does not has the property. You can do the same with get too in that case no more undefined cause of typo.

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);

2 Comments

This is a very useful example of how to check for a property. Thank you.
+1 for pointing out an object I wasn't even aware of. This post suggests that proxies are quite slow but concludes that "odds are you won't feel the performance implications unless you've ever found yourself changing promise libraries...for performance reasons".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.