你可以在javascript中使用自定义对象作为对象的属性吗?

时间:2011-11-04 20:40:55

标签: javascript object properties iteration encapsulation

假设我创建了一个自定义对象/ javascript“class”(airquotes),如下所示:

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

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

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

然后我想列出那些我可以轻松添加或删除该列表中的内容的自定义对象。我决定使用对象作为存储自定义对象列表的方法,因此我可以使用

将自定义对象添加到列表中
var customObjectInstance1 = new CustomObject('someString');
var customObjectInstance2 = new CustomObject('someOtherString');
var customObjectInstance3 = new CustomObject('yetAnotherString');

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

并使用

从列表中删除自定义对象
delete myListOfCustomObjects[customObjectInstance1];

但如果我尝试使用

遍历列表
for (i in myListOfCustomObjects) {
  alert(i.privilegedGetMethod());
}

我会在FireBug控制台中看到“i.privilegedGetMethod()不是函数”的错误。有没有办法解决这个问题或javascript中的成语来做我想要的?很抱歉,如果这是一个愚蠢的问题,但我是javascript的新手,并已搜索互联网解决我的问题无济于事。任何帮助将不胜感激!

P.S。我意识到我的示例是超级简化的,我可以使用this.property或者其他东西使privateProperty公开,但是我仍然会在警报中得到未定义,并且我希望将其封装起来。

3 个答案:

答案 0 :(得分:1)

for iteration变量只是索引,而不是对象本身。所以使用:

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

并且,在我看来,如果你使用一个Object作为数组索引/哈希,它只会被转换为字符串“Object”,它最终会出现在一个带有单个条目的列表中,因为所有键都是相同(“对象”)。

答案 1 :(得分:1)

i不会像您期望的那样成为原始对象:

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

这是因为JavaScript中的所有键都是字符串。任何使用其他类型作为键的尝试都将首先由toString()序列化。

如果toString()的结果对于每个实例都不是唯一的,那么它们都将是相同的键:

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

要使它们与众不同,请定义自定义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);
}

[编辑]

使用自定义toString,您可以将对象设置为序列化键,并将值设置为有序并仍然可以继续访问它们:

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

答案 2 :(得分:1)

myListOfCustomObjects =[ 
            new CustomObject('someString'),
            new CustomObject('someOtherString'),
            new CustomObject('yetAnotherString')
]

您将通过数组索引访问任何元素。