简体   繁体   中英

Javascript object literal: why can't I do this?

I have the following (simplified) object literal. The icons method uses closure to hide the icons variable, which I'd like to have as an associative array for later lookups.

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

    } ()
}

I add items to the to the icons object like so:

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

The following doesn't work:

allIcons[iconType] = icon;

But this does:

allIcons.push(icon);

Outside of the closure the associative array style works fine, so perhaps there is a conflict with jQuery? The error I get in firebug a is undefined looks to come from the library. I'd like to maintain the associative array style.

Any ideas?

Update

It looks like this conflict is coming from google maps. Odd, not sure of a way around this.

Dumbass Update

The part of my object literal that returned a base GIcon() object wasn't returning an object at all. So, the object didn't have the right properties.

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

And MapListings.baseIcon is NOT the same as MapListings.baseIcon()! D'oh

if you want a lookup table, just do var allIcons = {}

EDIT: Though technically it should work either way, as an array IS an object. Are you sure there isn't more to this?

EDIT #2 : Can't you just make allIcons as a property of MapListings?

EDIT #3: I think it's working, but maybe you're not accessing it right? That or it fails creating the object with Google somehow, or the error you posted is happening elsewhere, and not here

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'] )

You shouldn't loop using .length but instead directly access c7 or c8 .

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

So one thing you could do to fix this is change the way you reference the array. Since external to your add method you do this:

MapListings.icons["c7"]

You can also just use this to add to your array inside your add function:

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

allIcons[iconType] = icon; fails because allIcons is an Array, not an object. Try initializing allIcons to {} instead. That would allow you to place items in the collection by key.

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