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

发布于 2024-12-13 18:47:39 字数 1314 浏览 0 评论 0原文

假设我创建一个自定义对象/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 的新手,并且在互联网上搜索了我的问题的解决方案,但没有成功。任何帮助将不胜感激!

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

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!

P.S. 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不寐倦长更 2024-12-20 18:47:39

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

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());
}
薄荷梦 2024-12-20 18:47:39

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

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

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

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").

[旋木] 2024-12-20 18:47:39
myListOfCustomObjects =[ 
            new CustomObject('someString'),
            new CustomObject('someOtherString'),
            new CustomObject('yetAnotherString')
]

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

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文