简体   繁体   中英

Can you use custom objects as properties of an object in javascript?

Suppose I create a custom object/javascript "class" (airquotes) as follows:

// Constructor
function CustomObject(stringParam) {
  var privateProperty = stringParam;

  // Accessor
  this.privilegedGetMethod = function() {
    return privateProperty;
  }

  // Mutator
  this.privilegedSetMethod = function(newStringParam) {
    privateProperty = newStringParam;
  }
}

Then I want to make a list of those custom objects where I can easily add or remove things from that list. I decide to use objects as a way to store the list of custom objects, so I can add custom objects to the list with

var customObjectInstance1 = new CustomObject('someString');
var customObjectInstance2 = new CustomObject('someOtherString');
var customObjectInstance3 = new CustomObject('yetAnotherString');

myListOfCustomObjects[customObjectInstance1] = true;
myListOfCustomObjects[customObjectInstance2] = true;
myListOfCustomObjects[customObjectInstance3] = true;

and remove custom objects from the list with

delete myListOfCustomObjects[customObjectInstance1];

but if i try to iterate through the list with

for (i in myListOfCustomObjects) {
  alert(i.privilegedGetMethod());
}

I would get an error in the FireBug console that says "i.privilegedGetMethod() is not a function". Is there a way to fix this problem or an idiom in javascript to do what I want? Sorry if this is a dumb question, but I'm new to javascript and have scoured the internet for solutions to my problem with no avail. Any help would be appreciated!

PS I realize that my example is super simplified, and I can just make the privateProperty public using this.property or something, but then i would still get undefined in the alert, and I would like to keep it encapsulated.

The for iteration variable is just the index, not the object itself. So use:

for (i in myListOfCustomObjects) {
  alert(myListOfCustomObjects[i].privilegedGetMethod());
}

and, in my opinion, if you use an Object as an array index / hash, it just would be converted to the string "Object", which ends up in a list with a single entry, because all the keys are the same ("Object").

i won't be the original object as you were expecting:

for (i in myListOfCustomObjects) {
    alert(typeof i); // "string"
}

This is because all keys in JavaScript are Strings. Any attempt to use another type as a key will first be serialized by toString() .

If the result of toString() isn't somehow unique for each instance, they will all be the same key:

function MyClass() { }
var obj = {};

var k1 = new MyClass();
var k2 = new MyClass();

obj[k1] = {};
obj[k2] = {};

// only 1 "[object Object]" key was created, not 2 object keys
for (var key in obj) {
    alert(key);
}

To make them unique, define a custom toString :

function CustomObject(stringParam) {
    /* snip */

    this.toString = function () {
        return 'CustomObject ' + stringParam;
    };
}

var obj = {};
var k1 = new CustomObject('key1');
var k2 = new CustomObject('key2');

obj[k1] = {};
obj[k2] = {};

// "CustomObject key1" then "CustomObject key2"
for (var key in obj) {
    alert(key);
}

[Edit]

With a custom toString , you can set the object as the serialized key and the value to keep them organized and still continue to access them:

var customObjectInstance1 = new CustomObject('someString');
var customObjectInstance2 = new CustomObject('someOtherString');
var customObjectInstance3 = new CustomObject('yetAnotherString');

myListOfCustomObjects[customObjectInstance1] = customObjectInstance1;
myListOfCustomObjects[customObjectInstance2] = customObjectInstance2;
myListOfCustomObjects[customObjectInstance3] = customObjectInstance3;

for (i in myListOfCustomObjects) {
  alert(myListOfCustomObjects[i].privilegedGetMethod());
}
myListOfCustomObjects =[ 
            new CustomObject('someString'),
            new CustomObject('someOtherString'),
            new CustomObject('yetAnotherString')
]

you will get access to any element by index of array.

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