ES全称叫做:EcmaScript,是脚本语言的规范,而平时经常编写的 JavaScript 是 EcmaScript 的一种实现,所以 ES 新特性其实就是指的是 JavaScript 的新特性。

一 介绍

ECMA 是欧洲计算机制造商协会,这个组织是评估,开发,认可电信和计算机标准,1994年之后,该组织改名为:ECMA 国际
ECMAScript:是由 ECMA 国际通过 ECMA-262 标准化的脚本程序设计语言
ECMA-262:ecma制定了许多标准,262 是其中的一种。

TC39 是推进ECMAScript 发展的委员会,其会员都是公司(其中主要是浏览器厂商:苹果,谷歌,微软,因特尔等)TC39 定期召开会议,会议由会员公司的代表和特邀专家出席。

ES6 的版本变动内容最多,具有里程碑的意义,还加入很多新的语法特性,编程实现更加简单,高效。

二 ES6

2.1、let声明变量

1、不能重复声明变量
2、块级作用域

  1. {
  2. // 这里声明的 man 在外部不能被使用
  3. let man = 'tom'
  4. }
  5. console.log(man)

3、不存在变量提升,即不能在变量声明前使用
4、不影响作用域链,即函数块可以使用外部 let 声明的变量

2.2、const声明常量

1、常量必须初始化,即声明就需要赋值
2、常量名一般大写
3、常量的值不能修改
4、也是块级作用域
5、对数组,对象里面的元素做修改,不算是对常量的修改

2.3、变量的解构赋值

ES6 允许按照一定模式从数组对象当中提取值,对变量进行赋值,这就是被称为解构赋值
1、数组的解构

  1. const arr = ["a", "b", "c", "d"]
  2. let [a, b, c, d] = arr
  3. console.log(a, b, c, d)

2、对象的解构

  1. const obj = {
  2. 'name': 'kll',
  3. 'age': 18,
  4. 'address': 'gz'
  5. }
  6. let {name, age, address} = obj
  7. console.log(name, age, address)

2.4、模板字符串

ES6 引入了新的声明字符串的语法
1、声明变量

  1. let str = `halo, i am a boy, i very happy, and so do you, how are you`
  2. console.log(str)

2、可以直接使用换行符号

  1. let a = `---------\n==========`
  2. console.log(a)

3、变量拼接

  1. let c = `${str}hhhh`
  2. console.log(c)

2.5、对象的简化写法

允许在大括号中,直接写变量和函数,作为对象的属性和方法,更加简洁
且变量名的引号可以省略!

  1. let a = {
  2. name: 'lz',
  3. age: 18,
  4. say() {
  5. console.log('halo')
  6. }
  7. }
  8. console.log(a)
  9. a.say()

2.6、箭头函数

允许使用【箭头】 => 来定义函数

  1. // 正常声明函数
  2. let fn1 = function (a, b) {
  3. console.log(a, b)
  4. }
  5. fn1('aaaa', 'bbbb')
  6. // es6声明函数
  7. let fn2 = (a, b) => {
  8. console.log(a, b)
  9. }
  10. fn2('vvvvv','dsdsds')

1、this是静态的,this 始终指向外部函数声明时所在作用域下的 this 的值

  1. // 正常声明函数
  2. let fn1 = function () {
  3. console.log(this)
  4. }
  5. // es6声明函数
  6. let fn2 = () => {
  7. console.log(this)
  8. }
  9. let a = {
  10. a: 'a',
  11. b: 'b'
  12. }
  13. fn1.call(a) // 此时打印的 this 是 a
  14. fn2.call(a) // 箭头函数打印的 this 还是 window 对象

2、不能作为构造函数实例化
3、不能使用 arguments 变量

  1. let fn2 = () => {
  2. // console.log(arguments) // 不允许在内部使用这个变量
  3. }

4、箭头函数的简写

  1. 省略小括号,当形参有且只有一个的时候
  2. 省略花括号,当代码体有且只有一条语句的时候 ```javascript // 省略小括号,当形参有且只有一个的时候 let fn3 = n => { console.log(n) } fn3(3)

// 省略花括号,当代码体有且只有一条语句的时候 let fn4 = n => console.log(n) fn4(4)

  1. <a name="w2zTc"></a>
  2. ## 2.7、函数参数赋值默认值
  3. 允许在函数调用时,如果没有参数传过来,就使用默认值,一般设置默认值的参数都放在后面
  4. ```javascript
  5. let fn3 = (a = 100, b = 'l') => {
  6. console.log(a, b)
  7. }

和解构赋值结合使用
形参定义时对象的属性使用等号赋值默认值,使用函数时,参数值为对象

  1. let fn4 = ({name, age, address = 'gz'}) => {
  2. console.log(name, age, address)
  3. }
  4. fn4({name: 'lz', age: 18})

2.8、rest参数

引入 rest 参数,用于获取函数的实参,用来代替 arguments ,类似于Java的接收可变长参数的方式
arguments 存储的是所有的参数,而 args 存储的后面剩余的所有参数

  1. let fn5 = function (a) {
  2. console.log(a, arguments)
  3. }
  4. let fn6 = function (a, ...args) {
  5. console.log(a, args)
  6. }
  7. fn5(1, 2, 3, 4, 5) // 打印的 arguments = [1,2,3,4,5]
  8. fn6(1, 2, 3, 4, 5) // 打印的 args = [2,3,4,5]

2.9、扩展运算符

【…】扩展运算符可以将【数组】转换为逗号分隔的【参数序列】

  1. const arr = [1, 2, 3, 4]
  2. let fn1 = function (a, b, c, d) {
  3. console.log(a, b, c, d)
  4. }
  5. // 这就是将数组的元素分割开传参数到函数fn1当中
  6. fn1(...arr)

1、数组的合并

  1. const a = [1, 2, 3, 4]
  2. const b = [5, 6, 7, 8]
  3. const c = [...a, ...b]
  4. console.log(c)

2、数组的克隆

  1. const d = [...c]

3、将伪数组转化为真数组

2.10、symbol

ES6 引入了一种新的原始数据类型:symbol,表示独一无二的值。是 JavaScript 语言的第 7 种数据类型,是一种类似于字符串的数据类型。
特点:

  1. 值是唯一的,用来解决命名冲突问题
  2. 值不能和其他数据类型进行运算
  3. 定义的对象属性不能使用 for…in 循环遍历,但是可以使用 Reflect.ownKeys 来获取对象的所有键名

    1. let a = Symbol()
    2. let b = Symbol('b')
    3. let e = Symbol('b')
    4. let c = Symbol.for('c')
    5. let d = Symbol.for('c')
    6. console.log(c === d) // true
    7. console.log(b === e) // false

    JavaScript 中 7 中数据类型的记忆:you are so niubility
    u:undefined
    s:String,Symbol
    o:Oject
    n:null,number
    b:boolean

  • 为对象中添加属性和方法 ```javascript let obj = {

}

  1. - Symbol内置值
  2. <a name="lllxs"></a>
  3. ## 2.11、迭代器
  4. 迭代器是一种接口,为各种不同的数据结构提供统一的访问机制,任何的数据结构只要部署在 Iterator 接口,就可以完成遍历操作。
  5. 1. ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费
  6. 1. 原生具备 Iterator 接口的数据(可用于 for of 遍历)
  7. 1. Array
  8. 1. Arguments
  9. 1. Set
  10. 1. Map
  11. 1. String
  12. 1. TypedArray
  13. 1. NodeList
  14. 3. 工作原理:
  15. 1. 创建一个指针对象,指向当前的数据结构的起始位置
  16. 1. 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
  17. 1. 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
  18. 1. 每次调用 next 方法返回一个包含 value done 属性的对象
  19. ```javascript
  20. // 遍历数组元素
  21. const arr = [1, 2, 3, 4, 5]
  22. for (let number of arr) {
  23. console.log(number)
  24. }
  25. let fn1 = function () {
  26. for (const argument of arguments) {
  27. console.log(argument)
  28. }
  29. }
  30. fn1(1,2,3,4)

2.12、生成器

生成器其实就是一个特殊的函数

  1. function* gen() {
  2. console.log("----------")
  3. }
  4. // gen执行会返回一个迭代器对象,用于迭代执行该函数
  5. let iterator = gen() // 这样函数的方法还不能立即执行,还需要执行 next 方法
  6. iterator.next()

yield:相当于函数的代码分隔符

  1. function* gen2() {
  2. console.log(1111)
  3. yield 'aaa'
  4. console.log(2222)
  5. yield 'bbb'
  6. console.log(3333)
  7. }
  8. let it2 = gen2()
  9. for (const never of it2) {
  10. // 这里其实就是执行了 yield 分割的第一个片段
  11. console.log(never) // 这个 never 就是 yield 后面的值
  12. }
  13. // 打印结果是:1111 aaa 2222 bbb 3333 按照顺序打印

生成器的函数参数

2.13、promise

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

  1. 构造函数:Promise(excutore) {}
  2. Promise.prototype.then 方法
  3. Promise.prototype.catch 方法 ```javascript // 实例化,参数是一个函数 const p = new Promise(function (resole, reject) { let data = “成功” let err = ‘error’ // resole(data) // 调用这个方法表示请求成功 reject(err) // 调用这个方法表示失败 })

// 执行 then 方法,传入两个函数,如果成功执行第一个函数,失败执行第二个函数 p.then(function (res) { // 成功 console.log(res) }, function (err) { // 失败 console.log(err) })

  1. - 封装 Ajax 的操作
  2. ```javascript
  3. // 改造
  4. const p2 = new Promise(function (resolve, reject) {
  5. // 接口地址:https://api.apiopen.top/getJoke
  6. // 创建对象
  7. let xhr = new XMLHttpRequest();
  8. // 初始化
  9. xhr.open('GET', 'https://api.apiopen.top/getJoke')
  10. // 发送
  11. xhr.send()
  12. // 绑定事件,处理响应接口
  13. xhr.onreadystatechange = function () {
  14. // 判断
  15. if (xhr.readyState === 4) {
  16. if (xhr.status >= 200 && xhr.status < 300) {
  17. // 成功
  18. resolve(xhr.response)
  19. } else {
  20. // 失败
  21. reject(xhr.status)
  22. }
  23. }
  24. }
  25. })
  26. p2.then(function (res) {
  27. console.log(res)
  28. }, function (err) {
  29. console.log(err)
  30. })

promise 的 catch 方法。这个就是上面处理回调的第二种方式。

  1. // 使用 catch 方法来捕捉失败的处理
  2. new Promise(function (resolve, reject) {
  3. reject('error form reject')
  4. }).then(function (res) {
  5. console.log(res)
  6. }).catch(function (err) {
  7. console.log(err)
  8. })

2.14、Set

ES6 提供了全新的数据结构 Set,类似于数组,但是成员的值都是唯一的,即无重复元素,和Java语言的 Set 结构差不多。集合实现了 Iterator 接口,所以可以使用 for…of 来进行遍历,集合的属性和方法

  1. size:属性,返回集合的元素个数
  2. add:方法,增加一个新的元素,返回当前集合
  3. delete:方法,删除元素,返回 boolean 值
  4. has:方法,检测集合中是否包含了某个元素,返回 boolean 值 ```javascript // 声明实例 let set = new Set() // 打印 set 的元素个数 console.log(set.size)

let set2 = new Set([1, 2, 3]) console.log(set2.size)

// 增加一个元素 set2.add(4) console.log(set2)

// 删除一个元素,参数是被删除元素的值 set2.delete(1) console.log(set2)

// 检测是否包含某个元素 console.log(set2.has(2))

// 清空元素 set2.clear() console.log(set2)

  1. 结合数组的相关操作
  2. ```javascript
  3. let arr = [1, 2, 3, 4, 2, 3]
  4. // 1 数组去重
  5. let set = [...new Set(arr)]
  6. console.log(set)
  7. // 交集
  8. let arr2 = [4, 3, 5, 6, 4, 5]
  9. let set2 = new Set(arr2)
  10. let arr3 = set.filter(item => {
  11. return set2.has(item);
  12. })
  13. console.log(arr3)
  14. // 并集
  15. let arr4 = [...new Set([...arr, ...arr2])]
  16. console.log(arr4)
  17. // 差集
  18. let a = [...new Set(arr)].filter(item => !new Set(arr2).has(item))
  19. console.log(a)

2.15、Map

ES6 的 Map 数据结构类似于 Java 的 Map,也是键值对组合,键的范围不限于字符串,各种类型的值都可以作为键,Map实现了 Iterator 接口,所以可以使用 for…of 进行遍历。

  1. size:属性,返回元素个数
  2. Map:增加一个新元素,返回当前的Map
  3. get:返回键名对象的键值
  4. has:检测 Map 中是否包含了某个元素,返回 boolean 值
  5. clear:清空集合,返回 undefined ```javascript // 声明 Map let map = new Map()

// 添加元素 map.set(‘name’, ‘lz’) map.set(‘age’, 18)

// 遍历 for (const item of map) { console.log(item[0],item[1]) // item是一个数组,第一个元素是key,第二个元素是value }

  1. <a name="s6zlS"></a>
  2. ## 2.16、class类
  3. 这里的class,是作为对象的模板,也类似于Java的类。通过 class 关键字,可以定义类,基本上,这里的 class 可以看作是一个语法糖,绝大部分功能,ES5 都可以做到,新的 class 写法,也只是让对象的原型的写法更加清晰,更加像面向对象编程的语法而已。
  4. ```javascript
  5. class Phone {
  6. // 构造方法,名字不能修改
  7. constructor(a, b) {
  8. this.brand = a
  9. this.price = b
  10. }
  11. // 方法必须使用这个语法,不能使用 ES5 的对象完整形式
  12. say() {
  13. console.log('can call anybody')
  14. }
  15. }
  16. let xiaomi = new Phone('xiaomi', 1888)
  17. console.log(xiaomi)
  • 静态成员

声明在类中的静态成员是不能用实例调用的,只能使用类名来调用,因为这个静态成员是声明在构造函数上的,并不是在原型上的

  1. class Person {
  2. // 静态属性,属于这个类的,即构造函数的,只能使用类名调用
  3. static name = '人类'
  4. // 静态方法
  5. static fun() {
  6. console.log('fun')
  7. }
  8. }
  9. let xiaoMing = new Person()
  10. console.log(Person.name)

2.17、模块化

模块化指的是将一个大的程序文件,拆分成很多小的文件,然后将小文件组合起来。
模块功能主要由两个命令构成,export,import

  1. export命令用于规定模块的对外接口
  2. import命令用于输入其他模块提供的功能

1、暴露数据的方式

  1. // 分别暴露
  2. export let name = 'lz'
  3. export function fun() {
  4. console.log('i am a function in xxx.js')
  5. }
  1. let name = 'kk'
  2. function fun1() {
  3. console.log('hdsjhj')
  4. }
  5. // 统一暴露
  6. export {name, fun1}
  1. // 默认暴露
  2. export default {
  3. name: 'kkkk',
  4. fun2() {
  5. console.log('halo')
  6. }
  7. }
  1. <script type="module">
  2. import * as x from './js/xxx.js'
  3. import * as y from './js/yyy.js'
  4. import * as z from './js/zzz.js'
  5. console.log(x.name)
  6. y.fun1()
  7. z.default.fun2() // 需要加上 default
  8. </script>

2、引入数据的方式

  1. <script type="module">
  2. // 1、这种引入数据的形式是通用的形式
  3. import * as x from './js/xxx.js'
  4. import * as y from './js/yyy.js'
  5. import * as z from './js/zzz.js'
  6. console.log(x.name)
  7. y.fun1()
  8. z.default.fun2()
  9. // 2、解构赋值的形式
  10. import {name, fun} from './js/xxx.js'
  11. import {name as name2, fun1} from './js/yyy.js' // 可以给导入的变量起别名
  12. import {default as zz} from './js/zzz.js' // 导入默认暴露的数据
  13. console.log(name)
  14. console.log(name2)
  15. console.log(zz.name)
  16. // 3、简便形式,只实用于默认暴露的数据
  17. import zzz from './js/zzz.js'
  18. zzz.fun2()
  19. </script>

2.18、Object.assgin

对象赋值,赋值对象间相同属性名的值

  1. <script>
  2. let searchParams = {
  3. "category1Id": "", // 一级分类Id
  4. "category2Id": "", // 二级分类Id
  5. "category3Id": "", // 三级分类Id
  6. "categoryName": "", // 分类名称
  7. "keyword": "", // 关键字
  8. "order": "1:desc", // 排序
  9. "pageNo": 1, // 页码
  10. "pageSize": 10, // 每页数量
  11. "props": ["1:1700-2799:价格", "2:6.65-6.74英寸:屏幕尺寸"], // 商品属性的数组
  12. "trademark": "4:小米" // 品牌
  13. }
  14. let a = {"category1Id": 10}
  15. let b = {"categoryName": "手机", "keyword": "小米"}
  16. // 将后面的对象属性复制到第一个对象当中
  17. Object.assign(searchParams, a, b)
  18. console.log(searchParams)
  19. </script>