JavaScript对象字面量:为什么我不能这样做?

3

我有以下(简化的)对象字面量。icons方法使用闭包隐藏了icons变量,我希望将其作为关联数组以供稍后查找。

var MapListings = {
    icons: function () {
        var allIcons = [] ;

        return {
            add: function (iconType, iconImage) {
                var icon = new GIcon(MapListings.baseIcon);
                icon.image = iconImage;
                allIcons[iconType] = icon; // fails, but this is what I want
                // allIcons.push(icon); // works, but this is not what I want
            },
            get: function () {
                return allIcons;
            }
        };

    } ()
}

我这样向图标对象添加项目:

MapListings.icons.add("c7", "/images/maps/blue.png");
MapListings.icons.add("c8", "/images/maps/red.png");

以下方法无法正常工作:
allIcons[iconType] = icon;

但这个会:
allIcons.push(icon);

在闭包之外,关联数组样式运行良好,因此可能与jQuery存在冲突?在firebug中收到的错误a未定义似乎来自库。我想保持关联数组样式。
有什么想法吗?
更新
看起来这个冲突来自谷歌地图。奇怪,不确定有没有绕过这种方式。
蠢蛋更新
我的对象文字的一部分返回了一个基本的GIcon()对象,实际上并没有返回对象。因此,对象没有正确的属性。
baseIcon: function () {
    var base = new GIcon();
    base.shadow = '/images/maps/shadow.png';
    base.iconSize = new GSize(12, 20);
    base.shadowSize = new GSize(22, 20);
    base.iconAnchor = new GPoint(6, 20);
    base.infoWindowAnchor = new GPoint(5, 1);
    return base;
}

MapListings.baseIcon 不等于 MapListings.baseIcon()!这真是个大失误。


我刚把这段代码粘贴到一个HTML文件中,并用一个占位符替换了GIcon。看起来运行得很好。也许错误出在GIcon对象上,而不是你的代码上。我在Linux上使用Firefox 3.5运行。 - Gennadiy
1
你确定 "a 未定义" 错误与这段代码有关吗? - Jacob
@gennaidiy - GIcon来自谷歌地图。造成冲突的不是实际的GIcon对象,而是谷歌地图库。 - ScottE
除了jQuery库,您是否使用了其他库?它的版本是什么?这行代码能够进入jQuery中的唯一方式是有些变化绑定到本地阵列对象。jQuery本身不会这样做,但其他库会这样做。(事实上,谷歌库可能会这样做,我并不确定。) - Pointy
当你说allIcons[iconType] = icon失败时,这个赋值操作具体是哪里出了问题?这只是一个简单的对象赋值,我不明白它怎么会失败。你确定这就是导致异常的地方吗?请设置断点并逐步执行代码以获取更多信息。 - Anurag
3个回答

4
如果你想要一个查找表,只需执行var allIcons = {}
编辑:虽然从技术上讲,数组也是对象,但你确定这就是全部内容吗?
编辑#2: 你不能把allIcons作为MapListings的属性吗?
编辑#3: 我认为它正在工作,但是可能你没有正确地访问它?或者它无法与Google一起创建对象,或者你发布的错误发生在其他地方,而不是这里。
function GIcon(){};
var MapListings = {
    icons: function () {
        var allIcons = [] ;

        return {
            add: function (iconType, iconImage) {
                var icon = new GIcon(MapListings.baseIcon);
                icon.image = iconImage;
                allIcons[iconType] = icon; // fails, but this is what I want
                // allIcons.push(icon); // works, but this is not what I want
                window.x = allIcons
            },
            get: function () {
                return allIcons;
            }
        };

    } ()
};

MapListings.icons.add("c7", "/images/maps/blue.png");
MapListings.icons.add("c8", "/images/maps/red.png");

alert( MapListings.icons.get()['c8']['image'] )

您不应该使用 .length 进行循环,而是直接访问 c7c8

x = MapListings.icons.get();
for ( var prop in x ) {
    if ( x.hasOwnProperty(prop ) ) {
        alert( x[prop]['image'] )
    }
}

这样做会破坏闭包的目的。我更愿意将其保留为私有成员,因为 .add 方法还会执行其他工作。我只想以这种方式添加图标。 - ScottE
请看我上面的编辑。今天的教训是调试。抱歉打扰了。 - ScottE

1

因此,您可以做的一件事是更改引用数组的方式来修复此问题。由于在add方法之外,您执行以下操作:

MapListings.icons["c7"]

你也可以在 add 函数内部使用这个来添加到你的数组中:

add: function (iconType, iconImage) { 
    MapListings.icons[iconType] = iconImage;
}, 

0

allIcons[iconType] = icon; 失败了,因为 allIcons 是一个数组,而不是一个对象。尝试将 allIcons 初始化为 {}。这样可以通过键将项目放入集合中。


不是真的,在我的示例之外它可以正常工作。虽然不建议以这种方式使用它们,但请看这里:http://www.hunlock.com/blogs/Mastering_Javascript_Arrays - ScottE
我在那份文件中找不到任何关于允许使用字符串索引来访问数组的内容。 - Jacob
1
在JS中,任何对象都可以有属性,因此数组也可以有属性。 - casablanca
啊,我知道你的意思。我猜你可以向一个数组对象添加任意属性。但这并不等同于关联数组。 - Jacob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接