我将举例解释:

猫王运算符(?:)

“猫王运算符”是缩写 Java的三元运算符。一个 这很方便的例子是 返回一个“合理的默认值” 如果表达式解析为false或 null。一个简单的例子是这样的 这样的:

def gender = user.male ? "male" : "female"  //traditional ternary operator usage

def displayName = user.name ?: "Anonymous"  //more compact Elvis operator

安全导航操作员(?.) 使用安全导航操作符 来避免NullPointerException。 通常当你有一个参考 您可能需要验证的对象 在访问前它不是空的 对象的方法或属性。 为了避免这种情况,安全航行 运算符将简单地返回null 而不是抛出异常,比如 所以:

def user = User.find( "admin" )           //this might be null if 'admin' does not exist
def streetName = user?.address?.street    //streetName will be null if user or user.address is null - no NPE thrown

当前回答

我认为lodash _.get()在这里可以提供帮助,就像在_。Get (user, 'name'),以及更复杂的任务,如_。Get (o, 'a[0].b.c', 'default-value')

其他回答

2020年更新

JavaScript现在有了Elvis操作符和安全导航操作符的等价物。


安全出入物业

可选的链接运算符(?.)目前是ECMAScript第四阶段的提案。你今天可以用它来对付巴别塔。

// `undefined` if either `a` or `b` are `null`/`undefined`. `a.b.c` otherwise.
const myVariable = a?.b?.c;

逻辑与运算符(&&)是处理这种情况的“旧的”、更冗长的方法。

const myVariable = a && a.b && a.b.c;

提供默认值

空合并运算符(??)目前是第4阶段的ECMAScript提案。你今天可以用它来对付巴别塔。如果运算符的左边是一个空值(null/undefined),它允许您设置一个默认值。

const myVariable = a?.b?.c ?? 'Some other value';

// Evaluates to 'Some other value'
const myVariable2 = null ?? 'Some other value';

// Evaluates to ''
const myVariable3 = '' ?? 'Some other value';

逻辑或运算符(||)是一种行为略有不同的替代解决方案。它允许您在操作符左侧为假值时设置默认值。注意下面的myVariable3的结果与上面的myVariable3不同。

const myVariable = a?.b?.c || 'Some other value';

// Evaluates to 'Some other value'
const myVariable2 = null || 'Some other value';

// Evaluates to 'Some other value'
const myVariable3 = '' || 'Some other value';

这是一个有趣的解决方案,安全导航操作员使用一些mixin..

http://jsfiddle.net/avernet/npcmv/

  // Assume you have the following data structure
  var companies = {
      orbeon: {
          cfo: "Erik",
          cto: "Alex"
      }
  };

  // Extend Underscore.js
  _.mixin({ 
      // Safe navigation
      attr: function(obj, name) { return obj == null ? obj : obj[name]; },
      // So we can chain console.log
      log: function(obj) { console.log(obj); }
  });

  // Shortcut, 'cause I'm lazy
  var C = _(companies).chain();

  // Simple case: returns Erik
  C.attr("orbeon").attr("cfo").log();
  // Simple case too, no CEO in Orbeon, returns undefined
  C.attr("orbeon").attr("ceo").log();
  // IBM unknown, but doesn't lead to an error, returns undefined
  C.attr("ibm").attr("ceo").log();

我阅读了这篇文章(https://www.beyondjava.net/elvis-operator-aka-safe-navigation-javascript-typescript),并使用代理修改了解决方案。

function safe(obj) {
    return new Proxy(obj, {
        get: function(target, name) {
            const result = target[name];
            if (!!result) {
                return (result instanceof Object)? safe(result) : result;
            }
            return safe.nullObj;
        },
    });
}

safe.nullObj = safe({});
safe.safeGet= function(obj, expression) {
    let safeObj = safe(obj);
    let safeResult = expression(safeObj);

    if (safeResult === safe.nullObj) {
        return undefined;
    }
    return safeResult;
}

你这样称呼它:

safe.safeGet(example, (x) => x.foo.woo)

如果表达式在其路径上遇到null或undefined,则结果将是未定义的。你可以随意修改Object原型!

Object.prototype.getSafe = function (expression) {
    return safe.safeGet(this, expression);
};

example.getSafe((x) => x.foo.woo);

这通常被称为空合并运算符。Javascript没有。

我创建了一个软件包,使它更容易使用。

NPM jsdig Github jsdig

你可以处理简单的东西,比如and object:

const world = {
  locations: {
    europe: 'Munich',
    usa: 'Indianapolis'
  }
};

world.dig('locations', 'usa');
// => 'Indianapolis'

world.dig('locations', 'asia', 'japan');
// => 'null'

或者更复杂一点:

const germany = () => 'germany';
const world = [0, 1, { location: { europe: germany } }, 3];
world.dig(2, 'location', 'europe') === germany;
world.dig(2, 'location', 'europe')() === 'germany';