1. 严格模式
es6 默认是严格模式 ‘use strict’
1. let const
let
不存在变量提升
只在声明所在的块级作用域内有效
不允许重复声明
暂时性死区 就是要在声明之后使用
const
不存在变量提升
只在声明所在的块级作用域内有效
不允许重复声明 + 声明就要赋值 + 声明只读常量且不可改变(引用类型可变 变量指向的那个内存地址所保存的数据不得改动 [],{}中可以改变)
暂时性死区
2. 解构赋值
解构赋值:
- 左边一种结构,右边一种结构,一一对应赋值
- 如果解构不成功,变量的值就等于
undefined
。- 解构赋值允许指定默认值。 只有当一个数组成员严格等于
undefined
,默认值才会生效。默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
- 数组:次序排列,一一对应,没有就undefined;...只能用在最后一个参数,表示 其他的元素组成一个数组
- 对象:属性没有次序,变量必须与属性同名,才能取到正确的值。
- 字符串:也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。有length属性。
- 数值和布尔值:则会先转为对象。有
toString
属性。用途:
- 交换变量的值
- 从函数返回多个值
- 函数参数的定义
- 提取 JSON 数据
- 函数参数的默认值
- 遍历 Map 结构
- 输入模块的指定方法
3. 各种扩展
正则扩展
- RegExp 构造函数 var regex = new RegExp(/xyz/i);合法。
- 修饰符 i 不区分大小写
- 修饰符 u
- Unicode字符 要加上 u 才可以识别
- 不能识别 大于 0xffff(即两个字符)的Unicode 字符,必须加上 u 修饰
- 量词大于 0xffff 要用 u 修饰
- RegExp.prototype.unicode 表示是否设置了
u
修饰符- RegExp.prototype.flags 会返回正则表达式的修饰符
- 修饰符 g/y
- g => 全局查找 从上一次匹配的位置继续寻找直到找到匹配的位置开始,不一定是第一个就匹配上
- y => 全局查找 但是 必须是匹配成后紧跟着的第一个字符就要匹配成功才算
字符串扩展
- 修饰符 u 大于0xffff 要用{}就可以识别
- codePointAt() 能够正确处理 4 个字节储存的字符,返回一个字符的码点。
- fromCodePoint 可以超过 0xffff fromCharCode 不能
- let of
- includes(), startsWith(), endsWith() 参数=>(str,n) n为起始位置
- repeat 小数先进行取整运算
- padStart(),padEnd() 参数(n,str) n为位数,无str 空格代替
- String.raw 充当模板字符串的处理函数,返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,对应于替换变量后的模板字符串。String.raw`Hi\n${2+3}!` // 返回 "Hi\\n5!"
- 拼接字符串 ``与${}
数值扩展
- ob/oB => 二进制开头
- Oo => 八进制开头
- Number.isFinite 判断又穷
- Number.isNaN 判断是否为数
- Number.isInteger 判断是否为整数
- Number.isSafeInteger 判断是否安全
- Math.trunc 只取整数部分(Math.floor 向下取整,负数时有区别)
- Math.sign 判断是否为整数 -1,0,1,NaN
- Math.cbrt 立方根
注意: Number.isFinite,Number.isNaN,Number.isNaN 如果参数类型不是数值,一律返回
false。
函数扩展
- 函数参数的默认值 设置默认值的参数后面参数不能没有默认值
- 与解构赋值默认值结合使用
- 函数的 length 属性 就是没有默认值的参数的个数
- rest 参数 ...arg rest 参数之后不能再有其他参数
- name 属性 返回该函数的函数名。
箭头函数
- 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。 this指向是固定的。
- 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
- 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
- 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
- 不适用场合 1. cat.jumps() 2. 需要动态
this
的时候,也不应使用箭头函数。- 尾调用优化 指某个函数的最后一步是调用另一个函数。
- 尾递归 函数调用自身,称为递归。如果尾调用自身,就称为尾递归。
- 柯里化 意思是将多参数的函数转换成单参数的形式。
数组的扩展
- 扩展运算符 ..[1,2,3] reset参数的逆运算 可以代替apply Math.max 、push
- Array.from() 将类数组(对象/inerable的对象(Map/Set))转成数组
- Array.of() 方法用于将一组值,转换为数组。
- [].copyWithin(target,start,end)前闭后开
- [].find 返回第一个符合条件的value
- [].findIndex 返回第一个符合条件的Index
- [].fill(content,start,end) 前闭后开
- entries(),keys() 和 values()
- [].includes(content) 是否包含content
- 数组实例的 flat(),flatMap() 拉平默认一层
扩展运算符应用:
- 克隆数组 const a2 = [...a1]
- 合并数组 const a2 = [a1,...a3]
- 与解构赋值结合 [a1,...a2]=a3
- 字符串转数组 [...'hello']
- Map,Set,Generator等inerator let arr = [...map.keys()];
对象扩展:
- 简洁表示法 let o=1;let es6={o}; es6=> {o:1}
- 属性表达式 let a ='b';let es6 = {[a]:'c'}; es6=>{b:'c'}
- Object.is() 两个值相等就返回true NaN +0与-0不相等
- Object.assign() 浅拷贝
- Object.getOwnPropertyDescriptors() 返回某个对象属性的描述对象(descriptor)。
- Object.getPrototypeOf() 用于读取一个对象的原型对象。
- super 关键字
- Object.keys(),Object.values(),Object.entries()
4.symbol
- 声明唯一变量
- 魔术字符串 :在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。
Object.getOwnPropertySymbols方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。
- Reflect.ownKeys方法可以返回所有类型的键名,包括常规键名和 Symbol 键名。
- Symbol.for方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建并返回一个以该字符串为名称的 Symbol 值。“登记一下”;
- Symbol.for("bar") === Symbol.for("bar") true Symbol("bar") === Symbol("bar") false;
- Symbol.keyFor方法返回一个已登记的 Symbol 类型值('Symbol.for()')的key。
5.Set Map WeakSet WeakMap
Set
- Set 本身是一个构造函数,用来生成 Set 数据结构。
- 成员的值都是唯一的,没有重复的值。
- Set 函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。
- [...new Set(array)]
- 长度 .size
- 方法 add delete clear has
- 获取值 .keys .values .entries .forEach
- new Set(content) content 必须为数组或类数组;
Array.from
方法可以将 Set 结构转为数组。WeakSet
- WeakSet : 结构与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别。WeakSet 的成员只能是对象,而不能是其他类型的值。
- 其次,WeakSet 中的对象都是弱引用
- 方法 add delete has
- 没有 .size .forEach方法
Map
- Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
- 不仅仅是数组,任何具有 Iterator 接口、且每个成员都是一个双元素的数组的数据结构(详见《Iterator》一章)都可以当作Map构造函数的参数。这就是说,Set和Map都可以用来生成新的 Map。
- Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。
- Map.set() Map.get()
- 方法 add delete clear has
- 获取值 .keys .values .entries .forEach
- 特别注意的是,Map 的遍历顺序就是插入顺序。
- [...myMap] 转化为数组 将数组传入 Map 构造函数,就可以转为 Map。
WeakMap
WeakMap
与Map
的区别有两点。- WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。
- 其次,WeakMap的键名所指向的对象,不计入垃圾回收机制。
- API 上的区别主要是两个,
- 一是没有遍历操作(即没有keys()、values()和entries()方法),也没有size属性。
- 二是无法清空,即不支持
clear
方法。
6. proxy
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截
get
- get方法用于拦截某个属性的读取操作,可以接受三个参数,依次为目标对象、属性名和 proxy 实例本身(严格地说,是操作行为所针对的对象),其中最后一个参数可选。get(target, propKey, receiver)
set
- set方法用来拦截某个属性的赋值操作,可以接受四个参数,依次为目标对象、属性名、属性值和 Proxy 实例本身,其中最后一个参数可选。 set: function(obj, prop, value, receiver)
apply
apply
方法拦截函数的调用、call
和apply
操作。has
- has方法用来拦截HasProperty操作,即判断对象是否具有某个属性时,这个方法会生效。典型的操作就是in运算符。
construct
- construct方法用于拦截new命令,下面是拦截对象的写法。
7. Reflect
- Reflect.get(target, name, receiver)
Reflect.get方法查找并返回target对象的name属性,如果没有该属性,则返回undefined。- Reflect.set(target, name, value, receiver)
Reflect.set方法设置target对象的name属性等于value。- Reflect.has(obj, name)
Reflect.has方法对应name in obj里面的in运算符。- Reflect.construct(target, args) § ⇧
Reflect.construct方法等同于new target(...args),这提供了一种不使用new,来调用构造函数的方法。
8. Promise
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
Promise.prototype.then() then
方法返回的是一个新的Promise
实例Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。
- Promise.prototype.finally()
finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。- Promise.all()
Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。- Promise.race()
Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。- Promise.resolve()
有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用。- Promise.reject()
Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。- Promise.try()
实际开发中,经常遇到一种情况:不知道或者不想区分,函数f是同步函数还是异步操作
9. iterator
原生具备 Iterator 接口的数据结构如下
- Array
- Map
- Set
- String
- TypedArray
- 函数的 arguments 对象
- NodeList 对象
调用 Iterator 接口的场合
- 解构赋值
- 扩展运算符
- yield*
- for...of
Array.from()
Map(), Set(), WeakMap(), WeakSet()(比如new Map([['a',1],['b',2]]))
Promise.all()
Promise.race()for...of 循环
- for...of循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、后文的 Generator 对象,以及字符串。
- 并不是所有类似数组的对象都具有 Iterator 接口,一个简便的解决方法,就是使用Array.from方法将其转为数组。
- 对于普通的对象,for...of结构不能直接使用,会报错,必须部署了 Iterator 接口后才能使用。但是,这样情况下,for...in循环依然可以用来遍历键名。
与其他遍历语法的比较
- forEach与for of比较:无法中途跳出forEach循环,break命令或return命令都不能奏效。
10.Generator
Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。
Generator 函数的调用方法与普通函数一样,也是在函数名后面加上一对圆括号。不同的是,调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象
Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。
- yield表达式只能用在 Generator 函数里面,用在其他地方都会报错。
- yield表达式如果用在另一个表达式之中,必须放在圆括号里面。
- yield表达式用作函数参数或放在赋值表达式的右边,可以不加括号。
- yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。
- for...of循环可以自动遍历 Generator 函数时生成的Iterator对象,且此时不再需要调用next方法。
- 除了for...of循环以外,扩展运算符(...)、解构赋值和Array.from方法内部调用的,都是遍历器接口。这意味着,它们都可以将 Generator 函数返回的 Iterator 对象,作为参数。
- next()、throw()、return()这三个方法本质上是同一件事,可以放在一起理解。它们的作用都是让 Generator 函数恢复执行,并且使用不同的语句替换yield表达式。
- next()是将yield表达式替换成一个值。
- throw()是将yield表达式替换成一个throw语句。
- return()是将yield表达式替换成一个return语句。
- this new F.prototype。
异步
ES6 诞生以前,异步编程的方法,大概有下面四种。
- 回调函数
- 事件监听
- 发布/订阅
- Promise 对象
Generator 函数将 JavaScript 异步编程带入了一个全新的阶段。
11. async
- 第一点,前面已经说过,await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。
- 第二点,多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。
- 第三点,await命令只能用在async函数之中,如果用在普通函数,就会报错。
12. Class
//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
constructor
- constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。
- 类不存在变量提升(hoist),这一点与 ES5 完全不同。
- 类的方法内部如果含有this,它默认指向类的实例。但是,必须非常小心,一旦单独使用该方法,很可能报错。
- 类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
相关题目练习:
https://www.cnblogs.com/fengxiongZz/p/8191503.html
https://blog.csdn.net/qq_39207948/article/details/80678800#rd