javascript 中是否有空合并(Elvis)运算符或安全导航运算符?

IT技术 javascript jquery groovy safe-navigation-operator
2021-01-21 16:04:20

我将举例说明:

猫王运算符 (?:)

“Elvis 运算符”是 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
6个回答

您可以使用逻辑“OR”运算符代替 Elvis 运算符:

例如displayname = user.name || "Anonymous"

但是 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'>实际上仅用于开发而不是生产。

CoffeeScript 主页使用<script type="text/coffeescript">.
2021-03-13 16:04:20
我去吃香蕉吗?user2451227 的反对(目前有 4 票)当然是无效的,因为如果表达式/左操作数被定义并且为假,三元的中间操作数(即带有 Elvis 运算符的右操作数)同样不会被选中。在这两种情况下,你都必须去x === undefined
2021-03-26 16:04:20
在大多数情况下,逻辑或不是完全需要的东西,因为您可能希望它仅在左侧未定义时才选择正确的操作数,而不是在已定义且为假的情况下。
2021-03-27 16:04:20
请考虑更新它以提及可选的链接运算符?.,浏览器支持还没有达到我将它用于通用代码的程度,但它正朝着这个方向发展。此外,现在还有空合并运算符 (??),具有类似的状态。
2021-04-07 16:04:20
虽然这回答了这个问题,但它几乎完全是关于 coffeescript 而不是 javascript,而且一半以上是关于描述与 OP 无关的 coffeescript 好处。我建议将其归结为与问题相关的内容,就像 coffeescript 的其他好处一样美妙。
2021-04-08 16:04:20

我认为以下相当于安全导航操作符,虽然有点长:

var streetName = user && user.address && user.address.street;

streetName然后将是任一值user.address.streetundefined

如果您希望它默认为其他内容,您可以结合上述快捷方式或给出:

var streetName = (user && user.address && user.address.street) || "Unknown Street";
这有效,只是你不知道你是否从中得到 null 或 undefined
2021-04-02 16:04:20
加上一个空传播和空合并的很好例子!
2021-04-05 16:04:20

2020 更新

JavaScript 现在具有 Elvis Operator 和 Safe Navigation Operator 的等效项。


安全的财产访问

可选的链接运营商?.)是目前阶段4 ECMAScript的建议今天可以将它与 Babel 一起使用

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

逻辑AND运算符&&)是“老”,更详细的处理这种情况的方式。

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

提供默认值

所述nullish合并运算符??)是目前阶段4的ECMAScript提案今天可以将它与 Babel 一起使用如果运算符的左侧是空值 ( 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';

逻辑OR运算符||)是一种替代解决方案略有不同的行为如果运算符的左侧为falsy ,它允许您设置默认值请注意,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';
您可以使用 [] 语法添加执行此操作的方法 - 来自developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...,所有这些都是可能的: obj.val?.prop obj.val ?.[expr] obj.arr?.[index] obj.func?.(args)
2021-03-11 16:04:20
a && a.b && a.c应该是a && a.b && a.b.c我自己无法编辑它,因为这不是一个足够大的变化让 SO 接受,我不想做“改变无关紧要的事情以使其成为 6 个字符”的事情。
2021-03-18 16:04:20
这个答案需要更多的赞成。Nullish Coalescing Operator 现在处于第 4 阶段。
2021-03-26 16:04:20

Javascript 的逻辑 OR 运算符短路的,可以替换您的“Elvis”运算符:

var displayName = user.name || "Anonymous";

但是,据我所知,没有与您的?.运营商等效的东西

@Cameron,确实如此,但这在问题中提到了,似乎是提问者的意图。""或者0可能是出乎意料的,不过:)
2021-03-24 16:04:20
+1,我忘了||可以这样使用。请注意,这不仅会在表达式为 时合并null,还会在其未定义false0、 或空字符串时合并
2021-04-01 16:04:20

我偶尔发现以下习语很有用:

a?.b?.c

可以改写为:

((a||{}).b||{}).c

这利用了在对象上获取未知属性返回 undefined 的事实,而不是像nullor那样抛出异常undefined,因此我们在导航之前将 null 和 undefined 替换为空对象。

实际上,这是 javascript 中唯一真正安全的运算符。上面提到的逻辑“或”运算符是别的东西。
2021-03-15 16:04:20
它还允许导航匿名值而无需先将其分配给变量。
2021-03-24 16:04:20
爱它!如果您想在可能不返回任何结果的 array.find() 操作之后获取对象的属性,则非常有用
2021-03-26 16:04:20
@Filippos 你能举一个逻辑 OR 与 && 方法中不同行为的例子吗?我想不出有什么区别
2021-03-30 16:04:20
好吧,它很难阅读,但它比那种冗长的&&方法要好+1。
2021-04-10 16:04:20