Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ECMAScript2021: 逻辑赋值运算符 #241

Open
islishude opened this issue Oct 8, 2020 · 0 comments
Open

ECMAScript2021: 逻辑赋值运算符 #241

islishude opened this issue Oct 8, 2020 · 0 comments
Labels

Comments

@islishude
Copy link
Owner

islishude commented Oct 8, 2020

目前 js 支持 3 种逻辑赋值运算符:

// Logical OR assignment
a ||= b; // 等价于 a || (a = b);

// Logical AND assignment 
a &&= b; // 等价于 a && (a = b);

// Logical nullish assignment
a ??= b; // 等价于 a ?? (a = b);

与数学意义的逻辑运算符不同的是,逻辑赋值符在不符合逻辑条件下不会触发 setter

const obj = {
  _x: 0,
  get x() {
    return this._x;
  },
  
  set x(value) {
    console.log('setter called');
    this._x = value;
  }
};

// 始终会打印 "setter called"
obj.x += 1;
assert.equal(obj.x, 1);

// 当不满足逻辑条件调用时不会触发 setter
// 所以这里不会打印
obj.x ||= 2;
assert.equal(obj.x, 1);

// 但当满足逻辑条件时就会触发 setter
// 所以这里会打印 "setter called"
obj.x &&= 3;
assert.equal(obj.x, 3);

实际使用中,逻辑赋值运算符能提供更好的性能,如下面代码:

// Display a default message if it doesn’t override anything.
// Only assigns to innerHTML if it’s empty. Doesn’t cause inner
// elements of msgElement to lose focus.
function setDefaultMessage() {
  msgElement.innerHTML ||= '<p>No messages<p>';
}

// Display a default message if it doesn’t override anything.
// Buggy! May cause inner elements of msgElement to
// lose focus every time it’s called.
function setDefaultMessageBuggy() {
  msgElement.innerHTML = msgElement.innerHTML || '<p>No messages<p>';
}

上述代码中赋值给 .innerHTML 属性会删除 msgElement 元素内部子元素,然后插入从新分配的字符串后再进行解析,而逻辑赋值运算符正好能解决这种不必要的副作用。

目前 chrome 86 已经支持,但最新版 node v14.13.1 还未支持 nodejs v15.0.0开始支持。

@islishude islishude added the Web label Oct 8, 2020
@islishude islishude changed the title ECMA2021: 逻辑赋值运算符 ECMAScript2021: 逻辑赋值运算符 Nov 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant