JavaScript ES6新特性

178 阅读12分钟

ES6

let

  • 变量不能重复声明
  • 块级作用域(只在代码块中有效,外部就会无效)
  • 不存在变量提升(不允许在变量声明之前,使用这个变量)
  • 不影响作用域链
  • 暂时性死区(只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响)

const

用来声明常量(值不能修改的称为常量)

  • 一定要赋初始值
  • 一般常量使用大写(潜规则,小写也可以)
  • 常量值不能修改
  • 块级作用域
  • 对于数组和对象的元素修改,不算对常量的修改,不会报错。所以数据,对象创建时建议使用const

例:const ARR = [1,2,3];arr.push(4) 不会报错,原因是因为ARR指向的地址没有发生改变,发生改变的只是数组数据

变量结构赋值

ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值,称为解构赋值

  • 数组的解构

E}%]D8]8D[9@184UIWK1K.png

  • 对象解构赋值 image.png

模板字符串 ``

  • 内容中可以直接出现换行符
  • 可以直接进行变量拼接 image.png

简化对象写法

ES6允许在大括号里,直接写入变量和函数,作为对象的属性和方法 image.png

箭头函数 =>

箭头函数适合与this无关的回调,定时器,数组方法的回调。不适合与this有关的回调,事件回调,对象的方法

  • this是静态的,始终指向函数声明时所在作用域下的this的值,call和apply都不能改变指针的指向 image.png
  • 不能作为构造函数实例化对象 image.png
  • 不能使用arguments变量(arguments是用来保存实参的) image.png
  • 省略小括号,当形参有且只有一个是时候 image.png
  • 省略花括号,当代码体只有一条语句的时候,此时return必须也省略,而且语句的执行结果就是函数的返回值 image.png

允许给函数参数赋值初始值

  • 形参初始值,具有默认值的参数,一般位置要靠后(潜规则) image.png
  • 默认值可以与解构赋值同时使用 image.png

引入rest参数,用于获取函数的实参,用来代替arguments

  • ES5 image.png
  • ES6 image.png
  • rest参数必须放到参数的后面,否则会报错 image.png

扩展运算符 ...

扩展运算符能将数组转换为逗号分隔的参数序列 image.png

应用

  • 数组的合并 image.png
  • 数组的克隆(浅拷贝) image.png
  • 将伪数组转为真正的数组 image.png

Symbol

表示独一无二的值,它是js的第七种数据类型,是一种类似字符串的数据类型

特性

  • Symbol的值时唯一的,用来解决命名冲突问题
  • Symbol值不能与其他数据进行运算(不能进行隐式类型转换)
  • Symbol定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
  • Symbol 函数栈不能用 new 命令,因为 Symbol 是原始数据类型,不是对象

创建

image.png

使用场景

向对象中添加属性和方法,表示独一无二的

  • 安全的向一个对象中添加属性方法,不会影响到这个对象中本身的数据 image.png
  • 在写一个对象的时候,想为一个对象添加一个独一无二的属性 image.png

Symbol属性

除了定义自己使用的Symbol值以外,ES6还提供了内置的Symbol值,执行语言内部使用的方法。 可以称这些方法为魔术方法,因为它们会在特定的场 景下自动执行。

属性值说明
Symbol.hasInstance当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法(可以控制返回的结果)
Symbol.isConcatSpreadable对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开
Symbol.unscopables该对象指定了使用with关键字时,哪些属性会被with环境排除
Symbol.match当执行str.match(myObject)时,如果该属性存在,会调用他,返回该方法的返回值
Symbol.replace当该对象呗str.replace(myObject)方法调用时,会返回该方法的返回值
Symbol.search当该对象被str.search(myObject)方法调用时,会返回该方法的返回值
Symbol.split当该对象被str.split(myObject)方法调用时,会返回该方法的返回值
Symbol.iterator对象进行for...of循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器
Symbol.toPrimitive该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值
Symbol.toStringTag在该对象上调用toString方法时,返回该方法的返回值
Symbol.species创建衍生对象时,会使用该属性

Symbol方法

  • Symbol.for()

用于将描述相同的Symbol变量指向同一个Symbol值 image.png

  • Symbol.keyFor()

用来检测该字符串参数作为名称的 Symbol 值是否已被登记,返回一个已登记的 Symbol 类型值的 key image.png

a1已经用Symbol.for()登记过,因此返回的key为"a",而a2没有被登记,因此返回undefined

Symbol.for() 和 Symbol的区别

相同点

  • 它们定义的值类型都为"symbol"

不同点

  • Symbol()定义的值每次都是新建,即使描述相同值也不相等
  • Symbol.for()定义的值会先检查给定的描述是否已经存在,如果不存在才会新建一个值,并把这个值登记在全局环境中供搜索,Symbol.for()定义相同描述的值时会被搜索到,描述相同则他们就是同一个值

迭代器(Iterator)

是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口,就可以完成遍历操作(Iterator 接口的目的,就是为所有数据结构,提供了一种统一的访问机制,即for...of循环)

  • ES6创造了一种新的遍历命令for...of循环,Iterator接口(指的是对象里的属性Symbol.iterator)主要供for...of消费
  • 原生具备Iterator接口的数据(可用for...of遍历)
    • Array、Arguments、Set、Map、String、TypedArray、NodeList

特点

for...of循环调用遍历器接口,数组的遍历器接口只返回具有数字索引的属性。这一点跟for...in循环也不一样 image.png

上述代码中,for...of循环不会返回数组arr的foo属性

Iterator 接口的目的

就是为所有数据结构,提供了一种统一的访问机制,即for...of循环。当使用for...of循环遍历某种数据结构时,该循环会自动去寻找 Iterator 接口

工作原理

  • 创建一个指针对象,指向当前数据结构的起始位置
  • 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
  • 接下来不断调用next方法,指针一直往后移动,知道指向最后一个成员
  • 每调用next方法返回一个包含value和done属性的对象

应用

  • 实现自定义的遍历数据,对对象的遍历,对banji对象部署Iterator接口,Symbol.iterator属性对应一个函数,执行后返回当前对象的遍历器对象 image.png
  • 对于类似数组的对象(存在数值键名和length属性,字符串、DOM NodeList 对象、arguments对象),部署 Iterator 接口,有一个简便方法,就是Symbol.iterator方法直接引用数组的 Iterator 接口 image.png image.png

默认调用 Iterator 接口(即Symbol.iterator方法)

  • 解构赋值 image.png
  • 扩展运算符 image.png
  • yield* image.png
  • 其他场合:由于数组的遍历会调用遍历器接口,所以任何接受数组作为参数的场合,其实都调用了遍历器接口 image.png

遍历器对象的 return(),throw()

  • return()

使用场合是,如果for...of循环提前退出(通常是因为出错,或者有break语句),就会调用return()方法。如果一个对象在完成遍历前,需要清理或释放资源,就可以部署return()方法

image.png

注意,return()方法必须返回一个对象,这是 Generator 语法决定的 image.png image.png

上述代码中,情况一输出文件的第一行以后,就会执行return()方法,关闭这个文件;情况二会在执行return()方法关闭文件之后,再抛出错误

  • throw()

主要是配合 Generator 函数使用,一般的遍历器对象用不到这个方法

与其他遍历语法的比较:以数组为例

  1. for...in循环可以遍历数组的键名

缺点

  • 数组的键名是数字,但是for...in循环是以字符串作为键名“0”、“1”、“2”等等
  • for...in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键
  • 某些情况下,for...in循环会以任意顺序遍历键名
  • for...in循环主要是为遍历对象而设计的,不适用于遍历数组 image.png
  1. for循环 image.png

  2. for...of循环可以遍历数组的键值 image.png

  • 有着同for...in一样的简洁语法,但是没有for...in那些缺点
  • 不同于forEach方法,它可以与break、continue和return配合使用
  • 提供了遍历所有数据结构的统一操作接口

Generator 生成器

生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同 image.png

特性

  • function关键字与函数名之间有一个星号 image.png
  • 函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)

必须调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。换言之,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行 image.png

生成器的函数参数

image.png

异步操作的实例

image.png

next方法

next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值(next方法返回的是yield后面的东西)不传参就返回对应的那一次(每一次的next对应的是每一次yield,但是传参之后的值是上一次yield的结果而已,next对应的还是相对应的yield) image.png image.png

Generator.prototype.throw()

image.png

上述代码中,遍历器对象i连续抛出两个错误。第一个错误被 Generator 函数体内的catch语句捕获。i第二次抛出错误,由于 Generator 函数内部的catch语句已经执行过了,不会再捕捉到这个错误了,所以这个错误就被抛出了 Generator 函数体,被函数体外的catch语句捕获

throw方法可以接受一个参数,该参数会被catch语句接收,建议抛出Error对象的实例 image.png

不要混淆遍历器对象的throw方法和全局的throw命令。上面代码的错误,是用遍历器对象的throw方法抛出的,而不是用throw命令抛出的。后者只能被函数体外的catch语句捕获

Generator.prototype.return()

可以返回给定的值,并且终结遍历 Generator 函数 image.png

next()、throw()、return() 的共同点

它们的作用都是让 Generator 函数恢复执行,并且使用不同的语句替换yield表达式

  • next()是将yield表达式替换成一个值 image.png

上述代码中,第二个next(1)方法就相当于将yield表达式替换成一个值1。如果next方法没有参数,就相当于替换成undefined

  • throw()是将yield表达式替换成一个throw语句 image.png
  • return()是将yield表达式替换成一个return语句 image.png

Promise

是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,功能上用来封装异步操作并可以获取其成功或失败的结果 image.png

方法

then

then方法返回的是一个promise对象,对象状态(成功,失败)是由回调函数(then内函数的执行结果)的执行结果决定

  • 如果回调函数中返回结果是 非promise类型的数据,那么对象状态为成功,返回值为对象成功的值(若不return一个值,就会默认返回一个undefined) image.png image.png
  • 如果返回的是一个promise对象,内部返回的promise的状态,就决定then方法返回的状态,返回值就是内部promise的返回值 image.png image.png image.png image.png
  • 抛出错误,返回的是失败的状态,返回值时错误信息 image.png image.png

catch

promise对象失败的回调 image.png

all

参数接收一个数组,返回一个promise,只有当所有promise都成功时才成功,否则只要有一个失败的就失败 image.png image.png

race

参数接收一个数组,返回一个promise,其结果由第一个完成的promise决定 image.png image.png

语法糖

  • Promise.resolve()
  • Promise.reject()

手写Promise实现

Set

Map

class

ES5和ES6中实例化对象的方式

  • ES5中实例化对象的方式 image.png image.png

  • ES6中使用class实例化对象的方式 image.png image.png

  • 静态成员 image.png

ES5构造函数的继承和ES6的class继承

  • ES5 image.png image.png
  • ES6 image.png image.png

注意:子类是不能直接调用父类中同名的方法的,比如在ChildPhone中声明call(),会将父类的中call重写,在调用的时候,是调用的子类中的方法

get和set

get通常对动态属性进行封装,比如计数,set可以添加控制判断,比如判断添加的值是否符合设定的规则 image.png image.png

数值扩展

  • Number.EPSOLON image.png
  • Number.isFinite:检测一个数值是否为有限数
  • Number.isNaN:检测一个数值是否是NaN
  • Number.parseInt和Number.parseFloat:字符串转整数/浮点数
  • Number.isInteger:判断一个数值是否为整数
  • Math.trunc:将数值的小数部分抹掉
  • Math.sign:判断一个数值是正数(1)、负数(-1)还是零(0)

对象方法扩展

  • Object.is:判断两个值是否完全相等 image.png
  • Object.assign:对象的合并 image.png image.png
  • Object.setPrototypeOf 和 Object.getPrototypeOf image.png image.png

==================================

此为个人学习记录文章,如有错误请指出
欢迎小伙伴前来交流,如有转载请注明出处,谢谢
每一个努力的人都值得被肯定,但是最大的肯定来源于自己!!!
加油每一天!!!