简体   繁体   中英

Javascript “new” keyword making references to “class” properties

I have a javascript "class", that I instanciate several times. My issue is that modifying properties from the instances does actually modify those properties of the "class", so further instances are not initialized in the way I'd like. Here is a simplified snippet of what happens, the original code is using BackboneJS but this is enough to illustrate my case:

 var foo = function() { this.defaults.id = 1; }; // This is my property foo.prototype.defaults = { id: 0, }; console.log( foo.prototype.defaults ); // => {id: 0} var bar = new foo(); console.log( foo.prototype.defaults ); // => {id: 1} 

I thought that the "new" keyword would make a brand new object but it seems that it just makes a reference to the prototype properties. The best option I came with is to clone all properties from inside the constructor...

Do anyone have a clean way to achieve a clean "Class Property" behavior ?

Many thanks in advance,

Romain.

Edit: It does not work from the SO snippet... just copy/paste it to your console if you want.

The prototype is shared among all objects of this type. A new copy is not made. The usual way to initialize properties that are to be unique to this instance is to initialize them directly in the constructor:

this.property = "foo";

This will override any property of the same name in the prototype and will be unique per instance.


In general, the prototype is not used for data properties because they are shared among all instances. If you want to initialize an object with a default set of data properties, the "best practice" for that is to assign a default set of properties into the object instance and then set any overrides. You can't just assign a default object because objects are assigned by pointer, not by copy so all objects would still be pointing at the same object (the same issue you have when using the prototype).


You could initialize your object with a set of defaults like this:

var foo = function() {
    this.defaults = {};
    // copy default properties
    for (var prop in foo.defaults) {
        this.defaults[prop] = foo.defaults[prop];
    }
    this.defaults.id = 1;
};

// defaults (not on the prototype)
foo.defaults = {
    id: 0,
    something: "whatever",
    line: 22
};

Though, in practice, it is usually easier to just code in the defaults like this:

var foo = function() {
    this.options = {
        id: 1,
        something: "whatever",
        line: 22
    };
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM