阮大ES6入门学习总结
一、let 和 const 命令
- 块级作用域。
- for循环,变量设置部分与循环体部分可看成父子作用域。
- 无变量提升,‘变量提升’形成
暂时性死区,同作用域不能重复定义。 - 自执行函数形成独立作用域写法,可以改成
{let}写法。 - 函数表达式替换声明函数写法。
- const不变的是数据内存地址。
二、解构赋值
- 数组按序赋值(也可以已下标为键名,对象形式解构),对象按属性名赋值。
- 对象解构变量是左边的建值。
const {a} = {a: 1};
// 实际左边是{a: a}的简写, 变量是{a: a}中后面(建值)的a
- 对象解构可重复取值,属性名对应上。
const {a,a: b, a: c} = {a: 1};
- 解构赋值可设置默认值,只有解构目标严格等于(===)
undefined时才取默认值。 - 解构赋值不要以
{为行首,会解析成块级作用域,可以用()包住整个表达式,其他情况尽量避免使用(),防止出现解构歧义报错。 - 基本数据类型解构赋值。
- 函数参数解构赋值,及默认值设置方法。
- Map对象解构遍历。
三、字符串拓展
- 字符串遍历
for...of。 - 字符串模板写法`${}`包裹内容,{}内为可计算变量。
- 字符串模板入参函数(标签模板)。
includes(x)包含x、startsWith(x)匹配x开始,endsWith(x)匹配x结束,repeat(x)复制x次拼接,padStart(x,y)在开头用y循环补充到x位,padEnd(x,y)在结尾用y循环补充到x位,trimStart()去前空格,trimEnd()去后空格,matchAll()列出所有match。
四、正则拓展
- 断言匹配。
- 组名匹配。
五、数值拓展
Math.trunc()去掉小数部分,Math.hypot()计算平方和的平方根,**指数运算符。- 各种精度处理方法,及
Number.isFinite(), Number.isNaN(),Number.parseInt(), Number.parseFloat()移到Number对象上针对数值类型判断。
六、函数拓展
- rest参数fn(...arg)。
- 箭头函数,this指向外层this。
- 参数尾逗号,catch可无参数。
七、数组拓展
- 扩展运算符
...,替换f.apply、str.split(''),有Iterator 接口的对象都可使用:
Number.prototype[Symbol.iterator] = function*() {
let i = 0;
let num = this.valueOf();
while (i < num) {
yield ++i;
}
}
console.log([...5]) // [1, 2, 3, 4, 5]
- a = [...b] || [...a] = b 都能实现a与b之间的深拷贝(a与b本身引用不同),但a与b内部元素是浅拷贝(内部元素引用指向一致)。
Array.from()将类数组转化为数组,且可以传入第二个参数与map作用一致。
Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);
- Array.of()代替 new Array。Array.of()得到的总是参数组成的数组。
- arr.fill()填充参数为对象时,对象指针一致。
- 其他实例方法:
copyWithin()、find()、findIndex()、entries()、keys()、values()、includes()、flat()、flatMap(),entries返回一个Generator函数、flat入参数字表示扁平层级(可传Infinity完全扁平)。
八、对象拓展
- 简洁定义、属性表达式定义。
- super关键字,指向对象原型对象。
...运算符。- es2020新添加:
??判断运算符及?.判断连运算符。 Object.is()替换===:
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
Object.assign()对象属性合并,对象继承。Object.getOwnPropertyDescriptors()获取自身属性描述。__proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf()原型属性操作方法。Object.keys(),Object.values(),Object.entries()对象遍历方法,其中Object.entries()是Generator函数。Object.fromEntries()用于map转obj。
九、Symbol
- 继
undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)之后,javascript的第七种数据类型,用来创建唯一变量,可用作对象属性名。不是私有属性,不能被for...in、for...of遍历到。 Symbol.prototype.description获取定义Symbol定义时的参数字符串。Object.getOwnPropertySymbols()获取Symbol属性。Symbol.for():可理解成注册全局唯一变量。Symbol.keyFor():获取已注册变量的入参字符串。- 内置Symbol值:
Symbol.hasInstance:改变instanceof返回。
Symbol.isConcatSpreadable:concat是否可展开。
Symbol.species:指定父级链开始计算instanceof。
Symbol.match:改变str.match返回。
Symbol.replace:改变str.replace返回。
Symbol.search:改变str.search返回。
Symbol.split:改变str.split返回。
Symbol.iterator:改变默认遍历返回。
Symbol.toPrimitive:根据数据类型需求返回不同值(想到了经典问题a==1&&a==2成立)。
let obj = {
[Symbol.toPrimitive](hint) {
switch (hint) {
case 'number':
return 123;
case 'string':
return 'str';
case 'default':
return 'default';
default:
throw new Error();
}
}
};
2 * obj // 246
3 + obj // '3default'
obj == 'default' // true
String(obj) // 'str'
Symbol.toStringTag:修改数据toString返回的空格后字符串。
Symbol.unscopables:with环境排除属性数组
十、Set与Map数据结构
- Set数组,字符串去重;Map非字符串属性对象。
Set.prototype.size、Set.prototype.add(value)、Set.prototype.delete(value)、Set.prototype.has(value)、Set.prototype.clear()Map.prototype.size、Map.prototype.set(key, value)、Map.prototype.get(key)、Map.prototype.has(key)、Map.prototype.delete(key)、Map.prototype.clear(key),map.set可以链调。- WeakSet、WeakMap:都可以理解为键名只能是对象,键名所指对象不会计入垃圾回收机制。
十一、Proxy数据代理,Reflect对象
- Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。
- Proxy 实例的方法:
get(target, propKey, receiver):拦截对象属性的读取。
set(target, propKey, value, receiver):拦截对象属性的设置。
has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。
deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。
ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。
getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。
isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。
setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。
Proxy.revocable():创建一个可取消的Proxy实例。- Proxy实例的this指向Proxy,而非实例对象本身。
- Reflect对象的方法与Proxy对象的方法一一对应。
- 使用 Proxy、Reflect 实现观察者模式。
十二、Promise 对象
- 状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。
- 原型属性
Promise.prototype.then()、Promise.prototype.catch()、Promise.prototype.finally() Promise.all():所有请求得到结果,或者某个请求报错则结束。Promise.race():某个请求得到结果,或者某个请求报错则结束。Promise.allSettled():所有请求结束则结束。Promise.resolve()then接收、Promise.resolve()catch接收。
十三、Iterator 和 for...of 循环
- 数据原型添加
[Symbol.iterator]接口,即可用for...of遍历、...语法糖解析。 Array、Map、Set、String、TypedArray、函数的 arguments 对象、NodeList 对象自带Iterator接口。Iterator接口,本身可以理解成Generator函数next()方法获取的数据。
十四、Generator函数
- js异步处理方法
- 一般在传统函数function后紧跟
*,函数内用yield来处理异步 next()、throw()、return()可以理解替换yield
function* gen() {
yield 123 + 456;
}
yield*用来拆解Generator内部的Generatorthis处理,与配合new使用方法
function* gen() {
this.a = 1;
yield this.b = 2;
yield this.c = 3;
}
function F() {
return gen.call(gen.prototype);
}
var f = new F();
Thunk 函数:用来替换计算表达式。co 模块:用于 Generator 函数的自动执行。
十五、async 函数
- async函数实际是 Generator 函数的语法糖,结果返回的是Promise对象。
- 更简洁、语义的实现异步调用,不好处理异常
十六、类Class
- 可理解成构造函数语法糖,更好的实现继承
- 类的所有方法都定义在类的prototype属性上面
- 类的内部所有定义的方法,都是不可枚举的
- 与 ES5 一样,在“类”的内部可以使用get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。
- 类的方法内部如果含有this,它默认指向类的实例
- Class 可以通过extends关键字实现继承
- Object.getPrototypeOf方法可以用来从子类上获取父类。
- 子类的构造函数必须执行一次super函数,super()在相当于
父类.prototype.constructor.call(this) - 子类的__proto__属性,表示构造函数的继承,总是指向父类
- 子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性