深入理解JS的类型、值和类型转换

image


一、ECMAScript 2016

1、Array.prototype.includes

Array.prototype.includes() - JavaScript | MDN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const arr = [1, 2, 3, NaN];

if (arr.indexOf(3) >= 0) {
console.log(true)
}
// true

if (arr.includes(3)) {
console.log(true)
}
// true

arr.indexOf(NaN)
// -1 无法识别NaN
arr.includes(NaN);
// true 可以识别NaN

2、指数(幂)运算符 **

1
2
3
4
5
Math.pow(2, 3)
// 8

2 ** 3
// 8

二、ECMAScript 2017

1、Object.values()

Object.values() - JavaScript | MDN

1
2
const obj = { foo: "bar", baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

2、Object.entries()

Object.entries() - JavaScript | MDN

1
2
3
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]
Object.entries({name:'cosyer',age:25}).reduce((acc, [key, val]) => acc.concat({ [key]: val }), []) // [{name:'cosyer'},{age:25}]

3、字符串填充 String padding

String.prototype.padStart() - JavaScript | MDN String.prototype.padEnd() - JavaScript | MDN

1
2
3
4
5
6
7
8
9
10
'abc'.padStart(10);         // "       abc"
'abc'.padStart(10, "foo"); // "foofoofabc"
'abc'.padStart(6,"123465"); // "123abc"
'abc'.padStart(8, "0"); // "00000abc"
'abc'.padStart(1); // "abc"

'abc'.padEnd(10); // "abc "
'abc'.padEnd(10, "foo"); // "abcfoofoof"
'abc'.padEnd(6, "123456"); // "abc123"
'abc'.padEnd(1); // "abc"

注意,Emojis和双字节字符会占据两位

1
'heart'.padStart(10, "❤️"); // '❤️❤️❤heart'

4、Object.getOwnPropertyDescriptors

Object.getOwnPropertyDescriptor() - JavaScript | MDN

1
Object.getOwnPropertyDescriptor(obj, prop)

Object.getOwnPropertyDescriptor()方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

5、函数参数结尾逗号

1
2
function fn(a, b,) {}
// 注意,参数b后面多了个逗号,不会报语法错误

6、Async/Await

async function - JavaScript | MDN

三、ECMAScript 2018

1、共享内存与原子操作

即使有event loop的“伪多线程”和Service Worker的强力增援,但依然掩盖不了JS是单线程的事实。

共享内存与原子操作,给JS带来了多线程的功能,允许开发人员自行管理内存来开发高性能高并发的程序。

直到目前为止,我们只能通过postMessage在JS主线程和web worker之间通信,传输数据。

2、非转义序列的模板字符串

非转义序列的模板字符串 | esnext | es6 es7 es2017 es2018 es2019

3、对象展开运算符

1
2
3
4
5
6
7
8
9
10
11
let { firstName, age, ...rest } = {
firstName: 'a',
age: 18,
a: 1,
b: 2
};

firstName; // 'a',
age; // 18
rest;
// 重点看这里 { a: 1, b: 2 }

4、Promise.prototype.finally()

5、异步迭代器

提供了for-await-of,异步迭代,等待每个promise被resolve再执行下一个

1
2
3
4
5
const promises = [
new Promise(resolve =resolve(1)),
new Promise(resolve =resolve(2)),
new Promise(resolve =resolve(3))
];
1
2
3
4
5
6
7
8
9
10
// old
async function test1() {
for (const obj of promises) {
console.log(obj);
}
}
test1(); //
// Promise {<resolved>: 1}
// Promise {<resolved>: 2}
// Promise {<resolved>: 3}
1
2
3
4
5
6
7
8
// new
async function test2() {
for await (const obj of promises) {
console.log(obj);
}
}
test2();
// 1, 2, 3

6、正则表达式相关

  • dotAll 模式,使 . 可以匹配任意字符
  • 命名捕获组,可以理解为增加一个引用
1
2
3
4
5
6
const regex = /(\d{4})-(\d{2})-(\d{2})/;
const matchers = regex.exec('2015-01-02');
matchers[0]; // 2015-01-02
matchers[1]; // 2015
matchers[2]; // 01
matchers[3]; // 02
  • 反向断言 Lookbehind Assertions
  • Unicode转义 Unicode Property Escapes
本文结束感谢您的阅读

本文标题:深入理解JS的类型、值和类型转换

文章作者:陈宇(cosyer)

发布时间:2019年03月07日 - 00:03

最后更新:2020年10月14日 - 15:10

原始链接:http://mydearest.cn/2019/ECMAScript%202016%E3%80%812017%E3%80%812018%20%E6%96%B0%E7%89%B9%E6%80%A7%20.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

坚持原创技术分享,您的支持将鼓励我继续创作!