开发者问题收集

是否有像 Angular2 模板中那样的 JavaScript 未定义属性处理

2016-06-29
395

我想知道是否有一种简洁的方法可以做到这一点:

if (app && app.object && app.object.foo) {
  alert(app.object.foo.bar);
}

这真的很长而且“丑陋”。

我发现 Angular2 确实有一些非常适合这种情况的东西。但我认为它仅适用于模板:

<div>{{this?.object?.foo?.bar}}</div>

这让我非常兴奋,因为我有很多代码看起来就像第一个例子一样。它完成了工作,但我真的希望有更复杂的东西。

3个回答

许多语言都具有此功能,有些语言称之为 安全导航运算符 ,甚至 Elvis 运算符 (是的,哈哈)。

JavaScript 没有此功能。如果您愿意使用 CoffeeScript ,您可以查看 存在运算符

但是,如果您想继续使用 JS,您应该查看 lodash.get() ,它允许您执行如下操作:

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// → 3

_.get(object, 'a.b.d.c', 'default');
// → 'default'
demarchisd
2016-06-29

我在网上找到了这个解决方案:

function checkNested(obj /*, level1, level2, ... levelN*/) {
  var args = Array.prototype.slice.call(arguments, 1);

  for (var i = 0; i < args.length; i++) {
    if (!obj || !obj.hasOwnProperty(args[i])) {
      return false;
    }
  obj = obj[args[i]];
 }
  return true;
}

var test = {level1:{level2:{level3:'level3'}} };

checkNested(test, 'level1', 'level2', 'level3'); // true
checkNested(test, 'level1', 'level2', 'foo'); // false

jsFiddle: https://jsfiddle.net/nikdtu/kjsxnunp/

Nikhil Maheshwari
2016-06-29

不是开箱即用的。

var string = function(v){ return v == null? "": String(v) }  //because I usually want this behaviour

var fetch = function(path, obj){
    path instanceof Array || (path = string(path).split('.'));
    for(var i=0, v=obj; i<path.length; v = v[path[i++]])
        if(v == null) return void 0;
    return v;
}

和你的代码:

if(fetch("object.foo", app)){
    alert(app.object.foo.bar);
}

或者更直接:

alert( fetch("object.foo.bar", app) );
//will alert undefined, if the path could not be resolved

参数顺序是这样的,因为这个函数通常在我的代码中进行柯里化,所以我可以这样做:

arr.map(fetch('some.deeper.path'));
Thomas
2016-06-29