JS 最近进入 Stage 4 的两个提案

今天刷推特的时候看到 TC39 的成员说 js 的两个语法糖提案进入 stage 4,最终板上钉钉,修成正果。

  • Optional Chaining
  • Nullish Coalescing
    其中 Optional Chaining 在这之前的 TS 3.7 中就被引入了

Optional Chaining

在此之前使用我们通常获取一个多层级对象一个比较内层的属性,为了避免为空的情况不得不这样写

1
let prop = a.b && a.b.c && a.b.c.d // 取到值或者赋值为 undefined

习惯了 Lodash 之后

1
let prop = _.get(a, "b.c.d", undefined) // 可以自定义默认值

使用 Optional Chaining 之后

1
let prop = a?.b?.c?.d

从提案中找到这么一句话

If the operand at the left-hand side of the ?. operator evaluates to undefined or null, the expression evaluates to undefined. Otherwise the targeted property access, method or function call is triggered normally.

?. 为界限分为左边(LHS)和右边(RHS),对 LHS 进行界定,如果为 null 或者 undefined 那么返回 undefined,如果既不为 null 也不为 undefined,继续向后进行 evalute。
babel 转译出来的结果相比提案案例更为直观

1
2
3
4
5
6
7
let obj = {};
obj?.a;

// 转译为
("use strict");
var obj = {};
obj === null || obj === void 0 ? void 0 : obj.a;

除了取可选属性之外还可以取可选方法a.?(),对 a 进行 null 和 undefined 检验通过之后,如果 a 不是函数,还是会抛出错误

1
Uncaught TypeError: a is not a function

还可以 a?.[++x]
总结来说三种语法

1
2
3
obj?.prop; // optional static property access
obj?.[expr]; // optional dynamic property access
func?.(...args); // optional function or method call

Nullish Coalescing

在此之前,比较常用来设置默认值得方式为 ||,

1
let val = a.b || 1;

但是当本身已经有值为 0 或者 false 的情况就不再适用,看看 Nullish Coalescing 的定义

If the expression at the left-hand side of the ?? operator evaluates to undefined or null, its right-hand side is returned.

与 Optional Chaining 相同的是,它也是使用 undefined or null进行界定的。于是我们之前的代码可以变为

1
let val = a.b ?? 1;

总结

结合这两个提案可以写出这样的代码

1
let age = info?.person?.age ?? 25;

对比使用 lodash 的话

1
_.get(info, "person.age", 25);

我还是用 lodash 吧

后续

刚好在 v2ex 看到有帖子说这个问题,之前我认为的等价写法,其实并不成立,有个老哥纠正了我的写法,列出了

1
2
3
4
5
6
7
8
({a:null})?.a??'default'
=>'default'

_.get({a:null},'a','default')
=>null

// 老哥给出等价写法
_.defaultTo(_.get({a:null},'a'),'default')

事后查文档发现也不是完全等价的写法
_.defaultTonullundefinedNaN 都会取默认值
会导致, 以下两种情况并不等价

1
2
({ a: NaN }?.a ?? "default"); // NaN
_.defaultTo(_.get({ a: NaN }, "a"), "default"); // default

再次总结来说的话

  • _.get 碰到 undefined 返回默认值
  • _.defaultTo 碰到 null || undefined || NaN 返回默认值
  • ?? 碰到 null || undefined 返回默认值
  • .? 碰到 null || undefined 返回 undefined

参考

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×