简体   繁体   中英

How Can I Check a Object Literal's Name in JavaScript?

Here I got a object literal which looks like this one below:

 var assets = { images: { 'sky': 'assets/sky.png', 'platform': 'assets/platform.png' }, spritesheets: { 'dude': 'assets/dude.png' } } 

And my objective is to create a function which can invoke different functions depends on the type of these assets.

I was thinking of this kind of solution:

 function preload() { for (var asset in assets) { switch ( /* check the asset's type */ ) { case 'images': // do something break; case 'spritesheets': // do something break; } } } 

How should I implement it?

Sorry for my poor use of English, since I'm not a native speaker. ;D

Javascript's for...in feature loops over the properties (or keys ) of an object, not the values . So you could do this:

function preload() {
  for (var asset in assets) {
    switch (asset) {
      case 'images':
        for (var image in assets[asset]) {
          // assets[asset][image] will be an image url
        }
        break;
      case 'spritesheets':
        for (var spritesheet in assets[asset]) {
          // assets[asset][spritesheet] will be an spritesheet url
        }
        break;
    }
  }
}

I am a bit confused as to why you even want a loop, doesn't seem like there is any need. If you are using a switch, it means you know what the expected properties are called, so why not just access them directly. For example:

// Do something with assets.images
// Do something different with assets.spritesheets

If you are worried about not knowing if they have been specified then check first:

if(assets.images){
    // Do something with assets.images
}

if(assets.spritesheets){
    // Do something different with assets.spritesheets
}

asset will respond with the name.

Therefore you can do:

switch (asset) {

http://jsfiddle.net/1tekLw5h/


However it would be cleaner if you could structure your object differently:

var assets = [
  {
    name: "images",
    files: [
       {
          key: "sky",
          path: "assets/sky.png"
       },
       {
          key: "platform",
          path: "assets/platform.png"
       }
    ]
  },
  {
    name: "spritesheets",
    files: [
       {
          key: "dude",
          path: "assets/dude.png"
       }
    ]
  }
];

You can use asset in your switch statement as the for..in loop within JavaScript will loop over any enumerable properties (which all properties of an object literal are by default).

function preload(assets) {
  for (var asset in assets) {
    switch (asset) {
      case 'images':
        // do something
        break;
      case 'spritesheets':
        // do something
        break;
    }
  }
}

If you are asking how to enumerate over an object's properties (keys) in a different manner then one way is to use Object.keys() to get an array of key names to use to iterate over.

function preload(assets) {
  Object.keys(assets).forEach(function (asset) {
    switch (asset) {
      case 'images':
        // do something
        break;
      case 'spritesheets':
        // do something
        break;
    }
  });
}

In response to your question "How should I implement it?" (not to the title question regarding how to check an object literal's name)...

Rather than use a switch statement, you could create an object that maps each asset to the function you want to invoke for it, then, in your preload function, just call the functions on that mapping object.

That object would look something like this:

var fnByAsset = {
  images: function () { /* ... */ },
  spritesheets: function () { /* ... */ }
};

(If multiple asset s share the same function, of course, you'd move the function definitions outside of the object and just reference them from the object.)

And your preload function would then look like this:

function preload() {
  Object.keys(assets).forEach(function (asset) {
    fnByAsset[asset]();
  });
}

I prefer this more functional approach over switch statements whenever possible. It feels cleaner to me and tends to be more maintainable and extensible as you add more items ( asset s in your case).

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