【问题标题】:Can you use custom objects as properties of an object in javascript?你可以在javascript中使用自定义对象作为对象的属性吗?
【发布时间】:2011-12-22 08:42:21
【问题描述】:

假设我创建了一个自定义对象/javascript“类”(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 的新手,并且已经在互联网上搜索了我的问题的解决方案,但无济于事。任何帮助将不胜感激!

附:我意识到我的示例非常简化,我可以使用 this.property 或其他东西将 privateProperty 公开,但是我仍然会在警报中未定义,我想将其封装起来。

【问题讨论】:

  • 我不太确定您要在这里完成什么,但是您的代码不应该也不会工作,因为那里有语法错误。特别是你用[]而不是()调用构造函数的方式。
  • 抱歉,打错了。我固定了括号
  • 基本上我正在寻找一种方法来创建自定义对象列表并遍历它们,同时保持对其特权方法的访问。
  • 你为什么要为你的数组创建自定义对象索引呢?只需将它们放入数组中,如下所示:array.push(customObject);,然后使用标准的 for 循环遍历数组。
  • 我试图远离数组,因为我不知道按值删除项目的简单方法(我必须遍历数组,对吗?)。对于对象,我可以通过“if (something in object)”轻松检查是否存在某些东西。

标签: javascript object properties iteration encapsulation


【解决方案1】:

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

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

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

【讨论】:

  • 完全不正确。作为索引传递给数组的对象肯定不会被转换为字符串“对象”并创建一个包含一个元素的列表 - 但是它会在数组对象上创建一个属性“[object Object]”。
  • 对,我不想遍历索引而不是值吗?每个键/值对中的值都是真的。我假设我的列表对象看起来像 {CustomObject1: true, CustomObject2: true}
【解决方案2】:

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

【讨论】:

  • 啊,这就是我想知道的。所以它们都被转换为字符串?那么创建自定义对象列表并通过访问它们的特权方法来遍历它们的最佳方法是什么?
  • @user1030342 您可以通过将它们设置为值而不仅仅是true,将它们与其唯一的序列化相关联。以我的编辑为例。
  • 好的,现在我遇到了一个奇怪的错误。如果我只做一种特权方法,那效果很好!但是,当我有多个时,第一个特权方法可以正常工作,但是其余的会出现“myListOfCustomObjects [i] 未定义”错误。我交换了订单,第一个总是可以正常工作,但是其余的却出现了该错误。我又错过了什么吗?
  • 奇怪,当我发出警报时,我会收到上述错误,但如果我执行 console.log,我不会收到错误消息。好吧,我想我大部分时间都在工作。回顾一下,对象中的所有键都变成字符串,但值可以是任何东西,是吗?感谢您的帮助!
【解决方案3】:
myListOfCustomObjects =[ 
            new CustomObject('someString'),
            new CustomObject('someOtherString'),
            new CustomObject('yetAnotherString')
]

您可以通过数组的索引访问任何元素。

【讨论】:

  • 如果我最终不得不使用数组,从列表中删除对象的最佳方法是什么。说如果我想从列表中删除 CustomObject('yetAnotherString'),删除它的最佳方法是什么?
最近更新 更多