简体   繁体   中英

Javascript: array member variable not working as instance variable in prototypical inheritance

I am trying to use javascript inheritance in my code. Following is the jsfiddle for the same. http://jsfiddle.net/Fetsz/3/

var baseObject = Object.create(Object, {  
    // this works as an instance variable for derived objects  
    name: {
        writable: true,
        configurable: true,
        enumerable: true,
        value: null    
    },   
    // this should act as instance variable for derived objects   
    values: {
        writable: true,
        configurable: true,
        enumerable: true,
        value: []    
    },
    displayAlert: {
        value: function (){
            alert("Alert from base object");
        }
    }
});

var derivedObj1 = Object.create(baseObject, {});    
var derivedObj2 = Object.create(baseObject, {});    

function displayValues (obj) {
    alert("values for " + obj.name + "\n" + JSON.stringify(obj.values));
};

$(document).ready(function(){
    derivedObj1.name = "Object 1";
    derivedObj2.name = "Object 2";

    derivedObj1.values.push("DO1 element");
    derivedObj2.values.push("DO2 element");

    derivedObj1.displayAlert();

    // should display values added only for derivedObj1
    displayValues(derivedObj1);

    // should display values added only for derivedObj2
    displayValues(derivedObj2);
});

I also checked following question which nicely explains why my code doesn't work. Javascript Inheritance: Parent's array variable retains value

I need to have an array member variable in every derived class which will contain certain values. I was trying to achieve the same by adding array in base class. As mentioned in above question, to achieve the same, I will have to add array member to each derived class. Is there any other way to achieve this without modifying every derived class?

When they are created, both derivedObj1.values and derivedObj2.values point to the same array object. If you were to first reassign each one using derivedObj1.values = []; , in the same way as you are reassigning the name property, your code would behave as expected.

Instead of adding the values property to the original baseObject, you could create an init method that adds an array to the instance:

var baseObject = Object.create(Object, {  
    // this works as an instance variable for derived objects  
    name: {
        writable: true,
        configurable: true,
        enumerable: true,
        value: null    
    },   
    // this should act as instance variable for derived objects   
    init: {
        writable: true,
        configurable: true,
        enumerable: true,
        value: function(){
            this.values = [];
        }
    },
    displayAlert: {
        value: function (){
            alert("Alert from base object");
        }
    }
});

var derivedObj1 = Object.create(baseObject, {});
derivedObj1.init();
var derivedObj2 = Object.create(baseObject, {});
derivedObj2.init();

Your variables can't be on the prototype if you don't want them to be shared by all instances. You could create a second object with just the property definition for the array,and pass it as the second parameter to Object.create :

var arrDef = {
        values: {
            writable: true,
            configurable: true,
            enumerable: true,
            value: []
        }
}
var derivedObj1 = Object.create(baseObject, arrDef);    
var derivedObj2 = Object.create(baseObject, arrDef);    

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