ES6-11语法详解

1、ES6新特性

1.1、新增关键字(let和const)

1.1.1 let 关键字

let 关键字用来声明变量,使用 let 声明的变量有几个特点:

  1. 不允许重复声明
  2. 块儿级作用域
  3. 不存在变量提升
  4. 不影响作用域链

应用场景:以后声明变量使用 let 就对了

代码示例:let

			//變量申明,不允許重複申明
			let a = "a",
				d = {};
			let a = "this is a";
			console.log(a)
			//块作用域
			let b, c; {
				let boy = "月月"
			}
			console.log(boy)
			//变量提升不存在
			
			
			try () {
				console.log(school)
				let school = "长沙民政";
			}
			//可访问外层let变量
			{
				let collage = "长沙民政"

				function fn() {
					console.log(collage)
				}
				fn()
			}

代码示例:let案例:点击div块改变对应div块的颜色

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>letExample</title>
	</head>
	<style>
		.item {
			width: 100px;
			height: 50px;
			border: 1px solid #000000;
		}
	</style>
	<body>
		<div>
			<h2>点击改变颜色</h2>
			<div class="item"></div>
			<div class="item"></div>
			<div class="item"></div>
		</div>
		<script>
			var items = document.getElementsByClassName("item")

			//i 作为全局变量,在function的块级作用域没有,往外找,var的i的值会变为3
			/*
			for (var i = 0; i < items.length; i++) {
				items[i].onclick = function() {
					this.style.background = 'blue'
					//所以在这里使用items[i]进行使用。i的值为3,没有对应的属性style
					//items[i].style.background = 'skyblue'
				}
			}
			*/
			//如果要使用这个items[i]进行赋值的话,就需要使用let进行局部变量的声明
			for (let i = 0; i < items.length; i++) {
				items[i].onclick = function() {
					items[i].style.background = 'firebrick'
				}
			}
		</script>
	</body>
</html>

1.1.2 const 关键字

const 关键字用来声明常量,const 声明有以下特点

  1. 声明必须赋初始值
  2. 标识符一般为大写
  3. 不允许重复声明
  4. 值不允许修改
  5. 块儿级作用域

注意: 对象属性修改和数组元素变化不会出发 const 错误
应用场景:声明对象类型使用 const,非对象类型声明选择 let

代码示例:const

			// const 声明变量 必须要赋初始值
			const a;
			//默认常量使用大写(规范)
			const DIR = 4
			//常量值不可修改
			const TOP = 1
			TOP = 3
			console.log(TOP)
			//const 声明的数组、对象的值可改变
			// 虽然数组、对象的值改变了,但是其常量所指向的地址没有发生改变

1.2、变量的解构赋值

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

代码示例:

			//解构赋值
			const arr = ["the shy", "ning", "rookie", "baolan"];
			let [S, Y, Z, F] = arr;
			console.log(S);
			console.log(Y);
			console.log(Z);
			console.log(F);
			
			// 对象结构
			const Rookie = {
				name:"宋义进",
				age:23,
				middle:function(){
					console.log("IG middle");
				}
			}
			
			let {name,age,middle} = Rookie;
			console.log(name)
			console.log(age)
			console.log(middle)
			
			// let {middle} = Rookie
			// console.log(middle)

1.3、模板字符串

模板字符串(template string)是增强版的字符串,用反引号(`)标识,特点:

  1. 字符串中可以出现换行符
  2. 可以使用 ${xxx} 形式输出变量

代码示例:

			// `` 反引号
			let str = `is string`
			console.log(str)
			console.log(typeof str)
			
			// 内容中可以出现换行
			let stringSingle = "<ul><li>1</li><li>2</li><li>3</li></ul>"
			
			let stringResver = `<ul>
									<li>1</li>
									<li>2</li>
									<li>3</li>
								</ul>`
			// 变量拼接
			console.log(`${str} this is str`)

1.4、简化对象写法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这
样的书写更加简洁。

代码示例:

			let name = "name";
			let change = function(){
				console.log("change")
			}
			const obj ={
				name,
				change,
				noChange:function(){
					console.log("no change")
				}
			}
			console.log(obj)

1.5、箭头函数

ES6 允许使用「箭头」(=>)定义函数。

箭头函数的注意点:

  1. 如果形参只有一个,则小括号可以省略
  2. 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果
  3. 箭头函数 this 指向声明时所在作用域下 this 的值
  4. 箭头函数不能作为构造函数实例化
  5. 不能使用 arguments

代码示例:

			let f = function() {}
			let t = (a, b) => {
				return a + b
			}
			console.log(t(1, 2))
			// 箭头函数的特点
			// 1 this是静态的,this始终指向函数声明时所在作用域下的this
			function getName() {
				console.log(this.name)
			}
			let getName1 = () => {
				console.log(this.name)
			}
			// 改变window下的这个name的值
			window.name = '月月鸟'
			getName()
			getName1()

			const obj1 = {
				name: '黄月月'
			}
			// 使用call函数改变当前this的值
			getName.call(obj1)
			getName1.call(obj1)

			// 不能使用箭头函数保存agruments实参
			let fn = () => {
				console.log(arguments);
			}
			// fn()
			// 箭头函数的省略
			let fn1 = (n) => {
				return n * n
			}
			// 当形参只有一个点时候可以省略括号
			let fn2 = n => {
				return n * n
			}
			// 只有一条语句可省略大括号和return
			let fn3 = n => n * n
			console.log(fn1(3))
			console.log(fn2(3))
			console.log(fn3(3))

1.6、rest 参数

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

代码示例:

			// ES5
			function data(){
				console.log(arguments)
			}
			data('黄','月','月');
			// ES6 rest参数
			// rest 参数必须放在最后
			function data1(...args){
				console.log(args)
			}
			data1('黄','月','月');

1.7、 spread 扩展运算符

扩展运算符(spread)也是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。

代码示例:

			//  ... 扩展运算符可以将数组转换为逗号分隔的参数序列
			const IG = ['the shy','ning','rookie','jackerlove','baolan']
			
			function LPL(){
				console.log(arguments)
			}
			LPL(IG)
			LPL(...IG)
			
			// 数组合并
			const a = ['1','2','3']
			const b = ['4','5','6']
			// 对于ES5
			console.log(a.concat(b))
			// 对于ES6 扩展运算符来说直接在中间加上一个逗号即可
			console.log([...a,...b]);
			
			// 数组克隆
			const SZH = ['E','G','M']
			const SYC = [...SZH]
			console.log(SYC)
			
			// 伪数组转真数组
			const divs = document.querySelectorAll("div")
			const divArr = [...divs]
			console.log(divArr)

1.8、Symbol对象

1.8.1、Symbol 基本使用

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

Symbol 特点

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

代码示例:

			// 创建Symbol
			let s = Symbol()
			console.log(s)
			console.log(typeof s)

			let s2 = Symbol('s2')
			console.log(s2)

			let s3 = Symbol('s2')
			console.log(s2 == s3)
			
			let s4 = Symbol.for('s4')
			console.log(s4)
			
			// 不可进行运算
			let res = s4 + 100

1.8.2、Symbol 内置值

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

1.9、迭代器

遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。

  1. ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费
  2. 原生具备 iterator 接口的数据(可用 for of 遍历) Array、Arguments、Set、Map、String、TypedArray、 NodeList
  3. 工作原理
    3.1 创建一个指针对象,指向当前数据结构的起始位置
    3.2 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
    3.3 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
    3.4 每调用 next 方法返回一个包含 value 和 done 属性的对象

代码示例:

			const IG = ['the shy', 'ning', 'rookie', 'jackerlove', 'baolan']

			// 使用 for of 进行遍历
			for (item of IG) {
				console.log(item)
			}
			// of 得到值 in得到索引
			for (item in IG) {
				console.log(item)
			}

			// 迭代 往后指 得到value和done的值
			let iterator = IG[Symbol.iterator]();
			console.log(iterator.next())
			console.log(iterator.next())
			console.log(iterator.next())
			console.log(iterator.next())
			console.log(iterator.next())

1.10、生成器

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

生成器注意点:

  1. * 的位置没有限制
  2. 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到yield 语句后的值
  3. yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next方法,执行一段代码
  4. next 方法可以传递实参,作为 yield 语句的返回值

代码示例:

			function* gen() {
				console.log("hello world")
			}

			let res = gen()
			console.log(res)

			res.next()

			// yield 作为代码分隔符
			function* gen1() {
				console.log('1')
				yield 'this is one'
				console.log('2')
				yield 'this is two'
				console.log('3')
				yield 'this is three'
			}

			// 不会执行
			let res1 = gen1()
			res1.next()
			res1.next()
			res1.next()

			// 生成器参数
			function* gen2(arg) {
				console.log(arg)
				let B = yield 111;
				console.log(B)
				yield 222;
				yield 333;
			}

			let res2 = gen2("AA")
			console.log(res2.next())
			// next 方法可传实参 
			console.log(res2.next("BBB"))
			console.log(res2.next())

生成器实例:代码示例:解决异步问题,这里使用定时器模拟异步数据

			// 异步编程处理 IO Ajax SQL

			// 案例 1秒后输出111 2秒后输出222 等等
			// 延时器回调嵌套 套娃模式
			// setTimeout(() => {
			// 	console.log("111")
			// 	setTimeout(() => {
			// 		console.log("222")
			// 		setTimeout(() => {
			// 			console.log("333")
			// 		}, 3000)
			// 	}, 2000)
			// }, 1000)
			
			
			// 
			function one(){
				setTimeout(() => {
					console.log("111");
					res.next();
				}, 1000)
			}
			function two(){
				setTimeout(() => {
					console.log("222");
					res.next();
				}, 2000)
			}
			function three(){
				setTimeout(() => {
					console.log("333");
					res.next();
				}, 3000)
			}
			
			// 使用生成器
			function * gen (){
				yield one();
				yield two();
				yield three();
			}
			
			let res = gen();
			res.next();

1.11、Promise对象

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

  1. Promise 构造函数: Promise (excutor) {}
  2. Promise.prototype.then 方法
  3. Promise.prototype.catch 方法

Promise对象的创建和then方法,代码示例:

			// 实例化 Promise 对象
			const p = new Promise(function(resolve, reject) {
				setTimeout(() => {
					// 成功
					// let data = 'user';
					// resolve(data)
					// 失败
					let data = 'defult'
					reject(data)
				}, 1000)
			})
			// 
			p.then(function(value) {
				console.log(value)
			}, function(reason) {
				console.log(reason)
			})

使用Promise对象读取文件模拟异步请求处理,代码示例:(用到nodsjs的fs模块):

const fs = require('fs')

//读取文件
// fs.readFile('./君子有所为.md', (err, data) => {
// 	if (err) throw err;
// 	console.log(data.toString())
// })

// 使用Promise 进行封装

const p = new Promise(function(resolve, reject) {
	fs.readFile('./../君子有所为.md', (err, data) => {
		if (err) reject(err);
		if (data) resolve(data.toString())
	})
})

p.then(function(value) {
	console.log(value)
}, function(reason) {
	console.log(reason)
})

使用Promise对象封装Ajax请求,代码示例:

			// 创建对象
			const xhr = new XMLHttpRequest()
			// 初始化
			xhr.open('GET', "http://api.apiopen.top/getJoke")
			// 发送请求
			xhr.send()
			// 绑定事件,处理结果
			xhr.onreadystatechange = function() {
				if (xhr.readyState == 4) {
					if (xhr.status >= 200 && xhr.status < 300) {
						console.log(xhr.response)
					} else {
						console.error(xhr.status)
					}
				}
			}

then方法详解,代码示例:

			const p = new Promise(function(resolve, reject) {
				setTimeout(() => {
					let data = 'defult'
					resolve(data)
				}, 1000)
			})
			// then 方法返回结果是Promise 返回状态由回调函数执行结果决定
			const res = p.then(value => {
				console.log(value)
				// 返回字符串 Promise对象的PromiseValue为返回值
				// return '1111'
				// 返回Promise对象
				return new Promise((resolve, reject) => {
					resolve('ok');
				})
			}, reason => {
				console.log(reason)

			})
			console.log(res)
			// then 支持链式回调  .then(()=>{}).then(()=>{})......

使用Promise读取多个文件操作,代码示例(nodejs):

const fs = require('fs');

// fs.readFile('./君子有所为.md', (err, data1) => {
// 	fs.readFile('./我见众生皆草木.md', (err, data2) => {
// 		fs.readFile('./唯见青山不见君.md', (err, data3) => {
// 			console.log(data1 + data2 + data3)
// 		})
// 	})
// })

// 使用Promise
const p = new Promise((resolve, reject) => {
	fs.readFile('./君子有所为.md', (err, data) => {
		resolve(data.toString()) // 使用toString转字符串,或者使用 +'' 进行字符串拼接
	})
})

// p.then((value, reason) => {
// 	console.log(value)
// })

p.then((value, reason) => {
	return new Promise((resolve, reject) => {
		fs.readFile('./我见众生皆草木.md', (err, data) => {
			resolve(value + data)
		})
	})
}).then((value, reason) => {
	return new Promise((resolve, reject) => {
		fs.readFile('./唯见青山不见君.md', (err, data) => {
			let res = value + data
			resolve(res)
			console.log(res)
		})
	})
})

catch方法,代码示例:

			const p = new Promise((resolve, reject) => {
				setTimeout(() => {
					reject("err")
				}, 1000)
			})
			// p.then((value, reason) => {
			// 	console.log(reason)
			// })

			p.catch(reason => {
				console.log(reason)
			})

1.12、Set集合

ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历

集合的属性和方法:

  1. size 返回集合的元素个数
  2. add 增加一个新元素,返回当前集合
  3. delete 删除元素,返回 boolean 值
  4. has 检测集合中是否包含某个元素,返回 boolean 值
  5. clear 清空集合,返回 undefined

集合的声明和方法操作,代码示例:

			// set 的声明
			let set = new Set();
			console.log(set)
			console.log(typeof set)
			// Set 存储会进行去重
			let set2 = new Set(['a', 's', 'd', 'a', 's'])
			console.log(set2)
			// 元素的个数
			console.log(set2.size);
			// 添加元素
			set2.add('f')
			// 删除元素
			set2.delete('a')
			// 判断是否存在
			set2.has('s')
			// 清空
			//set2.clear()
			
			// 遍历
			for(let val of set2){
				console.log(val)
			}

集合实践,数组去重、交集、并集、差集,代码示例:

			// 1 数组去重
			let arr = [1, 2, 2, 3, 3, 4, 4, 2, 1, 1]

			// let res = new Set(arr) // 这是还是Set集合
			// res = [...res] // 转为Array数组
			// console.log(res)

			// 求交集
			let arr2 = [1, 2, 3, 4, 23, 2]
			let res = [...new Set(arr)].filter(item => {
				let res2 = new Set(arr2)
				if (res2.has(item)) {
					return true
				} else {
					return false
				}
			})
			console.log(res)

			let res2 = [...new Set(arr)].filter(item =>
				new Set(arr2).has(item)
			)
			console.log(res2)
			// 求并集
			let union = [...new Set([...arr, ...arr2])]
			console.log(union)

			// 求差集
			let diff = [...new Set(arr)].filter(item =>
			!(new Set(arr2).has(item))
			)
			console.log(diff)

1.13、Map集合

ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。

Map 的属性和方法:

  1. size 返回 Map 的元素个数
  2. set 增加一个新元素,返回当前 Map
  3. get 返回键名对象的键值
  4. has 检测 Map 中是否包含某个元素,返回 boolean 值
  5. clear 清空集合,返回 undefined

map集合的声明和操作,代码示例:

			// 声明
			let map = new Map()
			//元素的添加
			map.set('name', 'yueyue')
			map.set('age', 18)
			map.set('change', function change() {
				console.log('change function')
			})
			let key = {
				school: '民院'
			};
			map.set(key, ['长沙市雨花区'])
			console.log(map)
			// 个数
			console.log(map.size)
			// 删除
			map.delete('age')
			// 获取 根据键获取
			console.log(map.get('name'))
			console.log(map.get(key))
			// 清空
			// map.clear()
			// 遍历
			for (let v of map) {
				console.log(v)
			}

1.14、class 类

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

1.14.1 class类的创建

ES5和ES6创建class类的区别,代码示例:

			// ES5 
			// 通过构造函数
			function Person(name, age) {
				this.name = name;
				this.age = age;
			}
			// 添加方法
			Person.prototype.myself = function() {
				console.log('i am person')
			}
			// 实例化
			let p = new Person('yueyue', 20)
			console.log(p)
			p.myself()

			// ES6 通过class类
			class PersonOne {
				// 构造方法
				constructor(name, age) {
					this.name = name;
					this.age = age;
				}
				myself() {
					console.log('i am person')
				}
			}
			let p1 = new PersonOne('yueyue', 20)
			console.log(p1)
			p1.myself()

1.14.2、class类的继承

			// ES5
			function Person(name, age) {
				this.name = name;
				this.age = age;
			}
			Person.prototype.myself = function() {
				console.log('i am person')
			}

			// 继承
			function APerson(name, age, size) {
				// 继承父类
				Person.call(this, name, age)
				this.size = size
			}
			// 设置子类构造函数的原型
			APerson.prototype = new Person;
			APerson.prototype.constructor = APerson;

			// 添加子类方法
			APerson.prototype.play = function() {
				console.log('play')
			}
			let p = new APerson('yue', 18, 100)
			console.log(p)
			p.myself()
			p.play()

			//ES6
			class Phone {
				constructor(name, size) {
					this.name = name;
					this.size = size;
				}
				call() {
					console.log('i can call')
				}
			}
			// 继承父类
			class huawei extends Phone {
				constructor(name, size, price) {
					// 子类调父类的构造方法
					super(name, size);
					// 子类独有的参数构造
					this.price = price;
				}
				play() {
					console.log('i can play')
				}
				// 方法重写
				call(){
					console.log('i can huawei call')
				}
			}
			const magic2 = new huawei('magic2', '4.7 inch', 2999)
			console.log(magic2)
			magic2.call()
			magic2.play()

1.15、数值扩展

1.15.1、Number.EPSILON:

Number.EPSILON 是 JavaScript 表示的最小精度;
EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16;

			// JS 小数计算
			console.log(0.1 + 0.2 === 0.3)

			// 数值拓展
			function equal(a, b) {
				if (Math.abs(a - b) < Number.EPSILON) {
					return true;
				} else {
					return false;
				}
			}
			console.log(equal(0.1 + 0.2, 0.3))

1.15.2、二进制和八进制:

ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示;

			// 二进制 八进制 十六进制
			let b = 0b111;
			let o = 0o111;
			let x = 0xff;
			console.log(b)
			console.log(o)
			console.log(x)

1.15.3、Number.isFinite() 与 Number.isNaN() :

Number.isFinite() 用来检查一个数值是否为有限的;
Number.isNaN() 用来检查一个值是否为 NaN;

			// 是否为有限数
			console.log(Number.isFinite(100))
			console.log(Number.isFinite(100 / 0))

			// isNaN
			console.log(Number.isNaN(123))

1.15.4、Number.parseInt() 与 Number.parseFloat():

ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变;

			// 字符串转整数
			console.log(Number.parseInt("123456asdf"))
			console.log(Number.parseFloat("123.456asdf"))

1.15.5、Math.trunc:

用于去除一个数的小数部分,返回整数部分;

			// 将数字的小数去掉
			console.log(Math.trunc(123.587))

1.15.6、Number.isInteger:

Number.isInteger() 用来判断一个数值是否为整数;

			// 判断是否为整数
			console.log(Number.isInteger(2))
			console.log(Number.isInteger(2.32))

1.16、对象扩展

概述:ES6 新增了一些 Object 对象的方法:

  1. Object.is 比较两个值是否严格相等,与『===』行为基本一致(+0 与 NaN);
  2. Object.assign 对象的合并,将源对象的所有可枚举属性,复制到目标对象;
  3. proto、setPrototypeOf、 setPrototypeOf 可以直接设置对象的原型;

代码示例:

			//Object.is  判断两个值是否相等
			console.log(Object.is(120, 1))
			console.log(Object.is(NaN, NaN))
			console.log(NaN == NaN)
			//Object.assign 对象合并
			const a = {
				name: 'yue',
				age: '18',
				size: 10
			}
			const b = {
				name: 'huang',
				age: '22',
				color: 'blue'
			}
			// 出现重名进行覆盖
			console.log(Object.assign(a, b))

			// 设置原型对象
			const school = {
				name: '民院'
			}
			const city = {
				xiaoqu: ['长沙', '广州']
			}
			Object.setPrototypeOf(school, city)
			console.log(Object.getPrototypeOf(school))
			console.log(school)

1.17、模块化

概述:模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来;

模块化的优势有以下几点:

  1. 防止命名冲突;
  2. 代码复用;
  3. 高维护性;

模块功能主要由两个命令构成:export 和 import;

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

js 暴露

// 分别暴露
// me.js
export let school = '民院'

export function say() {
	console.log('i am 民院')
}

// 统一暴露
// me2.js
let school = '民院'

function say() {
	console.log('i am 民院')
}

export {
	school,
	say
}

// 默认暴露
// me3.js
export default {
	meThree: 'this is a',
	sayThree: function() {
		console.log('this is say function')
	}
}

导入js模块代码示例:

		<script type="module">
			// 直接打开会出现跨域问题
			import * as me from './me.js'
			console.log(me)
			import * as me2 from './me2.js'
			console.log(me2)
			
			// 解构赋值分别暴露
			 import {default as me3} from './me3.js'
			 console.log(me3)
			
			// 简便形式 只能针对默认暴露
			import me4 from './me3.js'
			console.log(me4)
		</script>

2、ES7新特性

2.1、Array.prototype.includes

概述:
Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值;
判断数组中是否包含某元素,语法:arr.includes(元素值);

2.2、指数操作符

概述:
在 ES7 中引入指数运算符 **,用来实现幂运算,功能与 Math.pow 结果相同;幂运算的简化写法,例如:2的10次方:2**10;

代码示例:

			//include
			let arr = [1, 2, 3, 4, 5];
			console.log(arr.includes(2))
			// 幂运算
			console.log(10 ** 2)
			console.log(Math.pow(10, 2))

3、ES8新特性

3.1、async 和 await

async 和 await 两种语法结合可以让异步代码像同步代码一样

3.2、async 函数

  1. async 函数的返回值为 promise 对象,
  2. promise 对象的结果由 async 函数执行的返回值决定

代码示例:

			async function fn() {
				// 返回的不是Promise对象,那么这个函数返回的就是一个成功的Promise
				// return 'this is function'
				// return null 也就是undefined
				// return;
				// 抛出错误,则返回结果为一个失败的Promise
				// throw new Error('404')
				// 返回结果为一个Promise 对象
				return new Promise((resolve, reject) => {
					resolve('success')
				})
			}
			const f = fn()

			f.then((value, reason) => {
				console.log(value)
			})

3.3、await 表达式

  1. await 必须写在 async 函数中
  2. await 右侧的表达式一般为 promise 对象
  3. await 返回的是 promise 成功的值
  4. await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理

代码示例:

			const p = new Promise((resolve, reject) => {
				resolve('success')
			})
			async function fn() {
				let res = await p;
				console.log(res)
			}
			fn()

			const p1 = new Promise((resolve, reject) => {
				reject('err')
			})
			async function fn1() {
				try {
					let res1 = await p1;
					console.log(res1)
				} catch (e) {
					console.log(e)
				}
			}
			fn()

3.4、async和await模拟Ajax请求异步处理

代码示例:使用nodejs读取文件进行模拟

const fs = require('fs')

function read1() {
	return new Promise((resolve, reject) => {
		fs.readFile('./君子有所为.md', (err, data) => {
			if (err) reject(err)
			resolve(data)
		})
	})
}

function read2() {
	return new Promise((resolve, reject) => {
		fs.readFile('./唯见青山不见君.md', (err, data) => {
			if (err) reject(err)
			resolve(data)
		})
	})
}

function read3() {
	return new Promise((resolve, reject) => {
		fs.readFile('./我见众生皆草木.md', (err, data) => {
			if (err) reject(err)
			resolve(data)
		})
	})
}

// async
async function read() {
	let r1 = await read1();
	let r2 = await read2()
	let r3 = await read3()
	console.log(r1 + r2 + r3)
}

read()

3.5、对象扩展

3.5.1、Object.values 和 Object.entries

  1. Object.values()方法返回一个给定对象的所有可枚举属性值的数组
  2. Object.entries()方法返回一个给定对象自身可遍历属性 [key,value] 的数组

3.5.2、Object.getOwnPropertyDescriptors

该方法返回指定对象所有自身属性的描述对象

代码示例:

			const school = {
				name: '民院',
				cities: ['长沙',
					'广州',
					'深圳',
				],
			}

			// 获取所有键与值
			console.log(Object.keys(school))
			console.log(Object.values(school))
			console.log(Object.entries(school))

			const map = new Map(Object.entries(school))
			console.log(map.get('name'))
			
			console.log(Object.getOwnPropertyDescriptors(school))

4、ES9新特性

4.1、Rest/Spread 属性

Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,
在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符

代码示例:

			function self({
				name,
				age,
				...user
			}) {
				console.log(name)
				console.log(age)
				console.log(user)
			}

			self({
				name: 'yueyue',
				age: 18,
				hieght: '170cm',
				weight: '62kg'
			})

			const person = {
				name: 'huang',
				age: '18',
				color: 'huang'
			}
			console.log({
				...person
			})

4.2、正则表达式命名捕获组

ES9 允许命名捕获组使用符号『?』,这样获取捕获结果可读性更强

代码示例:

			let str = '<a href="http://www.baidu.com">baidu</a>'
			const reg = /<a href="(.*)">(.*)<\/a>/
			const res = reg.exec(str)
			console.log(res)

			let str1 = '<a href="http://www.baidu.com">baidu</a>'
			const reg1 = /<a href="(?<url>.*)">(?<text>.*)<\/a>/
			const res1 = reg1.exec(str1)
			console.log(res1)
			console.log(res1.groups.url)
			console.log(res1.groups.text)

4.3、正则表达式反向断言

ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选。

			let str = '123456是是是555啊啊啊';

			// 正向断言
			const reg = /\d+(?=啊)/
			const res = reg.exec(str)
			console.log(res)

			// 反向断言
			const reg1 = /(?<=是)\d+/
			const res1 = reg.exec(str)
			console.log(res1)

4.4、正则表达式 dotAll 模式

正则表达式中点.匹配除回车外的任何单字符,标记『s』改变这种行为,允许行
终止符出现

代码示例:

			let str = `<ul>
			<li>
				<a>速度与激情9</a>
				<p>上映时间:2021-05-21</p>
			</li>
			<li>
				<a>阿甘正传9</a>
				<p>上映时间:1994-07-06</p>
			</li>
		</ul>`
			// 使用正则进行匹配
			const reg = /<li>\s+<a>(.*?)<\/a>/

			const res = reg.exec(str)

			console.log(res)

			const reg1 = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs
			// gs 进行全局匹配
			let res1;
			// 使用data进行保存
			let data = []
			while (res1 = reg1.exec(str)) {
				//console.log(res1)
				data.push({
					title: res1[1],
					time: res1[2]
				})
			}
			console.log(data)

5、ES10新特性

5.1、Object.fromEntries

把键值对列表转换为一个对象。

代码示例:

			// 二维数组
			const res = Object.fromEntries([
				['name', 'yueyue'],
				['age', 18]
			])
			console.log(res)

			// map 对象
			const m = new Map();
			m.set('name', 'huang')
			const res1 = Object.fromEntries(m)
			console.log(res1)

5.2、trimStart 和 trimEnd

清除空字符串

代码示例:

			let str = '  this is str  '
			console.log(str)
			// 清除空字符串
			console.log(str.trimStart())
			console.log(str.trimEnd())

5.3、flat 与 flatMap

flat 方法会按照一个指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回

flatMap方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与map连着深度值为1的flat几乎相同,但flatMap通常在合并成一种方法的效率稍微高些。

代码示例:

			// flat 多维数组转低维数组
			let arr = [1, 2, 3, [4, 5, [1, 55, [4]]]]
			// 参数 表示 降几个维度
			console.log(arr.flat(2))

			let arr1 = [4, 5, 2]
			const res = arr1.flatMap((item) => [item * 58])
			console.log(res)

5.4、Symbol扩展

description 是一个只读属性,它会返回 Symbol 对象的可选描述的字符串。

代码示例:

			let s = Symbol('this is symbol')
			console.log(s.description)

6、ES11新特性

6.1、字符串扩展 matchAll

代码示例:

			let str = `<ul>
			<li>
				<a>速度与激情9</a>
				<p>上映时间:2021-05-21</p>
			</li>
			<li>
				<a>阿甘正传9</a>
				<p>上映时间:1994-07-06</p>
			</li>
		</ul>`

			let reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/sg

			// const result = reg.exec(str)
		    // 进行全局匹配
			const result = str.matchAll(reg)
			console.log(result)

			for (let v of result) {
				console.log(v)
			}

6.2、类的私有属性

私有属性采用 # 进行定义,和Java一样,私有属性在类的外部是获取不到的。

代码示例:

			class Person {
				// 共有属性
				name;
				// 私有属性
				#age;
				// 构造方法
				constructor(name, age) {
					this.name = name;
					this.#age = age;
				}
				sayAge() {
					console.log(this.#age)
				}
			}

			const gril = new Person('qing', 18)
			console.log(gril)
			console.log(gril.name)
			// 私有属性无法访问 undefined
			console.log(gril.age)
			// 只有在类里面才可以获取到这个私有属性
			gril.sayAge()

6.3、Promise.allSettled

该Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。

当您有多个彼此不依赖的异步任务成功完成时,或者您总是想知道每个promise的结果时,通常使用它。

代码示例:

			const p1 = new Promise((
				resolve,
				reject
			) => {
				setTimeout(() => {
					resolve('data1')
				}, 1000)
			});
			const p2 = new Promise((
				resolve,
				reject
			) => {
				setTimeout(() => {
					//resolve('data2')
					reject('err')
				}, 1000)
			});
			// 返回一个成功的Promise对象
			const result = Promise.allSettled([p1, p2]);
			console.log(result)
			// 有一个Promise对象失败 则返回的是一个失败的Promise
			const result1 = Promise.all([p1, p2])
			console.log(result1)

6.4、globalThis 对象

			// 始终指向全局
			console.log(globalThis)
  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Modify_QmQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值