在javascript中合并

时间:2012-11-06 17:48:09

标签: javascript jquery backbone.js underscore.js

我正在使用jQueryBackbone(以及underscore)和RequireJS

我有这段代码:

var products = _.map(items, function(item) {
    return new ProductModel({
        title: item.product.title,
        description: item.product.description,
        link: item.product.link,
        'image-src': item.product.images[0].link,
        'image-height': item.product.images[0].height,
        'image-width': item.product.images[0].width
    });
});

不幸的是,一切都可能是null。我所说的所有内容item, item.product, item.product.images, item.product.images[0]等等都可能是null s。

我正在寻找像“合并”这样的东西:

    如果nullitem.product
  1. 将知道如何处理item并且不会抛出null的例外。
  2. 如果有null
  3. 将允许我提供默认值。
  4. 有类似的吗?

6 个答案:

答案 0 :(得分:4)

您可以使用布尔&&并依赖short-circuiting

...
'image_src': item && item.product && item.product.images && item.product.images[0] && item.product.images[0].link,
'image_height': item && item.product && item.product.images && item.product.images[0] && item.product.images[0].height,
...

更有可能的是,您不希望在如此多的行中执行相同的测试。我会将您的返回值与其各种属性设置为某些合理的默认值,然后在item.product.images[0]为非空时有条件地添加实际值:

var returnObject = { /* default values here */ }, product, image;

if (product = item && item.product) {
    returnObject.title = product.title,
    returnObject.description = product.description,
    returnObject.link = product.link
};

if (image = product && product.images && product.images[0]) {
    returnObject['image-src'] = image.link;
    returnObject['image-height'] = image.height;
    returnObject['image-width'] = image.width;
}

return returnObject;

答案 1 :(得分:3)

我首先.filter出空产品:

var goodItems = _.filter(items, function(item) {
     return 'product' in item;
});

如果product中的那个不存在,则通过提供空对象来简化图像测试:

var products = _.map(goodItems, function(item) {
    var product = item.product;
    var img = (product.images && product.images[0]) || {};
    return new ProductModel({
        title: product.title,
        description: product.description,
        link: product.link,
        'image-src': img.link,
        'image-height': img.height,
        'image-width': img.width
    });
});

答案 2 :(得分:0)

如果你想要null的默认值,那么你可以创建一个这样的辅助函数:

var coalesce = function(obj, path, defaultValue) {
  while(obj != null && path.length) {
    obj = obj[path.shift()];
  }
  return (obj == null ? defaultValue : obj);
};

您可以按如下方式使用它:

coalesce(item, ["product", "title"], "Default title");
coalesce(item, ["product", "images", 0, "link"], "Default image link");

答案 3 :(得分:0)

不确定是否有类似内容,但我认为您可以创建和使用自定义函数,如下所示:

    return new ProductModel({
             title: getPorductAttribute(item,'title'),
             description: getPorductAttribute(item,'description'),
             link: getPorductAttribute(item, 'link'),
             'image-src': getImageAttirbute(item,0,'link'),
             'image-height': getImageAttirbute(item,0,'height'),
             'image-width': getImageAttirbute(item,0,'width')
            });


  function getPorductAttribute(item, attributeName){
       if(!(item && item.product)) 
           return defaultValue;
       return item.product.getAttribute(attributeName);
   }

  function getImageAttirbute(item, index, attributeName){
       if(!(item && item.product && item.product.images)) 
           return defaultValue;
       return item.product.images[index].getAttribute(attributeName);
   }

答案 4 :(得分:0)

您可以使用逻辑OR运算符“||”合并,如这里所描述的......

http://pietschsoft.com/post/2008/10/14/JavaScript-Gem-Null-Coalescing-using-the-OR-Operator

  

var something = maybeNothing || 0;

适用于null或undefined。

答案 5 :(得分:0)

如果你不确定对象究竟是什么。你可以做好旧的尝试......



var testObject = {
  alpha: {
    beta: null
  },
  gama: {
    delta: null
  }  
};

try {
    console.log(testObject.alpha.beta.gama.delta);
} catch(err) {    
    alert(err.message);
}




这不会破坏您的应用,因为错误不是throw。您可以在catch语句中执行的操作是使用缺少的默认值填充对象。