序
ECMAScript 是由ECMA国际通过 ECMA-262标准化的脚本标准化的脚本程序设计语言,Ecma 国际制定了许多标准,而 ECMA-262 只是其中的一个,从 ES6 开始,每年发布一个版本,版本号比年份最后一位大 1,ECMA-262至今已发展到了第十一版。
ECMA
ECMA(European Computer Manufacturers Association)
- 中文名称为欧洲计算机制 造商协会,这个组织的目标是评估、开发和认可电信计算机标准。1994年后该组织改名为 ECMA国际
谁在维护 ECMA-262
- TC39(Technical Committee 39)是推进 ECMAScript 发展的委员会。其会员都是公司(其中主要是浏览器厂商,有苹果、谷歌、微软、因特尔等)。TC39 定期召开会议,会议由会员公司的代表与特邀专家出席
兼容性
红色表示不兼容,绿色表示兼容
ES6
- ES6 的版本变动内容最多,具有里程碑意义
- ES6 加入许多新的语法特性,编程实现更简单、高效
let关键字
- let 关键字用来声明变量,使用 let 声明的变量有几个特点:
- 不允许重复声明
- 块级作用域
- 不存在变量提升,不允许在变量声明之前使用
- 不影响作用域链的效果
- 应用场景:以后声明变量使用 let 就对了
const 关键字
- const 关键字用来声明常量,const 声明有以下特点
- 声明必须赋初始值
- 标识符一般为大写
- 不允许重复声明
- 值不允许修改
- 块级作用域
- 注意: 对象属性修改和数组元素变化不会触发const错误,因为地址没有改变
- 应用场景:声明对象类型使用 const,非对象类型声明选择 let
变量的解构赋值
- ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23//数组的解构赋值
const arr = ['张学友', '刘德华', '黎明', '郭富城'];
let [zhang, liu, li, guo] = arr;
//对象的解构赋值
const lin = {
name: '林志颖',
tags: ['车手', '歌手', '小旋风', '演员']
};
let {name, tags} = lin;
//复杂解构
let wangfei = {
name: '王菲', age: 18,
songs: ['红豆', '流年', '暧昧', '传奇'],
history: [
{name: '窦唯'},
{name: '李亚鹏'},
{name: '谢霆锋'}
]};
let {songs: [one, two, three], history: [first, second, third]} =wangfei;模板字符串
- 模板字符串(template string)是增强版的字符串,用反引号(`)标识,特点:
1) 字符串中可以出现换行符
2) 可以使用 ${xxx} 形式输出变量1
2
3// 变量拼接
let lovest = '魏翔';
let out = `${lovest}是我心目中最搞笑的演员!!`;
简化对象写法
- ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁
1
2
3
4
5
6
7
8
9
10
11
12let name = 'xxx';
let change = function(){
console.log('xxx!');
}
const school = {
name,
change,
improve(){ //可以省略function
console.log("xxx");
}
}
箭头函数
- ES6 允许使用「箭头」( => )定义函数。
箭头函数的注意点:
1) 如果形参只有一个,则小括号可以省略
2) 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果
3) this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值
4) 箭头函数不能作为构造函数实例化
5) 不能使用 arguments1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/**
* 1. 通用写法
*/
let fn = (arg1, arg2, arg3) => {
return arg1 + arg2 + arg3;
/**
* 2. 省略小括号的情况, 当形参有且只有一个的时候
*/
let fn2 = num => {
return num * 10;
/**
* 3. 省略花括号的情况,当代码体只有一条语句的时候, 此时 return 必须省略,语句的执行结果就是函数的返回值
*/
let fn3 = score => score * 20;
/**
* 4. this 指向声明时所在作用域中 this 的值
*/
let fn4 = () => {
console.log(this);
} - 注意:箭头函数不会更改 this 指向,用来指定回调函数会非常合适
- ES6 允许给函数参数赋值初始值
- 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)
- 默认值还可以与解构赋值结合
rest 参数
- ES6 引入 rest 参数(…args),用于获取函数的实参,用来代替 arguments
1
2
3
4
5
6
7rest 参数必须要放到参数最后
function fn(a,b,...args){
console.log(a);
console.log(b);
console.log(args);
}
fn(1,2,3,4,5,6);
spread 扩展运算符
- 扩展运算符(spread)也是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包
- 可以合并数组
- 可以克隆数组
- 将伪数组转为真正的数组
1
2
3
4
5
6
7
8
9// 『...』 扩展运算符能将『数组』转换为逗号分隔的『参数序列』
//声明一个数组 ...
const tfboys = ['易烊千玺','王源','王俊凯'];
// => '易烊千玺','王源','王俊凯'
// 声明一个函数
function chunwan(){
console.log(arguments);
}
chunwan(...tfboys);// chunwan('易烊千玺','王源','王俊凯')
Symbol
- ES6 引入了一种新的原始数据类型 Symbol, 表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol 特点
1) Symbol 的值是唯一的,用来解决命名冲突的问题
2) Symbol 值不能与其他数据进行运算
3) Symbol 定义的对象属性不能使用 for…in 循环遍历, 但是可以使用
Reflect.ownKeys 来获取对象的所有键名 - js数据类型:undefined string symbol object null number boolean
Symbol 内置值
- 除了定义自己使用的 Symbol 值以外,ES6 还提供了11 个内置的Symbol 值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行
迭代器
- 遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作
1) ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费
2) 原生具备 iterator 接口的数据(可用 for of 遍历)- Array
- Arguments
- Set
- Map
- String
- TypedArray
- NodeList
3) 工作原理 - 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
- 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
- 每调用 next 方法返回一个包含 value 和 done 属性的对象
- 注: 需要自定义遍历数据的时候,要想到迭代器
生成器
- 生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同代码说明:
1
2
3
4
5
6function * gen(){
yield '一只没有耳朵';
yield '一只没有尾巴'; return '真奇怪';
}
let iterator = gen(); console.log(iterator.next()); console.log(iterator.next());
console.log(iterator.next());
1) *的位置没有限制
2) 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到
yield 语句后的值
3) yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next
方法,执行一段代码
4) next 方法可以传递实参,作为 yield 语句的返回值
Promise
- Promise 是 ES6 引入的异步编程的新解决方案。语法上Promise 是一个构造函数, 用来封装异步操作并可以获取其成功或失败的结果。
1) Promise 构造函数: Promise (excutor) {}- promise (function(resolve,reject){});
2) Promise.prototype.then 方法 - then(function(){value},function(reason){})
- 调用 then 方法 then方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果决定
- 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值
- 如果是promise对象,promise返回的对象的状态就决定了then方法返回的promise的状态
3) Promise.prototype.catch 方法
- promise (function(resolve,reject){});
Set
- ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,集合的属性和方法:
1) size 返回集合的元素个数
2) add 增加一个新元素,返回当前集合
3) delete 删除元素,返回 boolean 值
4) has 检测集合中是否包含某个元素,返回 boolean 值
5) clear 清空集合,返回 undefined
Map
- ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键” 的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。Map 的属性和方法:
1) size 返回 Map 的元素个数
2) set 增加一个新元素,返回当前 Map
3) get 返回键名对象的键值
4) has 检测 Map 中是否包含某个元素,返回 boolean 值
5) clear 清空集合,返回 undefined
class 类
- ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法塘,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
知识点:
1) class 声明类
2) constructor 定义构造函数初始化
3) extends 继承父类
4) super 调用父级构造方法
5) static 定义静态方法和属性
6) 父类方法可以重写
数值扩展
Number.EPSILON 是 JavaScript 表示的最小精度
- 0.1+0.2===0.3不成立,因为浮点数运算是由误差的
- EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16
- 用EPSILON表示js运算的最小精确度
二进制和八进制
- ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示
Number.isFinite() 与 Number.isNaN()
- Number.isFinite() 用来检查一个数值是否为有限的
- Number.isNaN() 用来检查一个值是否为 NaN
Number.parseInt() 与 Number.parseFloat()字符串转整数
- ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变
Math.trunc
- 用于去除一个数的小数部分,返回整数部分
Number.isInteger
- Number.isInteger() 用来判断一个数值是否为整数
Math.sign
- 判断一个数到底为正数 负数 还是零
对象扩展
- ES6 新增了一些 Object 对象的方法
1) Object.is比较两个值是否严格相等,与『===』行为基本一致(+0 与 NaN)
2) Object.assign 对象的合并,将源对象的所有可枚举属性,复制到目标对象
3) proto 、setPrototypeOf、 setPrototypeOf 可以直接设置对象的原型
模块化
- 模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
1.模块化的好处
- 模块化的优势有以下几点:
1) 防止命名冲突
2) 代码复用
3) 高维护性
- 模块化规范产品
- ES6 之前的模块化规范有:
1) CommonJS => NodeJS、Browserify
2) AMD => requireJS
3) CMD => seaJS
- ES6 模块化语法
- 模块功能主要由两个命令构成:export 和 import
- export 命令用于规定模块的对外接口
- import 命令用于输入其他模块提供的功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import:
1. 通用的导入方式
引入 m1.js 模块内容
import * as m1 from "./src/js/m1.js";
//引入 m2.js 模块内容
import * as m2 from "./src/js/m2.js";
//引入 m3.js
import * as m3 from "./src/js/m3.js";
2. 解构赋值形式
import {school, teach} from "./src/js/m1.js";
import {school as guigu, findJob} from "./src/js/m2.js";
import {default as m3} from "./src/js/m3.js";
3. 简便形式 针对默认暴露
import m3 from "./src/js/m3.js";
console.log(m3);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21export:
//分别暴露
export let school = 'xxx';
export function teach() {
console.log("xxx");
}
//统一暴露
let school = 'xxx';
function teach(){
console.log("xxx");
}
export {school, teach};
//默认暴露
export default {
school: 'xxx',
teach: function(){
console.log("xxx");
}
}
ES7
Array.includes()
- Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值
指数操作符
- 在 ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同
ES8
async 和 await
- async 和 await 两种语法结合可以让异步代码像同步代码一样
- async 函数
- async 函数的返回值为 promise 对象,
- promise 对象的结果由 async 函数执行的返回值决定
- await 表达式
- await 必须写在 async 函数中
- await 右侧的表达式一般为 promise 对象
- await 返回的是 promise 成功的值
- await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理
Object.values 和 Object.entries
- Object.values()方法返回一个给定对象的所有可枚举属性值的数组
- Object.entries()方法返回一个给定对象自身可遍历属性 [key,value] 的数组
Object.getOwnPropertyDescriptors
- 该方法返回指定对象所有自身属性的描述对象
ES9
- Rest/Spread 属性
- Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
1
2
3
4
5
6
7
8
9
10
11
12
13function connect({host, port, ...user}) {
console.log(host);
console.log(port);
console.log(user);
}
connect({
host: '127.0.0.1',
port: 3306,
username: 'root',
password: 'root',
type: 'master'
});
- 正则表达式命名捕获组
- ES9 允许命名捕获组对捕获的结果进行命名,这样获取捕获结果可读性更强
1
2
3
4
5
6
7
8let str = '<a href="http://www.atguigu.com"></a>';
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result = reg.exec(str);
console.log(result.groups.url);
console.log(result.groups.text);
- 正则表达式反向断言
- ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选
1
2
3
4
5
6
7
8
9
10
11//声明字符串
let str = 'JS5211314 你知道么 555 啦啦啦';
//正向断言
const reg = /\d+(?=啦)/;
const result = reg.exec(str);
//反向断言
const reg = /(?<=么)\d+/;
const result = reg.exec(str);
console.log(result);
- 正则表达式 dotAll 模式
- 正则表达式中点 . 匹配除回车外的任何单字符,标记『s』改变这种行为,允许行终止符出现
ES10
- Object.fromEntries
- 将二维数组转化为对象,与entries作用相反
- trimStart 和 trimEnd
- trimStart负责清除字符串左侧空白
- trimEnd负责清除字符串右侧空白
- Array.flat() 与 flatMap
- flat()将多维数组转化为低维数组
- flatMap把Map的结果做一个维度降低,是flat和map操作的结合体
- Symbol.prototype.description
- 获取symbol的描述字符串
ES11
类的私有属性
- 私有属性前要加#
String.prototype.matchAll
- 用来得到正则批量匹配的结果
Promise.allSettled
- 接受一个promise数组,返回一个成功的结果,成功的值是每一个promise对象的状态和结果
可选链操作符?.
- xxx1?.xxx2?.xxx3如果有xxx1才会读取后面的xxx2以此类推
动态 import 导入
globalThis 对象
- 始终指向全局对象