ES6部分新特性

103 阅读5分钟

解构赋值

let [head = 0, , ...tail] = [1, 2, 3, 4]
head // 1
tail // [3, 4]
const [a, b, c, d, e] = 'hello'

//交换值
let x = 1;
let y = 2;
[x, y] = [y, x];
// 提取 JSON 数据
let jsonData = {
    id: '42',
    status: "OK",
    // data: [867, 5309]
};
let { id, status, data: number } = jsonData;
// 遍历 Map Set结构
const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
    console.log(key + " is " + value);
}

字符串

// 模板字符串中嵌入变量
let name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`
// 能识别码点大于0xFFFF的字符 对应codePointAt
String.fromCodePoint(0x20BB7) 
// 将模板字符串中的所有变量替换
String.raw`Hi\n${2 + 3}!`// "Hi\\n5!"
string.normalize() //Unicode 正规化

let s = 'Hello world!';// 第二个参数表示开始搜索的位置。
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false

'a'.repeat(4) // "aaaa"

'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(4, 'ab') // 'xaba'

const str = '  abc  ';
str.trim() // "abc"
str.trimStart() // "abc  "
str.trimEnd() // "  abc"

Number Math

Number.isFinite | isSafeInteger | isInteger | isNaN

Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45

let minMargin = Number.EPSILON * Math.pow(2, 2); //表示可以接受的最小误差范围 0.3 - (0.2 + 0.1)

2 ** 3 // 8 指数运算符

// BigInt(大整数)

Math.trunc(4.1) // 4  去除小数部分
Math.sign(x) // -1 0 1  判断正数、负数、还是零
Math.cbrt('8') // 2 立方根
Math.hypot(3, 4); // 5  所有参数的平方和的平方根

函数

function log (x, y = 0, ...values) { //参数默认值 最后一个参数可以是rest参数
    console.log(x, y, values);
}
log(1, 3, 4, 5, 6)
log.name //log 

let sum = (num1, num2) => { return num1 + num2 }

Function.prototype.toString()

try {
    // ...
} catch {
    // ...
}

数组

扩展运算符(spread): 是三个点(...),rest 参数的逆运算
Array.from 转为数组相当于[].slice.call
Array.of方法用于将一组值,转换为数组。
find  findIndex
fill方法使用给定值,填充一个数组。
entries(),keys()和values(), includes(),flat(),flatMap()

对象

let lastWord = 'last word';
const a = {
    'first word': 'hello',
    [lastWord]: 'world'
};
a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"
// 遍历对象的属性
for...in, Object.keys, Object.getOwnPropertyNames,      Object.getOwnPropertySymbolsReflect.ownKeys.

//可选链式判断 js2020
message?.body?.user?.firstName || 'default'
支持 a ?? b
Object.is() //严格相等
Object.assign //对象合并
Object.getOwnPropertyDescriptors()// 自身属性(非继承属性)的描述对象。
Object.setPrototypeOf(),Object.getPrototypeOf()
Object.keys(),Object.values(),Object.entries(),Object.fromEntries()

Symbol 独一无二的值

const sym = Symbol('foo');
sym.description // "foo"

const mySymbol = Symbol();
const obj = {
    mySymbol: 'abc',
    [mySymbol]: 'symbol'
};
console.log(obj.mySymbol, obj[mySymbol], obj['mySymbol']) //abc symbol abc

Symbol.for("key") key相同 每次都会返回同一个值

Set Map

`let set = new Set();`
``
`set.add({});`
`set.size // 1`
``
`set.add({});` //delete has clear
`set.size // 2`
遍历: keys values entries foreach
eakSet 的成员只能是对象


`const m = new Map();`
`const o = {p: 'Hello World'};`
``
`m.set(o, 'content')` //对象也可以作为key
`m.get(o) // "content"`
``
`m.has(o) // true`
`m.delete(o) // true`
`m.has(o) // false`
遍历: keys values entries foreach
`WeakMap`只接受对象作为键名

Proxy

`var proxy = new Proxy(target, handler);`

`var proxy = new Proxy({}, {`
`get: function(target, propKey) {`
`return 35;`
`}`
`});`
``
`proxy.time // 35`
`proxy.name // 35`
`proxy.title // 35`

`var target = {};`
`var handler = {};`
`var proxy = new Proxy(target, handler);`
`proxy.a = 'b';` //访问`proxy`就等同于访问`target`
`target.a // "b"`

拦截的操作:
get set has delete ownKeys getOwnPropertyDescriptor defineProperty
preventExtensions getPrototypeOf isExtensible setPrototypeOf call

Proxy.revocable()返回对象,proxy属性是Proxy实例,revoke属性是一个函数,可以取消Proxy实例 this关键字会指向代理

Reflect

Reflect对象上可以拿到语言内部的方法。修改某些Object方法的返回结果,让其变得更合理

Reflect.has(Object, 'assign') Reflect对象的方法与Proxy对象的方法一一对应。

Promise

Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),无法中途取消,必须设置回调函数。

const promise = new Promise(function (resolve, reject) { //创建实例
            // ... some code
            if (/* 异步操作成功 */) {
                resolve(value);
            } else {
                reject(error);
            }
        });
        promise.then(function (value) { //then可以同时接受成功和失败的函数,第二个可选。返回的是一个新的新的新的Promise实例
    // success
}, function (error) {
    // failure
});

promise
    .then(result => {··· })
    .catch(error => {··· })
    .finally(() => {··· }); //最后都会执行的操作

setTimeout(function () {
    console.log('three'); //在下一轮“事件循环”开始时执行
}, 0);
Promise.resolve().then(function () {//Promise.resolve()返回一个Promise对象,状态为fulfilled
    console.log('two');// 在本轮“事件循环”结束时执行
});
console.log('one');//立即执行
// one
// two
// three

Promise.reject(reason)//返回一个Promise实例,该实例的状态为rejected。

const f = () => console.log('now');
(async () => f())(); //让同步函数同步执行,异步函数异步执行
console.log('next');
// now
// next

//同步和异步都能捕获
Promise.try(() => database.users.get({ id: userId }))
    .then(...)
    .catch(...)

//将多个 Promise 实例,包装成一个新的 Promise 实例。
Promise.all()// p1、p2、p3的状态都变成fulfilled
Promise.race()//只要有一个实例率先改变状态,p的状态就跟着改变。
Promise.allSettled()//只有等到所有实例都返回结果
Promise.any() //只要有一个变成fulfilled状态,就会变成fulfilled状态.

Iterator 遍历器 用于for...of

Array Map Set String TypedArray 函数的 arguments对象 NodeList对象

interface Iterable {
    [Symbol.iterator] (): Iterator,
}

let arr = ['a', 'b', 'c'];
let iter = arr[Symbol.iterator]();
iter.next() // { value: 'a', done: false }
iter.next() // { value: 'b', done: false }
iter.next() // { value: 'c', done: false }
iter.next() // { value: undefined, done: true }

const obj = {
    [Symbol.iterator]: function () {
        return {
            next: function () {
                return {
                    value: 1,
                    done: true
                };
            }
        };
     }
};

let myIterable = {
    [Symbol.iterator]: function* () {
        yield 1;
        yield 2;
        yield 3;
    }
}
[...myIterable] // [1, 2, 3]

Generator

function* helloWorldGenerator () {
    yield 'hello'; //yield表达式就是暂停标志,只能用在Generator函数里面
    yield 'world';
    return 'ending';
}
var hw = helloWorldGenerator();//调用函数不会执行,而是返回一个指针(遍历器)对象
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }

async

async函数返回一个 Promise 对象.
async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里。

async function getStockPriceByName(name) {
const symbol = await getStockSymbol(name);
const stockPrice = await getStockPrice(symbol);
return stockPrice;
}

getStockPriceByName('goog').then(function (result) {
console.log(result);
});

// awaiting.js` 顶层await
let output;
export default (async function main() {
const dynamic = await import(someMission);
const data = await fetch(url);
output = someProcess(dynamic.default, data);
})();
export { output };

// usage.js
import promise, { output } from "./awaiting.js";
promise.then(() => {todo});

class

//定义类
class Point extends ClassA {//继承A 
    topValue = "topString"
    static age = 0//静态属性
    constructor(x, y) {
        super(x)//通过super访问父类
        this.x = x;
        this.y = y;
    }
    toString () {
        return '(' + this.x + ', ' + this.y + ')';
    }
    static classMethod () { //静态方法
        return 'hello';
    }
}
var point = new Point(2, 3);
Point.classMethod()
point.topValue
point.toString() // (2, 3)
point.hasOwnProperty('x') // true
point.hasOwnProperty('y') // true
point.hasOwnProperty('toString') // false
point.__proto__.hasOwnProperty('toString') // true
Object.getPrototypeOf(Point) === ClassA//获取父类

class A {
}
class B extends A {
}
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true

module

引擎处理import语句是在编译时,既importexport命令只能在模块的顶层(非if)。
import()是动态加载,可以在需要的时候才开始加载。 返回一个Promise对象。

async function main () {
   const myModule = await import('./myModule.js');
   const { export1, export2 } = await import('./myModule.js');
   Promise.all([
       import('./module1.js'),
       import('./module2.js'),
       import('./module3.js'),
   ])
       .then(([module1, module2, module3]) => {

});
 }

 export

     // profile.js
 export var firstName = 'Michael';
 var lastName = 'Jackson';
 var year = 1958;
 export { lastName, year, firstName as fn};
 export function multiply (x, y) {
     return x * y;
 };
 export { multiply as m}; //这样导出函数需要大括号

使用export default时,对应的import语句不需要使用大括号。并且一个模块只能有一个默认输出。本质上,export default就是输出一个叫做default的变量或方法或者类,然后系统允许你为它取任意名字。

<script type="module" src="./foo.js" async></script> //按照模块引入顺序异步加载

应避免循环加载。