Nodejs中使我震惊的 js 语法 ?.(没错,看起来很像三目但却不是:而是.)

Nodejs中使我震惊的 js 语法 ?.(没错,看起来很像三目但却不是:而是.)
举例
let a = {a:“1”,b:“2”}
console.log(a?.a)

契机:另一个组的同事在一个 angular 项目里发现了这个语法的使用,
通过关键字查了一下也就这么个 csdn 的结果
《 angular 中的 ? 和 !》 https://blog.csdn.net/weixin_30908941/article/details/95594290

里面除了交代?可以判断前面的变量是否为 null 或 undefined 再执行后面,还有个!判断后面键所对应的值是否为 null 或 undefined,不过没有成功在 js 里再现这个!。

就我个人在网上的搜索结果来看,感觉这个?.的写法比!!还要冷门,用途的效果上个人感觉类似 react 写 jsx 进行页面渲染时的&&或者?:

当然,我自己的这些肤浅猜测总结也没什么营养,还请各位有了解或者感兴趣的分析一波这个?.吗


101 回复

这语法在其他语言也不是很罕见的,比如 swift


kotlin 也有这种语法

可空类型,不算冷门

?。这语法太超前了,虽然各种 objectPath 类组件早就在用,可以一次访问很深层的节点,不用一层层判空

现在主流语言是天下语法一大抄,越来越趋同了。

感谢楼上的各位解疑,原来是其他语言已经存在的语法,get 了

最近在 kotlin 里写这个都写吐了. 之前 swift 的项目里也用到很多.

我写了一年多 js 也 不知道这个…我是不是太菜了

你还可以使用 ?? 来代替 ||,避免需要判断值是不是 0 这种情况
关键词:Nullish Coalescing

dart 也有。这是 ES2020 的新语法,挺好用的,不用在写什么 a && a.b 之类的了。

刚开始看到时,我也是很震惊的。
但是实话实说,这个语法的确很实用,不对吗?

写 swift 的时候经常这么写。现在的语言很多都开始互通有无了,都会相互借鉴对方的一些东西

kotlin 里面有,thymeleaf 模板写对象判断非空也是用这里的语法

新版本 ts 提前支持的 Optional Chaining 等 ES2020 的新语法拉

es 里还在提案吧

关注 ts 的话应该不会觉得这个写法冷门😂

建议关注 ECMA262 repo

写 js 的不都是天天跟着最新语法标准走吗,这种最近大半年都在谈的语法就算没用过,总不至于没听过吧……

还是说现在前端已经足够成熟,大家都不学新内容了?

主要是新,冷门应该不至于,毕竟很实用

我觉得还是 aardio 中的直接下标更简洁好用,
if( a[[b]] ){ } 不管 a 是什么都不会抛异常,不是对象返回 null,可以节省好多代码。

比 swift,kotlin,js 什么的出现早多了,国产小语言也是有亮点的。

Safe calls are useful in chains. For example, if Bob, an Employee, may be assigned to a Department (or not), that in turn may have another Employee as a department head, then to obtain the name of Bob’s department head (if any), we write the following:

bob?.department?.head?.name
Such a chain returns null if any of the properties in it is null.

C#也有这个语法了

浏览器端不敢瞎 babel,比不了后端可以自己决定版本

有意思,学到了

已经进 stage4 了

ts 有插件会自动不上。。虽然我自己写还是 if 判断一下

c# 里面也有!

要多想

为了减少对父元素的空置判定,尤其是很多个级别。
a.b.c.d 这种,if(a) { if(a.b) { if(a.b.c) { a.b.c.d }}}},不想一级一级判断的时候就很方便了。

握草,刚刚试了一下,除了?.运算符之外,??运算符也被支持了!
var a = {sa: 3, sb: 4};
var b = null;
console.log(a?.sa ?? 5); // 3
console.log(b?.sa ?? 5); // 5

c# 也是用这个判断是否为空的

dart 也有

https://caniuse.com/#feat=mdn-javascript_operators_optional_chaining
太超前了,FF 和 CR 各只过了两个版本,过 babel 可行( angular 可以用大概就是 babel 的原因?)
早前 coffee 就看到了

?? 和 || 有啥区别啊

看来 C#还是有人用的。。。

angular 也只是能在模板中使用吧,要想在 ts 中使用还是得配置 babel 插件。

#30 这种我一直是用 lodash 的 get 一把梭

C#里我经常这么用,比判断==null 方便多了

啊,老哥一般是在哪里了解这些新内容的?


https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
摘录:
由于 || 是一个布尔逻辑运算符,左侧的操作数会被强制转换成布尔值用于求值。任何假值( 0, ‘’,NaN,null,undefined )都不会被返回。这导致如果你使用 0,’'或 NaN 作为有效值,就会出现不可预料的后果.
空值合并操作符??可以避免这种陷阱,其只在第一个操作数为 null 或 undefined 时(而不是其它假值)返回第二个操作数。

感谢#10 提供了拓展和线索

蟹蟹,MDN 常看常新啊

#11 对对

VS Code + TypeScript 会给我强推这种写法.

推一下前两天我们关于 nullish coalescing operator post: https://zsqk.github.io/news/2020-04-08-nullish-coalescing-operator.html

上次遇见了一次,搜了半天才知道是干什么的
还有!!

Optional Chaining
去年写的 ts 项目就在用了,在 react 项目中很舒服。

这是新语法啦,很实用的

看起来楼主没写过 coffeescript 啊,coffeescript 里面有这个问号运算符

c# 空运算

很棒的语法啊,c#首创的吧?

C#的语法糖

ruby 里可以直接 inline 外挂一个 exception 更方便。不管是 . 挂了还是别的什么挂了都能正常执行。

TypeScript 啊 。。。

相当于 Ruby 的单身狗运算符 a&.a

ruby-china.org/topics/30415

学 swift 的时候感觉这个有点绕,项目做完后不再写 swift 就忘了

ts 3.7 的语法吧

c# 6.0 ( 2015 年) 才有 Null 条件运算符,应当是比较晚了。

国产小语言 aardio 在十多年前就有了类似的语法,不仅仅是对象,任何对象都可以 if( a[[b]] ){ } ,真正的有鸭子的声音就可以当鸭子用,说到偷懒这个事,我们还是行的。

只能 null 对象,还是会有麻烦,如果是其他类型呢,还是要写判断,偷懒还是不够彻底这不行的。

php 早就有了

ES7+后的新语法 我知道有 但是不知道在哪个版本里

js 生态就要经常上来看看 tc39,ts 可以经常看看 roadmap

除了 ts , 暂时还不敢用。

PHP 就更晚了,PHP 7 才有 $d = $a->$b->$c ?? ‘DEFAULT’ 的写法,不是很简洁。

C#基本操作,ts 也有

Dart 里面经常用…还有 ?? 语法 😝

多关注 tc39

最近写 flutter,看别人的库经常这种语法

很有用 学习了

新语法哈哈

没记错的话是 es7 新语法吧,一般情况下不敢用,怕不支持😄

最近新开项目 下意识在使用 ?. … 这些语法
说真的 能少掉好多头发 少些好多代码

已经纳入标准,可以用 babel 进行兼容处理

<br>{<br> name: 'aaa',<br> ...(true &amp;&amp; {age: 10})<br>}<br>

比如像这种神奇的写法 真的能让自己少掉好几根头发

我印象中 PHP7 也有这种语法。但是我还是喜欢用传统的:?判断为主。 太新的语法我怕其他人调式出错。就蒙蔽了。

thymeleaf 里面经常会用到

可选链啊, 如果用过 Swift 肯定会觉得很熟悉
实际上 a?.b 就等于 a && a.b 的意思, 防止对不存在的变量读取属性而产生异常
在处理某些前后端交互的不稳定数据时相当舒服

现在很常见了,以前在模板引擎语法里很常见

因为 js 里面访问 undefined 或者 null 的成员会报错,所以如果调用很深,譬如这种,a.b.c.d.e.f,为了防止报错,要这么写

a?a.b?a.b.c?a.b.c.d?a.b.c.d.e?a.b.c.d.e.f:null:null:null:null:null

巨难看
所以出了个语法糖

a?.b?.c?.d?.e?.f

C# 还有 ?? ??=

a?.b 等同于 if(a == null) return null
还有 a??0 等同于 if(a == null) return 0
a??=0 等同于 if(a == null){ a = 0; return a;}

#83 Logical Assignment Operators,ES 这边已经 Stage 3,如无意外明年就纳入规范了

还好吧,flutter 早就有这个语法了,kotlin 也有类似的语法,简单来说就是简化判空操作的,js 听说要新加这个语法,当时跑了是还不能用的

Optional Chaining 不仅有 foo.bar?.qux ,还有 foo.bar?.( ) 呢
:-)

ES2020 里面的

Python PEP505,不过这语法确实有点 magic,不符合 Python 的一贯风格,难怪还没被采纳

很多语言都有,这个叫 Safe navigation operator, Wikipedia 有 18 种语言的例子
https://en.wikipedia.org/wiki/Safe_navigation_operator

您这个就算没有 ?. 语法,也可以不用 ?: 啊……
用 ?: 是丑,但是直接
a && a.b && a.b.c && a.b.c.d && a.b.c.d.e && a.b.c.d.e.f || null
也稍微好看一些啊……
(虽然还是 ?. 更香

我还写过 webpack 的实现,不过只是用了正则替换来判断,不是很完美。
TC39 有关于可选链的解释。

很好用的语法糖,各大语言应该引入

C#里面就有。。。 后来换到用 Java 的公司就没这个待遇了

optional 更适合用来解包判空之类的。
如果用来判断布尔的话是有歧义的,比如:if (a?.b == 0)或者 if(a?.b == false),到底是 a 为空还是 a 不为空 b 为 false 或者 b 为空

原来 JS 也有了

可选链,香的很。震惊啥 TS 强推

我写 C#,这玩意儿都写了好几年了,基本就是日常。。。。。
学新语言的时候觉得没有 x?.x 还有 x??y 这种写法很别扭。。。。

angular 里面经常写

在Node.js中,你提到的.?(可选链,Optional Chaining)操作符确实是一个令人惊讶且强大的JavaScript语法特性。这个操作符允许你安全地访问深层嵌套对象属性,而无需手动检查每一级是否存在,从而避免了常见的TypeError错误。

以下是一个简单的示例,展示了可选链操作符的使用:

const user = {
  name: 'John',
  address: {
    city: 'New York'
  }
};

// 使用可选链操作符访问嵌套属性
const city = user.address?.state?.name ?? 'Unknown State';
console.log(city); // 输出: Unknown State

// 如果不使用可选链,代码可能会抛出错误
try {
  const cityWithoutOptionalChain = user.address.state.name;
  console.log(cityWithoutOptionalChain);
} catch (error) {
  console.error(error.message); // 输出: Cannot read properties of undefined (reading 'name')
}

在上面的例子中,user.address?.state?.name使用了可选链操作符,即使state属性不存在,也不会抛出错误,而是返回undefined。接着,我们使用逻辑空值合并操作符??来提供一个默认值'Unknown State'

可选链操作符极大地简化了处理可能为nullundefined的对象属性的代码,使代码更加简洁和健壮。它是ES2020(ECMAScript 2020)规范的一部分,Node.js从v14开始支持这一特性。

回到顶部