JavaScript 中是否有空合并(Elvis)运算符或安全导航运算符?
我将通过示例进行解释:
Elvis Operator (?:)
“Elvis 运算符”是缩写 Java的三元运算符。一 方便的例子是 返回“合理的默认”值 如果表达式解析为 false 或 无效的。一个简单的例子可能看起来像 这个:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(22)
您可以使用逻辑“OR”运算符代替 Elvis 运算符:
例如
displayname = user.name || “匿名”
。但 Javascript 目前不具备其他功能。如果您想要替代语法,我建议您查看 CoffeeScript 。它有一些与您正在寻找的类似的简写。
例如,存在运算符
函数快捷方式
性感函数调用
还有多行注释和类。显然,您必须将其编译为 javascript 或作为
You can use the logical 'OR' operator in place of the Elvis operator:
For example
displayname = user.name || "Anonymous"
.But Javascript currently doesn't have the other functionality. I'd recommend looking at CoffeeScript if you want an alternative syntax. It has some shorthand that is similar to what you are looking for.
For example The Existential Operator
Function shortcuts
Sexy function calling
There is also multiline comments and classes. Obviously you have to compile this to javascript or insert into the page as
<script type='text/coffeescript>'
but it adds a lot of functionality :) . Using<script type='text/coffeescript'>
is really only intended for development and not production.2020 更新
JavaScript 现在具有 Elvis Operator 和 Safe Navigation Operator 的等效项。
安全属性访问
可选链接运算符 (
?.
) 目前处于第 4 阶段< /a> ECMAScript 提案。您可以立即将其与 Babel 一起使用。逻辑 AND 运算符 (
&&
) 是处理这种情况的“旧”、更详细的方法。提供默认值
无效合并运算符(
??
)当前是一个第 4 阶段 ECMAScript 提案。您可以立即将其与 Babel 一起使用。如果运算符的左侧为空值 (null
/undefined
),它允许您设置默认值。逻辑 OR 运算符 (
||
) 是一种替代解决方案,其行为略有不同。如果运算符的左侧为 falsy,它允许您设置默认值。请注意,下面的myVariable3
的结果与上面的myVariable3
不同。2020 Update
JavaScript now has equivalents for both the Elvis Operator and the Safe Navigation Operator.
Safe Property Access
The optional chaining operator (
?.
) is currently a stage 4 ECMAScript proposal. You can use it today with Babel.The logical AND operator (
&&
) is the "old", more-verbose way to handle this scenario.Providing a Default
The nullish coalescing operator (
??
) is currently a stage 4 ECMAScript proposal. You can use it today with Babel. It allows you to set a default value if the left-hand side of the operator is a nullary value (null
/undefined
).The logical OR operator (
||
) is an alternative solution with slightly different behavior. It allows you to set a default value if the left-hand side of the operator is falsy. Note that the result ofmyVariable3
below differs frommyVariable3
above.我认为以下内容相当于安全导航运算符,尽管有点长:
streetName
将是user.address.street
或undefined< 的值/代码>。
如果您希望它默认为其他内容,您可以与上面的快捷方式结合使用或给出:
I think the following is equivalent to the safe navigation operator, although a bit longer:
streetName
will then be either the value ofuser.address.street
orundefined
.If you want it to default to something else you can combine with the above shortcut or to give:
Javascript 的逻辑或运算符是短路 并可以替换您的“Elvis”运算符:
但是,据我所知,没有与您的
?.
运算符等效的东西。Javascript's logical OR operator is short-circuiting and can replace your "Elvis" operator:
However, to my knowledge there's no equivalent to your
?.
operator.我偶尔发现以下习惯用法很有用:
可以重写为:
这利用了这样一个事实,即在对象上获取未知属性会返回未定义,而不是像在
null
或 < 上那样抛出异常code>undefined,因此我们在导航之前将 null 和 undefined 替换为空对象。I've occasionally found the following idiom useful:
can be rewritten as:
This takes advantage of the fact that getting unknown attributes on an object returns undefined, rather than throwing an exception as it does on
null
orundefined
, so we replace null and undefined with an empty object before navigating.我认为 lodash
_.get()
可以在这里提供帮助,如_.get(user, 'name')
,以及更复杂的任务,例如_.get(o, 'a[0].bc', 'default-value')
i think lodash
_.get()
can help here, as in_.get(user, 'name')
, and more complex tasks like_.get(o, 'a[0].b.c', 'default-value')
目前有一个草案规范:
https://github.com/tc39/proposal-optical-chaining
https://tc39.github.io/proposal-optional-chaining/
不过现在,我喜欢使用 lodash
get(object, path [,defaultValue])
或 dlvdelve(obj, keypath)
更新(截至 2019 年 12 月 23 日):
There is currently a draft spec:
https://github.com/tc39/proposal-optional-chaining
https://tc39.github.io/proposal-optional-chaining/
For now, though, I like to use lodash
get(object, path [,defaultValue])
or dlvdelve(obj, keypath)
Update (as of Dec 23, 2019):
对于前者,您可以使用
||
。 Javascript“逻辑或”运算符不是简单地返回预设的 true 和 false 值,而是遵循以下规则:如果为 true,则返回其左参数,否则评估并返回其右参数。当您只对真值感兴趣时,其结果是相同的,但这也意味着foo ||酒吧|| baz
返回 foo、bar 或 baz 中包含真值的最左边的一个。不过,您找不到可以区分 false 和 null 的值,而且 0 和空字符串都是假值,因此请避免使用
value || default
构造,其中value
可以合法地为 0 或""
。For the former, you can use
||
. The Javascript "logical or" operator, rather than simply returning canned true and false values, follows the rule of returning its left argument if it is true, and otherwise evaluating and returning its right argument. When you're only interested in the truth value it works out the same, but it also means thatfoo || bar || baz
returns the leftmost one of foo, bar, or baz that contains a true value.You won't find one that can distinguish false from null, though, and 0 and empty string are false values, so avoid using the
value || default
construct wherevalue
can legitimately be 0 or""
.是的,有!
Yes, there is! ????
Optional chaining is in stage 4 and this enables you to use the
user?.address?.street
formula.If you can't wait the release, install
@babel/plugin-proposal-optional-chaining
and you can use it.Here are my settings which works for me, or just read Nimmo's article.
这是一个简单的 elvis 运算符等效项:
Here's a simple elvis operator equivalent:
您可以通过以下方式实现大致相同的效果:
You can achieve roughly the same effect by saying:
2019年9月更新
是的,JS现在支持这个。
可选链接即将在 v8 中推出了解更多
UPDATE SEP 2019
Yes, JS now supports this.
Optional chaining is coming soon to v8 read more
这通常称为空合并运算符。 JavaScript 没有这样一个。
This is more commonly known as a null-coalescing operator. Javascript does not have one.
我有一个解决方案,可以根据您自己的需求定制它,摘录自我的一个库:
就像魅力一样。享受更少的痛苦!
I have a solution for that, tailor it to your own needs, an excerpt from one of my libs:
works like a charm. Enjoy the less pain!
您可以推出自己的:
并像这样使用它:
* 如果 a、b、c 或 d 中的任何一个未定义,则结果未定义。
You could roll your own:
And use it like this:
* result is undefined if any one of a, b, c or d is undefined.
我读了这篇文章(https://www.beyondjava.net /elvis-operator-aka-safe-navigation-javascript-typescript)并使用代理修改了解决方案。
您可以这样称呼它:
对于沿其路径遇到 null 或未定义的表达式,结果将是未定义的。您可以疯狂并修改对象原型!
I read this article (https://www.beyondjava.net/elvis-operator-aka-safe-navigation-javascript-typescript) and modified the solution using Proxies.
You call it like this:
The result will be undefined for an expression that encounters null or undefined along its path. You could go wild and modify the Object prototype!
很晚才介入,目前在第 2 阶段有一个关于可选链的提案[1],并提供了 babel 插件[2]。目前我所知道的任何浏览器中都没有它。
Jumping in very late, there's a proposal[1] for optional chaining currently at stage 2, with a babel plugin[2] available. It's not currently in any browser I am aware of.
这一直是我的一个问题。我必须想出一个解决方案,一旦我们有了 Elvis 操作员或其他东西,就可以轻松迁移。
这就是我用的;适用于数组和对象,
将其放入 tools.js 文件或其他
用法示例中:
我知道这会使代码有点难以阅读,但它是一个简单的单行解决方案,并且效果很好。我希望它对某人有帮助:)
This was a problem for me for a long time. I had to come up with a solution that can be easily migrated once we get Elvis operator or something.
This is what I use; works for both arrays and objects
put this in tools.js file or something
usage example:
well I know it makes the code a bit unreadable but it's a simple one liner solution and works great. I hope it helps someone :)
??
在 js 中可以工作,相当于 kotlin 中的?:
??
would work in js which is equivalent to?:
in kotlin对于使用一些 mixin 的安全导航操作员来说,这是一个有趣的解决方案。
http://jsfiddle.net/avernet/npcmv /
This was an interesting solution for the safe navigation operator using some mixin..
http://jsfiddle.net/avernet/npcmv/
我创建了一个包,使它更容易使用。
NPM jsdig
Github jsdig
你可以处理简单的事情,比如 and object:
或更复杂一点:
I created a package that makes this a lot easier to use.
NPM jsdig
Github jsdig
You can handle simple things like and object:
or a little more complicated:
我个人使用
,例如安全获取:
Personally i use
and for example safe get: