ES6特殊运算符

3 篇文章 0 订阅

  本文用以记录工作或学习中碰到的ES6中的一些特殊运算符,持续更新…

提案中,尚未进入标准的运算符可能在当前的浏览器版本中还并未受到支持

  • ?.

链式运算符

  • 链式调用的时候判断左侧的对象是否为null或者undefined。如果是,就不再往下运算,直接返回undefined。
 obj?.prop // 对象属性
 obj?.[expr] // 同上 [expr]是对象属性表达式
 obj?.func?.(...args) // 函数或对象方法的调用
  • ||

判断运算符

  • 左侧为真值则取左侧,否则取右侧。
  • ??

判空运算符

  • 只有左侧为null或undefined时,才取右侧。
  • ::

函数绑定运算符 – 提案中,尚未进入标准

  • 函数绑定运算符是并排的两个冒号(::),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即this对象),绑定到右边的函数上面。
  • 如果双冒号左边为空,右边是一个对象的方法,则等于将该方法绑定在该对象上面。
obj::foo	// ==> foo.bind(obj)
obj::foo(...args)	// ==> foo.apply(obj, args)
let fn = ::obj.foo	// ==> let fn = obj::obj.foo

import { map, takeWhile, forEach } from "iterlib";

getPlayers()
::map(x => x.character())
::takeWhile(x => x.strength > 100)
::forEach(x => console.log(x));

扩展运算符

  • @fn

装饰器

@testable
class Person {
  @readonly
  @nonenumerable
  name() { return `${this.first} ${this.last}` }
}
  • #prop / #fn

class内部私有属性或私有方法,只能在class内部访问。

  • get fn / set fn

class get 或 set 方法

  • static prop / static fn

class静态属性或静态方法,只能用class类名访问,不能用实例访问,静态方法中的this指向当前class。

  • function* / yield

generate函数

  • async function / await

异步函数

  • new.target
  • Class 内部调用new.target,返回当前 Class。用在构造函数之中,返回new命令作用于的那个构造函数。如果构造函数不是通过new命令或Reflect.construct()调用的,new.target会返回undefined。
  • 在函数外部,使用new.target会报错。
function Person(name) {
  if (new.target !== undefined) {
    this.name = name;
  } else {
    throw new Error('必须使用 new 命令生成实例');
  }
}

// 另一种写法
function Person(name) {
  if (new.target === Person) {
    this.name = name;
  } else {
    throw new Error('必须使用 new 命令生成实例');
  }
}

子类继承父类时,new.target会返回子类,利用这个特点,可以写出不能独立使用、必须继承后才能使用的类。

class Shape {
  constructor() {
    if (new.target === Shape) {
      throw new Error('本类不能实例化');
    }
  }
}

class Rectangle extends Shape {
  constructor(length, width) {
    super();
    // ...
  }
}

var x = new Shape();  // 报错
var y = new Rectangle(3, 4);  // 正确
  • ,

逗号运算符

  • 逗号运算符的特性及作用:逗号运算符的作用是将若干表达式连接起来。它的优先级是所有运算符中最低的,结合方向是自左至右。
  • 逗号表达式:
    • 一般形式:表达式1,表达式2,表达式3,…表达式n
      求解过程:先计算表达式1的值,再计算表达式2的值,…一直计算到表达式n的值。最后整个表达式的值是表达式n的值。
  • do

do表达式 – 提案中,尚未进入标准

  • 在块级作用域之前加上do,使它变为do表达式,然后就会返回内部最后执行的表达式的值。
// x = t * t + 1
let x = do {
  let t = f();
  t * t + 1;
};
  • throw

throw表达式 – 提案中,尚未进入标准

  • throw出现在行首,一律解释为throw语句,反之则为throw表达式。
// 参数的默认值
function save(filename = throw new TypeError("Argument required")) {
}

// 箭头函数的返回值
lint(ast, {
  with: () => throw new Error("avoid using 'with' statements.")
});
  • 函数部分执行

函数部分执行 – 提案中,尚未进入标准

  • ?是单个参数的占位符,…是多个参数的占位符。?和…只能出现在函数的调用之中,并且会返回一个新函数。
const add = (x, y) => x + y;
const addOne = add(1, ?);

const g = f(?, 1, ...);
// 等同于
const g = (x, ...y) => f(x, 1, ...y);

let obj = {
  f(x, y) { return x + y; },
};

const g = obj.f(?, 3);
g(1) // 4
  • > |

管道运算符 – 提案中,尚未进入标准

  • 它的左边是一个表达式,右边是一个函数。管道运算符把左边表达式的值,传入右边的函数进行求值。管道运算符最大的好处,就是可以把嵌套的函数,写成从左到右的链式表达式。
// 传统的写法
exclaim(capitalize(doubleSay('hello')))
// "Hello, hello!"

// 管道的写法
'hello'
  |> doubleSay
  |> capitalize
  |> exclaim
// "Hello, hello!"

x |> await f
// 等同于
await f(x)

const userAge = userId |> await fetchUserById |> getAgeFromUser;
// 等同于
const userAge = getAgeFromUser(await fetchUserById(userId));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值