目录
一、ECMAScript是什么
二、ES6新特性
2.1、let关键字
let常用于声明变量,使用let声明的变量有以下特点:
- 不允许重复声明变量
- 块级作用域
- 不存在变量提升
-
不影响作用域链
注意:以后声明变量使用let
2.2、const关键字
const关键字用来声明常量,const声明有以下特点:
- 声明必须赋初始值
- 常量名一般为大写
- 不允许重复声明
-
常量的值不能修改
-
块级作用域
注意:声明对象类型使用const。对象属性修改和数组元素变化不会出发const错误。
2.3、变量的解构赋值
1、数组的解构
const F3 = ['老大','老二','老三']
let [one,two,three] = F3
console.log(one,two,three); //输出结果:老大 老二 老三
2、对象的解构
const laoda = {
name:'张三',
age:'不详',
play:function(){
console.log('我会玩篮球');
}
}
let { name , age , play } = laoda
console.log(name); //输出结果:张三
console.log(age); //输出结果:不详
play() //输出结果:我会玩篮球
注意:频繁使用对象方法、数组元素,就可以使用解构赋值形式。
2.4、模板字符串
模板字符串(template string)是增强版的字符串,用反引号( ` ` )标识。
特点:
1、内容中可以出现换行符
2、变量拼接,使用 ${xxx} 形式输出变量
// 定义字符串
let str2 = `<ul>
<li>老大</li>
<li>老二</li>
<li>老三</li>
</ul>`;
// 变量拼接
let one = '老大';
let result = ` ${one}在家排行第一 `;
console.log(result) //输出结果:老大在家排行第一
注意:当遇到字符串与变量拼接的情况使用模板字符串。
2.5、简化对象写法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
let name = '张三'
let change = function(){
console.log('学技术可以改变你!!');
}
const school = {
name,
change,
improve(){
console.log("学技术可以提高你的技能");
}
}
注意:对象简写形式简化了代码,所以以后用简写就对了。
2.6、箭头函数
ES6 允许使用[箭头] ( => )定义函数
// 写法
let fn = (a,b)=>{
return a+b;
}
let result = fn(1,1)
console.log(result) //输出结果:2
- 如果形参只有一个,则小括号可以省略。
- 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果。
- 箭头函数 this 指向声明时所在作用域下 this 的值。
- 箭头函数不能作为构造函数实例化。
- 不能使用arguments。
注意:箭头函数不会更改 this 指向,可以用来指定回调函数。
2.7、rest参数
ES6 引入 rest 实参,用于获取函数的实参,用来代替 arguments。
// ES5 获取实参的方式
function date(){
console.log(arguments);
}
date('a','b','c')
// rest 参数
function date2(...args){
console.log(args);
}
date2('d','f','e')
// rest 参数必须要放到参数最后
function date3(a,b,...args){
console.log(a);
console.log(b);
console.log(args);
}
date3(1,2,3,4,5,6)
注意:rest 参数适用于多个不定参数函数
2.8、spread扩展运算符
扩展运算符(spread)也是三个点(...)。扩展运算符能将 [数组] 转换为逗号分隔的 [参数序列] 。
// 声明一个数组
const F3 = ['老大','老二','老三']
// 声明一个函数
function output(...args){
console.log(args);
}
output(...F3) // output('老大','老二','老三')
2.9、Symbol
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
2.9.1、Symbol 的基本使用
特点:
-
Symbol 的值是唯一的,用来解决命名冲突的问题。
-
Symbol 值不能与其他数据进行运算。
-
Symbol 定义的对象属性不能使用 for…in 循环遍历,但是可以使用 Reflect.ownKeys 来获取对象的所有键名。
// 创建Symbol let s = Symbol() console.log(s,typeof s); // 输出结果:Symbol() 'symbol' let s2 = Symbol('尚硅谷') let s3 = Symbol('尚硅谷') console.log(s2); //Symbol(尚硅谷) console.log(s3); //Symbol(尚硅谷) console.log(s2 === s3); // 输出结果:false // Symbol.for 创建 let s4 = Symbol.for('尚硅谷') let s5 = Symbol.for('尚硅谷') console.log(s4 === s5); // 输出结果:true
2.9.2、Symbol 内置值
Symbol.hasInstance
|
当其他对象使用
instanceof
运算符,判断是否为该对象的实例时,会调用这个方法。
|
Symbol.isConcatSpreadable
|
对象的
Symbol.isConcatSpreadable
属性等于的是一个 布尔值,表示该对象用于Array.prototype.concat()
时,是否可以展开。
|
Symbol.species
|
当执行
str.match(myObject)
时,如果该属性存在,会调用它,返回该方法的返回值。
|
Symbol.replace
|
当该对象被
str.replace(myObject)
方法调时,会返回该方法的返回值。
|
Symbol.search
|
当该对象被
str.search (myObject)
方法调时,会返回该方法的返回值。
|
Symbol.split
|
当该对象被
str.split(myObject)
方法调用时,会返回该方法的返回值。
|
Symbol.match
|
当执行
str.match(myObject)
时,如果该属性存在,会调用它,返回该方法的返回值。
|
Symbol.iterator
|
对象进行
for...of
循环时,会调用
Symbol.iterator
方法,返回该对象的默认遍历器。
|
Symbol.toPrimitive
|
该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
|
Symbol. toStringTag
|
在该对象上面调用
toString
方法时,返回该方法的返回值。
|
Symbol. unscopables
|
该对象指定了使用
with
关键字时,哪些属性会被
with 环境排除。
|
2.10、生成器
function * gen(){
yield '一只没有耳朵',
yield '一只没有尾巴',
yield '真奇怪',
}
let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
// for循环输出
for(let v of gen()){
console.log(v);
}
代码说明:
* 的位置没有限制。 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到yield 语句后的值。 yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next 方法,执行一段代码。 next 方法可以传递实参,作为 yield 语句的返回值。
2.11、迭代器(Iterator)
ES6 创造了一种新的遍历命令 for...of 循环, Iterator 接口主要供 for...of 消费。 原生具备 iterator 接口的数据 ( 可用 for of 遍历 )。 Array、Set、Map、String、Arguments、NodeList、TypedArray。 工作原理
创建一个指针对象,指向当前数据结构的起始位置。 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员。 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员。 每调用 next 方法返回一个包含 value 和 done 属性的对象 。
2.12、Map与Set
2.12.1、Map
属性和方法:
- size 返回Map的元素个数
- set 增加一个新元素,返回当前Map
- get 返回键名对象的键值
- has 检测 Map 中是否包含某个元素,返回 boolean 值
- clear 清空集合,返回undefined
//创建一个 Map
let m = new Map([
['name','张三'],
['play','打篮球']
]);
//属性和方法
//获取映射元素的个数
console.log(m.size);
//添加映射值
console.log(m.set('age', 18));
//获取映射值
console.log(m.get('age'));
//检测是否有该映射
console.log(m.has('age'));
//清除
console.log(m.clear());
2.12.2、Set
属性和方法:
size 返回集合的元素个数 add 增加一个新元素,返回当前集合 delete 删除元素,返回 boolean 值 has 检测集合中是否包含某个元素,返回 boolean 值 clear 清空集合,返回 undefined
//创建一个 Set集合
let s1 = new Set([1,2,3,3]); // 会自动去重
//集合属性与方法
//返回集合的元素个数
console.log(s1.size);
//添加新元素
console.log(s1.add(4));
//删除元素
console.log(s1.delete(1));
//检测是否存在某个值
console.log(s1.has(2));
//清空集合
console.log(s1.clear());
2.13、Promise
//实例化 Promise 对象
const p = new Promise(function(resolve,reject){
let data = '数据库中的用户数据'
// resolve(data) // 成功返回
let err = '获取数据失败'
reject(err) // 失败返回
})
// 调用 promise 对象的 then 方法
p.then(function(value){
console.log(value) // 成功结果输出
},function(reason){
console.error(reason); //失败结果输出
})
// 调用 promise 对象的 catch 方法
p.catch((reason)=>{
console.log(reason); //失败结果输出
})
2.14、class类
class 声明类constructor 定义构造函数初始化extends 继承父类super 调用父级构造方法static 定义静态方法和属性父类方法可以重写
-
//父类 class Phone { //构造方法 constructor(brand, color, price) { this.brand = brand; this.color = color; this.price = price; } //对象方法 call() { console.log('我可以打电话!') } } //子类 class SmartPhone extends Phone { constructor(brand, color, price, screen, pixel) { super(brand, color, price); this.screen = screen; this.pixel = pixel; } //子类方法 photo(){ console.log('我可以拍照!'); } playGame(){ console.log('我可以玩游戏!'); } //方法重写 call(){ console.log('我还可以视频通话!'); } //静态方法 static run(){ console.log('我可以运行程序!') } static connect(){ console.log('我可以建立连接!') } } //实例化对象 const Nokia = new Phone('诺基亚', '黑色', 666); const iPhone6s = new SmartPhone('苹果', '白色', 6666, '4.7inch','6000w'); //调用子类方法 iPhone6s.playGame(); //调用重写方法 iPhone6s.call(); //调用静态方法 SmartPhone.run();
2.15、模块化
export 命令用于规定模块的对外接口import 命令用于输入其他模块提供的功能
2.16、对象方法扩展
- Object.is() 判断两个值是否完全相等,与(===)行为基本一致。
-
Object.assign() 对象的合并,将源对象的所有可枚举属性,复制到目标对象。
-
Object.setPrototypeOf() 设置原型对象。
//1.Object.is() 判断两个值是否完全相等
console.log(Object.is(120,120)); //输出结果:true
//2.Object.assign() 对象的合并
const config1 = {
host:'localhost',
port:3306,
name:'root',
pass:'root',
test: 'test'
}
const config2 = {
host:'https://baidu.com',
port:5500,
name:'baidu.com',
pass:'baidu.com',
}
console.log(Object.assign(config1,config2));
// 输出结果:{ host: "https://baidu.com",name: "baidu.com",pass: "baidu.com",port: 5500,test: "test" }
//3.Object.setPrototypeOf() 设置原型对象
const school = {
name:"编程学院"
}
const cities = {
xiaoqu:["北京","上海","深圳"]
}
Object.setPrototypeOf(school,cities);
console.log(school);// 输出结果:{name: "编程学院", xiaoqu: Array(3)}
三、ES7新特性
3.1、Array.prototype.includes
const mingzhu = ['西游记', '红楼梦', '三国演义', '水浒传']
//判断
console.log(mingzhu.includes('西游记')) // 输出结果:true
console.log(mingzhu.includes('金瓶梅')) // 输出结果:false
3.2、指数操作符
console.log(2 ** 10) // 1024; Math.pow(2,10)
四、ES8新特性
4.1、async和await
- async 函数的返回值为 promise 对象。
- promise 对象的结果由async函数执行的返回值决定。
- await 必须写在 async 函数中。
- await 右侧的表达式一般为 promise 对象。
- await 返回的是 promise 成功的值。
- await 的 promise 失败了,就会抛出异常,需要通过 try...catch 捕获处理。
async function fn() {
return new Promise((resolve, reject) => {
resolve('成功的数据');
})
}
const result = fn();
console.log(result);
result.then(value => {
console.log(value);
}, reason => {
console.log(reason);
})
// await 要放在async函数中
const p = new Promise((resolve, reject) => {
// resolve('成功');
reject('失败了')
})
async function test() {
try {
let result = await p
console.log(result);
}catch (error) {
console.log(error);
}
}
test()
4.2、对象方法扩展
- Object.values()方法返回一个给定对象的所有可枚举属性值的数组。
- Object.entries()方法返回一个给定对象自身可遍历属性 [key,value] 的数组。
- Object.getOwnPropertyDescriptors()方法返回指定对象所有自身属性的描述对象
// 声明对象
const school = {
name: '编程学院',
cities: ['北京', '广州', '深圳'],
xueke: ['前端', 'Java', '大数据', '运维']
}
// 获取对象所有的键
console.log(Object.keys(school));
// 获取对象所有的值
console.log(Object.values(school));
// entries 获取所有的键值对
console.log(Object.entries(school));
// 创建Map
const m = new Map(Object.entries(school));
console.log(m);
console.log(Object.getOwnPropertyDescriptors(school));
const obj = Object.create(null, {
name: {
// 设置值
value: '张三',
// 属性特性
writable: true,
configurable: true,
enumerable: true
}
})
console.log(obj);
五、ES9新特性
- Rest/Spread属性
- 正则表达式命名捕获组
- 正则表达式反向断言
- 正则表达式doAll模式
// 1.对象展开
function 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'
})
const skillOne = {
q: "666",
w: "999"
}
// ...skillOne => q:"666",w:"999"
// 2.正则扩展-命名捕获分组
let src = '<a href="https://www.baidu.com">百度</a>'
// 提取 url 与 [标签文本]
const reg = /<a href="(.*)">(.*)<\/a>/
// 换行
const result1 = reg.exec(src)
console.log(result1);
console.log(result1[1]);
console.log(result1[2]);
const reg2 = /<a href="(?<url>.*)">(?<test>.*)<\/a>/
const result2 = reg2.exec(src)
console.log(result2);
// 3.正则扩展-反向断言
let str = 'JS12323你是个666好好好'
// 正向断言
const reg3 = /\d+(?=好)/;
const result3 = reg3.exec(str)
console.log(result3);
// 方向断言
const reg4 = /(?<=个)\d/;
const result4 = reg4.exec(str)
console.log(result4);
// 4.正则扩展-dotAll模式
// . 元字符 除换行符以外的任意单个字符
let str2 = `
<ul>
<li>
<a>战狼2</a>
<p>上映时间:2017-7-17</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映时间:1994-07-06</p>
</li>
</ul> `
const reg5 = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/
const result5 = reg5.exec(str2)
console.log(result5);
六、ES10新特性
- Object.fromEntries
- trimStart 和 trimEnd
- Array.prototype.flat 与 flatMap
- Symbol.prototype.description
// 1.Object.fromEntries() // 用于将一个键值对数组转为对象
// 二维数组
const result = Object.fromEntries([
['name','编程学院'],
['xueke','Java,Vue']
])
console.log(result);
// Map 对象
const m = new Map()
m.set('name','编程学院')
const result2 = Object.fromEntries(m);
console.log(result2);
const arr = Object.entries({
name:"编程学院",
})
console.log(arr);
// 2. trimStart() 和 trimEnd() // 去除字符串两端的空格
// trim
let str = ' 编程学院 '
console.log(str);
console.log(str.trim());
console.log(str.trimStart());
console.log(str.trimEnd());
// 3.flat() 和 flatMap() // 数组的扁平化和扁平映射
// flat 平
// 将多维数组转化为低位数组
const arr1 = [1,2,3,4,[5,6]]
console.log(arr1.flat());
const arr2 = [1,2,3,4,[5,6,[7,8,9]]]
console.log(arr2.flat(2)); //参数为深度,是一个数字
// flatMap
const arr3 = [1,2,3,4]
const result3 = arr3.flatMap(item => [item * 10])
console.log(result3);
// 4.Symbol.prototype.description
let s = Symbol('编程学院')
console.log(s.description); // 输出结果:编程学院
七、ES11新特性
- String.prototype.matchAll
- 类的私有属性
- Promise.allSettled
- 可选链操作符
- 动态 import 导入
- globalThis 对象
八、ES12新特性
-
数字分隔符 ES12引入了一种新的语法,允许在数字中使用下划线作为分隔符,以增加可读性。例如,可以使用数字分隔符将1000000写为1_000_000。
-
Promise.any() Promise.any()是一个新的Promise方法,它接收一个Promise数组,并在其中的任何一个Promise成功时解决。这与Promise.race()方法不同,Promise.race()在其中的任何一个Promise解决或拒绝时返回。
-
String.prototype.replaceAll() String.prototype.replaceAll()是一个新的字符串方法,它可以在字符串中替换所有匹配的子字符串。它接收两个参数:要替换的子字符串和替换后的字符串。
-
WeakRef WeakRef是一种新的引用类型,它可以跟踪对象的引用,同时允许垃圾回收器在没有其他强引用时自动释放对象。这有助于避免内存泄漏。
-
Logical Assignment Operators ES12引入了三个逻辑赋值运算符:||=、&&=和??=。这些运算符结合逻辑运算符和赋值运算符的功能,并且对于简化某些常见的操作很有用。