我将举例解释:

猫王运算符(?:)

“猫王运算符”是缩写 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

当前回答

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

其他回答

在很晚的时候,有一个建议[1]的可选链接目前在第二阶段,与巴别塔插件[2]可用。目前在我所知道的任何浏览器中都没有。

https://github.com/tc39/proposal-optional-chaining https://www.npmjs.com/package/@babel/plugin-proposal-optional-chaining

我有一个解决方案,根据你自己的需要来调整,摘自我的一篇文章:

    elvisStructureSeparator: '.',

    // An Elvis operator replacement. See:
    // http://coffeescript.org/ --> The Existential Operator
    // http://fantom.org/doc/docLang/Expressions.html#safeInvoke
    //
    // The fn parameter has a SPECIAL SYNTAX. E.g.
    // some.structure['with a selector like this'].value transforms to
    // 'some.structure.with a selector like this.value' as an fn parameter.
    //
    // Configurable with tulebox.elvisStructureSeparator.
    //
    // Usage examples: 
    // tulebox.elvis(scope, 'arbitrary.path.to.a.function', fnParamA, fnParamB, fnParamC);
    // tulebox.elvis(this, 'currentNode.favicon.filename');
    elvis: function (scope, fn) {
        tulebox.dbg('tulebox.elvis(' + scope + ', ' + fn + ', args...)');

        var implicitMsg = '....implicit value: undefined ';

        if (arguments.length < 2) {
            tulebox.dbg(implicitMsg + '(1)');
            return undefined;
        }

        // prepare args
        var args = [].slice.call(arguments, 2);
        if (scope === null || fn === null || scope === undefined || fn === undefined 
            || typeof fn !== 'string') {
            tulebox.dbg(implicitMsg + '(2)');
            return undefined;   
        }

        // check levels
        var levels = fn.split(tulebox.elvisStructureSeparator);
        if (levels.length < 1) {
            tulebox.dbg(implicitMsg + '(3)');
            return undefined;
        }

        var lastLevel = scope;

        for (var i = 0; i < levels.length; i++) {
            if (lastLevel[levels[i]] === undefined) {
                tulebox.dbg(implicitMsg + '(4)');
                return undefined;
            }
            lastLevel = lastLevel[levels[i]];
        }

        // real return value
        if (typeof lastLevel === 'function') {
            var ret = lastLevel.apply(scope, args);
            tulebox.dbg('....function value: ' + ret);
            return ret;
        } else {
            tulebox.dbg('....direct value: ' + lastLevel);
            return lastLevel;
        }
    },

效果非常好。享受较少的痛苦!

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

你可以使用逻辑'OR'操作符来代替Elvis操作符:

例如displayname = user.name || "匿名"。

但Javascript目前还不具备其他功能。如果你想要一种替代语法,我建议你看看CoffeeScript。它有一些类似于你要找的东西的简写。

例如存在操作符

zip = lottery.drawWinner?().address?.zipcode

功能快捷键

()->  // equivalent to function(){}

性感的函数调用

func 'arg1','arg2' // equivalent to func('arg1','arg2')

还有多行注释和类。显然,你必须将此编译为javascript或插入到页面中,作为<script type='text/coffeescript>',但它增加了很多功能:)。使用<script type='text/coffeescript'>实际上只用于开发而不是生产。

2019年9月更新

是的,JS现在支持这个。 可选的链接很快就会出现在v8中