你可能不知道的 6 个 babel 语法

由于要整理基于 babel@7 的 babel preset babel-preset-umi,故而对 babel 插件进行了一遍完整的梳理。期间发现一些之前不熟悉或是新引入的语法,个人觉得挺有用,介绍如下。虽然基本都处于 stage 1 和 stage 0 阶段,但不影响使用。

有啥特性

pipeline

语法是 |>,类似其他语言,比如 Elm、LiveScript、OCaml 等,还有 UNIX 管道。

// Before
let result = exclaim(capitalize(doubleSay("hello")));

// After
let result = "hello"
  |> doubleSay
  |> capitalize
  |> exclaim;

还可以和 await 混用,以及传递额外参数,详见提案的例子

nullish coalescing

语法是 ??。和 || 操作符类似,但只判断左边的值是否为 nullundefined,不判断 ""0NaNfalse 等,详见提案

适用于配默认值。

var foo = object.foo ?? "default";

optional chaining

记得以前好像叫 guard operator,我更喜欢这个名字。用于防御性地检测对象、函数等,详见提案

比如:获取对象属性。

// before
var street = user && user.address && user.address.street;

// after
var street = user?.address?.street;

获取函数执行结果的子属性。

// before
var fooInput = myForm.querySelector('input[name=foo]');
var fooValue = fooInput ? fooInput.value : undefined;

// after
var fooValue = myForm.querySelector('input[name=foo]')?.value;

判断函数存在再执行。

a?.()

optional catch binding

catch 没有用到 error 对象时可以不用写。

// before
try {
} catch(e) {}

// after
try {
} catch {}

function bind

Function bind 的新语法,可以 bind,也可以直接 call。

obj::func
// is equivalent to
func.bind(obj)

::obj.func
// is equivalent to
obj.func.bind(obj)

obj::func(val)
// is equivalent to
func.call(obj, val)

::obj.func(val)
// is equivalent to
obj.func.call(obj, val)

有个挺好的用法是可以直接用于类数组,比如:

var urls = document.querySelectorAll('a')
  ::map(node => node.href)

do expression

简单的判断场景可以用三元操作符,复杂场景用 do expression 会比较合适。

let x = 100;
let y = 20;

let a = do {
  if(x > 10) {
    if(y > 20) {
      'big x, big y';
    } else {
      'big x, small y';
    }
  } else {
    if(y > 10) {
      'small x, big y';
    } else {
      'small x, small y';
    }
  }
};

另一个场景是可以用于 JSX:

var Component = props =>
  <div className='myComponent'>
    {do {
      if(color === 'blue') { <BlueComponent/>; }
      else if(color === 'red') { <RedComponent/>; }
      else if(color === 'green') { <GreenComponent/>; }
    }}
  </div>
;

怎么使用

可以直接用 babel@7-beta,也可以用 umi 或者 roadhog@2