ES(6-11)

1.let 关键字

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

  1. 不允许重复声明
  2. 块级作用域
  3. 不存在变量提升
  4. 不影响作用域链
    应用场景:以后声明变量使用 let 就对了

e.g:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>let 关键字</title>
	<style type="text/css">
		.item {
			width: 200px;
			height: 200px;
			border: 1px solid #000000;
		}
	</style>
</head>

<body>
	<div class="item"></div>
	<div class="item"></div>
	<div class="item"></div>
	<script type="text/javascript">
		//1.不允许重复声明
		// let a = 1
		// let a = 2
		// console.log(a)

		//2.块级作用域
		// {
		// 	let a = 2
		// }
		// console.log(a)

		//3.不存在变量提升
		// console.log(a)
		// let a = 3

		//4.不影响作用域链
		// {
		// 	let a = 1
		// 	function fn() {//此函数相当于var fn = function(){},因此存在变量提升,fn可在块级作用域外被调用
		// 		console.log(a, 'ssss')
		// 	}
		// 	fn()
		// }

		//实例
		let items = document.querySelectorAll(".item")
		//这样就可以
		// for (let i = 0; i < items.length; i++) {//利用了块级作用域
		// 	items[i].onclick = function () {
		// 		items[i].style.background = "red"
		// 	}
		// }
		//第二种做法(利用闭包)
		// for (var i = 0; i < items.length; i++) {
		// 	(function(i){
		// 		items[i].onclick = function(){
		// 		items[i].style.background = "red"
		// 	}
		// 	})(i)
		// }
		//第三种做法
		// for (var i = 0; i < items.length; i++) {
		// 	items[i].index = i
		// 	items[i].onclick = function(){
		// 		items[this.index].style.background = "red"
		// 	}
		// }
	</script>
</body>
</html>

2.const 关键字

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

  1. 声明必须赋初始值
  2. 标识符一般为大写
  3. 不允许重复声明
  4. 值不允许修改
  5. 块级作用域
  6. 不存在变量提升
  7. 不影响作用域链
  8. 但是可以修改const修饰的数组,对象变量中的元素
    注意: 对象属性修改和数组元素变化不会触发 const 错误
    应用场景:声明对象类型使用 const,非对象类型声明选择 let

e.g:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>const 关键字</title>
	</head>
	<body>
		<script type="text/javascript">
			// const 关键字用来声明常量,const 声明有以下特点
			// 1) 声明必须赋初始值
			// const a; 报错
			// 2) 标识符一般为大写(行业中的常识)
			// const CAR = "福特"
			// 3) 不允许重复声明
			// const a = 1
			// const a = 2
			// 4) 值不允许修改
			// const CAR = "福特"
			// CAR = "长安"
			// 5) 块级作用域
			// {
			// 	const A = 200
			// }
			// console.log(A)
			//6 不存在常量提升
			// console.log(c)
			// const c = 3
			//7 但是可以修改const修饰的数组,对象变量中的元素
			const a = ['uzi','ming']
			a.push('letem')
		</script>
	</body>
</html>

3.变量的解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称
为解构赋值。
注意:频繁使用对象方法(属性)、数组元素,就可以使用解构赋值形式

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			//1.将数组中的元素解构为变量,方便以后复用
			// const name = ['孙悟空','猪八戒','沙和尚']
			// let [sun,bajie] = name
			// console.log(sun) //孙悟空
			// console.log(bajie) //猪八戒
			
			//2.将对象中的属性解构为变量,方便以后复用
			// const wukong = {
			// 	name: '大师兄',
			// 	play: function(){
			// 		console.log("大师兄打白骨精")
			// 	}
			// }
			// let {name,play} = wukong
			// console.log(name)
			// console.log(play)
			// play()
		</script>
	</body>
</html>

4.模板字符串

模板字符串是增强版的字符串,用反引号(` (Tab上面的按键))标识,

特点

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

注意:当遇到字符串与变量拼接的情况使用模板字符串

5.对象简化写法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这
样的书写更加简洁
注意:对象简写形式简化了代码,所以以后用简写就对了

6.箭头函数

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

箭头函数的注意点:

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

注意:箭头函数不会更改 this 指向,用来指定回调函数会非常合适
定时器中的回调函数,数组中的回调函数

7.rest参数

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

/**
* 作用与 arguments 类似
*/
function add(...args){
 console.log(args);  //结果是数组
}
add(1,2,3,4,5);
/**
* rest 参数必须是最后一个形参
*/
function minus(a,b,...args){
console.log(a,b,args);
}
minus(100,1,2,3,4,5,19);

注意:rest 参数非常适合在函数参数不定个数的场景下使用

函数形参默认值
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			//注意: 设置默认值的那个参数必须放在形参列表最后,否则没有意义
			function add(a,b,c=6){
				console.log(a+b+c)  //9
			}
			add(1,2)
			//函数参数默认值与解构赋值结合
			function connect({host,port,username,password='home'}){
				console.log(host)
				console.log(port)
				console.log(username)
				console.log(password)
			}
			connect({
				host: 'www.baidu.com',
				port: 80,
				username: 'admin'
				// password: 'admin'
			})
		</script>
	</body>
</html>

8.spread 扩展运算符

扩展运算符(spread)也就是三个点(…),将一个数组(对象)转为用逗号分隔的参数序列,对数组(对象)进行解包.

let tfboys = ['德玛西亚之力','德玛西亚之翼','德玛西亚皇子'];
function fn(){
 console.log(arguments); //'德玛西亚之力','德玛西亚之翼','德玛西亚皇子'
}
fn(...tfboys)
/**
* 展开对象
*/
let skillOne = {
q: '致命打击',
};
let skillTwo = {
w: '勇气'
};
let skillThree = {
e: '审判'
};
let skillFour = {
r: '德玛西亚正义'
};
let gailun = {...skillOne, ...skillTwo,...skillThree,...skillFour};
//{q: '致命打击',w: '勇气',e: '审判',r: '德玛西亚正义'}

9.Symbol

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

Symbol 特点

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

注: 遇到唯一性的场景时要想到 Symbol
e.g:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Symbol 应用</title>
	</head>
	<body>
		<script type="text/javascript">
			//创建 Symbol
			let s1 = Symbol();
			// console.log(s1, typeof s1);
			//添加标识的 Symbol
			let s2 = Symbol('尚硅谷');
			let s2_2 = Symbol('尚硅谷');
			// console.log(s2 === s2_2,s2); //false
			//使用 Symbol for 定义
			let s3 = Symbol.for('尚硅谷');
			let s3_2 = Symbol.for('尚硅谷');//会从全局中找是否有Symbol('尚硅谷'),有就返回之前的,没有就新创建一个
			// console.log(s3 === s3_2,s3); //true

			//1.用于向arr对象中添加属性或者方法时不确定之前有没有和我一样的属性名
			// let arr = {
			// 	up: function(){
			// 		console.log('我是up方法')
			// 	}
			// }
			// let tem = {
			// 	up: Symbol()
			// }
			// arr[tem.up] = function(){
			// 	console.log("我是symbol的up")
			// }
			// let s = Symbol()
			// arr[s] = function(){
			// 	console.log("我是symbol的up222")
			// }
			// arr[tem.up]()
			// arr[s]()
			// console.log(arr)
			
			//2.第二种添加方式
			// let xiyouji = {
			// 	name: "孙悟空",
			// 	[Symbol('say')]: function(){
			// 		console.log('say method')
			// 	}
			// }
			// console.log(Reflect.ownKeys(xiyouji)[1])
			// xiyouji[Reflect.ownKeys(xiyouji)[1]]()

			/**
			 * Symbol内置对象属性的用法示例
			 */
			//  let obj = {name: '王二麻子'}
			// class Person{
			// 	static [Symbol.hasInstance] = function(param){
			// 		console.log(param)//{name: '王二麻子'}
			// 		console.log(param === obj);//true
			// 	}
			// }
			// console.log(obj instanceof Person)//false
			
			//第二个示例
			// let a = [1,2,3]
			// let b = [4,5,6]
			// b[Symbol.isConcatSpreadable] = false
			// let arr = a.concat(b)
			// console.log(arr)
			//(4) [1, 2, 3, Array(3)]
			
		</script>
	</body>
</html>
Symbol 内置值

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

Symbol内置对象自动执行的场景
Symbol.hasInstance当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法
Symbol.isConcatSpreadable对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于 Array.prototype.concat()时,是否可以展开

10.迭代器

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

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

注: 需要自定义遍历数据的时候,要想到迭代器。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			const team = {
				name: 'EDG',
				per: [
					'deft',
					'meiko',
					'panw',
					'clearlove',
					'korol'
				],
				[Symbol.iterator](){
					//索引
					let i = 0
					return {
						next: ()=>{
							//简化成一行代码
							return i < this.per.length?{value: this.per[i++],done: false}:{done: true}
							//繁琐的写法
							// if(i < this.per.length){
							// 	return {value: this.per[i++],done: false}
							// }else{
							// 	return {value: undefined,done: true}
							// }
							
						}
					}
				}
			}
			for (let v of team) {
				console.log(v)
			}
		</script>
	</body>
</html>

11.生成器

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

特点

  1. * 的位置没有限制
  2. 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到
    yield 语句后的值
  3. yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next
    方法,执行一段代码
  4. next 方法可以传递实参,作为 yield 语句的返回值
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			//1s后输出111-->2s之后输出222-->3s之后输出333
			function one(){
				setTimeout(()=>{
					console.log(111)
					iterator.next()
				}, 1000);
			}
			function two(){
				setTimeout(()=>{
					console.log(222)
					iterator.next()
				}, 2000);
			}
			function three(){
				setTimeout(()=>{
					console.log(333)
					iterator.next()
				}, 3000);
			}
			/**
			 * 声明生成器函数
			 * yield作用就是将函数代码块分隔开,只有调用一次iterator.next()才执行一个代码块,如下:3个yield分隔了4个代码块
			 */
			function* gen(){
				yield one()
				yield two()
				yield three()
			}
			let iterator = gen()
			iterator.next()
		</script>
	</body>
</html>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			//模拟流程: 先获取用户数据--->根据用户数据获取订单数据--->根据订单数据获取商品数据
			function getUsers(){
				setTimeout(()=>{
					let data = '用户数据'
					iterator.next(data)
				}, 1000);
			}
			function getOrders(){
				setTimeout(()=>{
					let data = '订单数据'
					iterator.next(data)
				}, 1000);
			}
			function getGoods(){
				setTimeout(()=>{
					let data = '商品数据'
					iterator.next(data)
				}, 1000);
			}
			/**
			 * 声明生成器函数
			 * yield作用就是将函数代码块分隔开,只有调用一次iterator.next()才执行一个代码块,如下:3个yield分隔了4个代码块
			 */
			function* gen(){
				let users = yield getUsers()
				console.log(users)
				let orders = yield getOrders()
				console.log(orders)
				let goods = yield getGoods()
				console.log(goods)
			}
			let iterator = gen()
			iterator.next()
		</script>
	</body>
</html>

12.Promise

Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,
用来封装异步操作并可以获取其成功或失败的结果。
详细资料及面试题请参考JavaScript专栏下的Promise

13.Set

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

  1. size 返回集合的元素个数
  2. add 增加一个新元素,返回当前集合
  3. delete 删除元素,返回 boolean 值
  4. has 检测集合中是否包含某个元素,返回 boolean 值
  5. clear 清空集合,返回 undefined
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			let arr = [1,2,3,4,5,4,3,2,1]
			//1.数组去重
			// let result = [...new Set(arr)]
			// console.log(result)
			
			//2.交集
			let arr2 = [4,5,6,4,5]
			// let result = [...new Set(arr)].filter((item)=> new Set(arr2).has(item))
			// console.log(result)
			//3.并集
			// let result = [...new Set([...arr,...arr2])]
			// console.log(result)
			//4.差集
			let result = [...new Set(arr)].filter((item)=> !(new Set(arr2).has(item)))
			console.log(result)
		</script>
	</body>
</html>

14.Map

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

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //创建一个空 map
        let m = new Map();
        //创建一个非空 map
        let m2 = new Map([
            ['name', 'dsfaf'],
            ['slogon', 'dsffgdg']
        ]);
        //获取映射元素的个数
        // console.log(m2.size);//2
        //添加映射值
        // console.log(m2.set('age', 6));
        // console.log(m2);
        //获取映射值
        // console.log(m2.get('age'));
        //检测是否有该映射
        // console.log(m2.has('age'));
        //清除
        // console.log(m2.clear());
    </script>
</body>
</html>

15.class

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

知识点:

  1. class 声明类
  2. constructor 定义构造函数初始化
  3. extends 继承父类
  4. super 调用父级构造方法
  5. static 定义静态方法和属性 (是在class的对象属性上)
  6. 父类方法可以重写
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			class Person {
				//静态属性是Person的属性,不是在Person的prototype上
				static header = '头'

				constructor(name, age) {
					this.name = name
					this.age = age
				}
				play() {
					console.log('人生如戏')
				}
				//get set方法 作用:可以根据具体的需求动态的拿到想要的数据
				get white(){
					return 120
				}
				set white(newname){
					this.name = newname
				}
				static say(){//静态方法是Person的属性,不是在Person的prototype上
					console.log('hello');
				}
			}
			let p = new Person('张三',10)
			console.log(p,Person.header)
			Person.say()
			
			class Student extends Person{
				constructor(name,age,school){
					super(name,age)
					this.school = school
				}
				study(){
					console.log('好好学习')
				}
			}
			let stu = new Student('王二麻子',16,'南大')
			// console.log(stu)
		</script>
	</body>
</html>

数值扩展

二进制,八进制,十六进制

ES6 提供了二进制,八进制,十六进制数值新的写法,分别用前缀 0b ,0o ,0x 表示,后面直接跟对应的进制数字就可以了

Number.isFinite() 与 Number.isNaN()

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

Number.parseInt() 与 Number.parseFloat()

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

Math.trunc

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

Number.isInteger

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

对象扩展

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

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

ES7新特性

1.Array.prototype.includes

Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值

2.指数操作符

在 ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同
console.log(3 ** 4);

ES8新特性

1.async 和 await

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

async 函数

  1. async 函数的返回值为 promise 对象,
  2. promise 对象的结果由 async 函数执行的返回值决定
    1)如果async函数返回的不是promise对象,则此函数的返回值是成功的promise对象
    2)如果async函数返回的是promise对象,则取决于promise对象是否成功
    3)抛出错误则是失败的promise对象

await 表达式

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

2.Object.values 和 Object.entries

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

ES9新特性

1.正则表达式命名捕获组

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

let str = '<a href="https://www.baidu.com">百度</a>';
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result = reg.exec(str);
console.log(result.groups.url);
console.log(result.groups.text);

2.正则表达式反向断言

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

//声明字符串
let str = 'JS5211314你知道么 555啦啦啦';
//正向断言
const reg = /\d+(?=啦)/;
const result = reg.exec(str); //555
//反向断言
const reg = /(?<=么)\d+/;
const result = reg.exec(str); //555

3.正则表达式dotAll模式(/s)

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

let str = `
<ul>
<li>
<a>肖生克的救赎</a>
<p>上映日期: 1994-09-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期: 1994-07-06</p>
</li>
</ul>`;
		//声明正则
		const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;
		//执行匹配
		// const result = reg.exec(str);
		let result;
		let data = [];
		while (result = reg.exec(str)) {
			data.push({ title: result[1], time: result[2] });
		}
		//输出结果
		console.log(data);

ES10新特性

1.Object.fromEntries

将二维数组转换为对象

2.trimStart 和 trimEnd

trimStart清除字符串左侧的空格
trimEnd清除字符串右侧的空格

3.Array.prototype.flat

flat可以将多维数组降为一维数组

ES11新特性

1.class的私有属性

在属性前加#字符即可,私有属性只能在类的内部访问,不能在类的外部访问(使用实例化对象访问私有属性也不行)

2.Promise.allSettled

批量执行互不依赖的异步任务

3.可选链操作符

字符是’ ?. ’
可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空(nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。

4.globalThis 对象

无论任何环境都是指向全局对象的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值