ES6 基础类型 let 1 .变量不能重复声明
2 .块级作用域
3 .不存在变量提升
4 .不影响作用域链
const 定义常量 1 .一定要赋初始值
2 .一般常量使用大写
3 .常量的值不能修改
4 .块级作用域
5 .对于数组和对象元素修改,不算对常量的修改,不会报错
1 2 const TEAM = ['UZI','Ming','Kasa']; TEAM.push('Lifa');//控制台不会报错,因为常量指向的地址没有发生改变,虽然数组元素改变了
变量的解析赋值 ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称作解析赋值
1 .数组的解构
1 2 3 const jijie = ["春", "夏", "秋", "冬"]; let [a, b, c, d] = jijie; console.log(a, b, c, d);
2 .对象的解构
1 2 3 4 5 6 7 8 9 10 11 12 const obj = { name: "张三", age: 18, fn: function () { console.log("testtest"); }, }; let { name, age, fn } = obj; console.log(name); console.log(age); console.log(fn); fn();
模板字符串 ES6 引入新的声明字符串的方式
特性:
1 2 3 let fistName = "Lee"; let fullName = `${fistName}Alfa`; console.log(fullName);
简化对象写法 ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法,这样更简洁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 let objName = "lifa"; let funTest = function () { console.log("fnTest"); }; // let objSimplify={ // objName:objName, // funTest:funTest, // anotherFn:function(){ // console.log('another'); // } // } let objSimplify = { objName, funTest, another(){ console.log(another); } }; console.log(objSimplify);
箭头函数 ES6 允许使用箭头(=>)定义函数
特性:
1 .this 是静态的,this 始终指向函数声明时所在作用域下的 this 的值,即便是 call 也不可改变 this 的指向
2 .不能作为构造函数实例化对象
3 .不能使用 arguments 对象
4 .箭头函数简写
箭头函数适合与 this 无关的回调,定时器,数组的方法回调
箭头函数不适合与 this 有关的回调,事件回调,对象的方法
参数默认值 ES6 允许给函数参数赋值初始值
1 .形参初始值,具有默认值的参数,一般位置要靠后(潜规则)
2 .与解构赋值结合
1 2 3 4 5 6 7 8 9 10 11 12 function connect({ url = "127.0.0.1", host, username, port }) { console.log(url); console.log(host); console.log(username); console.log(port); } connect({ host: "atguigu.com", username: "root", password: "root", port: 3306, });
rest 参数 ES6 引入rest 参数,用于获取函数的实参,用来替代 arguments,arguments 不是数组,而 rest 是数组
注意:rest 参数必须要放到参数最后
1 2 3 4 5 6 7 8 9 10 11 //ES5获取参数方式 function date1() { console.log(arguments); } date1("a", "b", "c", typeof arguments);//[Arguments] { '0': 'a', '1': 'b', '2': 'c', '3': 'object' } //ES6方式 function date2(a, b, ...rest) { console.log(rest); } date2("aa", "bb", "cc", "dd");//[ 'cc', 'dd' ]
spread 扩展运算符 …扩展运算符能将数组(或伪数组)**转换为逗号分隔的 参数序列**
1 2 3 4 5 6 const dir = ['东','南','西','北']; function dirFn(){ console.log(arguments); } dirFn(dir);//[Arguments] { '0': [ '东', '南', '西', '北' ] } dirFn(...dir);//[Arguments] { '0': '东', '1': '南', '2': '西', '3': '北' }
应用:
1 2 3 4 5 6 const arr1 = ["a", "b"]; const arr2 = ["c", "d"]; const fullArr1 = arr1.concat(arr2); //[ 'a', 'b', 'c', 'd' ] console.log(fullArr1); const fullArr2 = [...arr1, ...arr2]; //[ 'a', 'b', 'c', 'd' ] console.log(fullArr2);
1 2 3 4 5 function spreadFn() { console.log(arguments);//[Arguments] { '0': 'a', '1': 'b' } console.log([...arguments]);//[ 'a', 'b' ] } spreadFn("a", "b");
Symbol 原始数据类型 Symbol,表示独一无二的值,第七种数据类型
Symbol 特点
Symbol 的值是唯一的,用来解决命名冲突的问题
Symbol 值不能与其他数据进行运算
Symbol 定义的对象属性不能用 for…in 循环遍历,但可以使用 Reflect.ownKeys 来获取对象的所有键名
创建 Symbol
Symbol()方式
1 2 3 4 5 let s = Symbol(); console.log(s, typeof s); let s1 = Symbol("我是描述字符串"); let s2 = Symbol("我是描述字符串"); console.log(s1 == s2); //false
使用 Symbol.for 创建
1 2 3 4 5 6 7 let s3 = Symbol.for("尚硅谷"); let s4 = Symbol.for("尚硅谷"); let s5 = Symbol.for("我是描述字符串"); console.log(s3, typeof s3); console.log(s3 == s4);//true console.log(s3 === s4);//true console.log(s3 == s5);//false
USONB–you are so niubility u undefined
s——string symbol
o——object
n——null number
b——boolean
Symbol 创建对象属性 1 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 27 28 29 30 31 32 33 let game = { up: function () { console.log("upup"); }, down: function () { console.log(down); }, [Symbol("left")]: function () {//此种方法如何调用? console.log("left1"); }, [Symbol.for('left')]: function () {//此种方法可以调用 console.log("left2"); }, }; // console.log(game[Symbol("left")]); ------------------------------------------------------------------ let methods = { up: Symbol("up"), down: Symbol("down"), left: Symbol("left"), }; game[methods.up] = function () { console.log("up2"); }; game[methods.down] = function () { console.log(down2); }; game[methods.left] = function () { console.log("left3"); }; console.log(game); // console.log(game[Symbol('left')]()); console.log(game[Symbol.for('left')]());
Symbol 内置值 11 个内置的 Symbol 值,指向语言内部使用的方法,控制对象在特定场景下的表现
1 2 3 4 5 6 7 8 9 10 class Persong { static [Symbol.hasInstance](param) { console.log(param); console.log("用来检测类型"); // return true; return false; } } let o = {}; console.log(o instanceof Persong);
Symbol.isConcatSpreadable
1 2 3 4 let symArr1 = ["1", "2"]; let symArr2 = ["3", "4", "5"]; symArr2[Symbol.isConcatSpreadable] = false; console.log(symArr1.concat(symArr2));//["1", "2", Array(3)]
迭代器 迭代器(Iterator)是一个接口,任何数据结构只要部署了Iterator 接口(即对象中的属性,Symbol.iterator) ,就可以完成遍历操作。
1 2 3 4 5 6 7 8 9 10 11 12 let iteratorArr = ['a', 'b', 'c']; console.log(iteratorArr); //获取Symbol.iterator对应的函数,用以创建对象,在可遍历对象的_proto_上 let iteratorFunction = iteratorArr[Symbol.iterator]; //创建指针对象,使用Symbol.iterator对应的函数创建 let iteratorObj = iteratorArr[Symbol.iterator](); console.log(iteratorObj); //指针对象上有next方法,调用 console.log(iteratorObj.next());//{value: "a", done: false} console.log(iteratorObj.next()); console.log(iteratorObj.next()); console.log(iteratorObj.next());//{value: undefined, done: true}
自定义迭代器遍历对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 const iteratorData = { name: "二班", students: ["老二", "雅兴", "张超"], [Symbol.iterator]: function () { let index = 0; let _this = this; return { next: function () { if (index < _this.students.length) { const result = { value: _this.students[index], done: false }; index++; return result; } else { const result = { value: _this.students[index], done: true }; return result; } }, }; }, }; for (let v of iteratorData) { console.log(v); }
生成器 生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同
迭代器对象信息
1 2 3 4 5 6 7 8 9 10 11 12 function* gen() { yield "aaa"; yield "bbb"; yield "ccc"; } let iteratorGen = gen();//返回值为一个迭代器对象 console.log(iteratorGen); console.log(iteratorGen.next()); //{value: "aaa", done: false} for (const v of gen()) { console.log(v); //aaa bbb ccc }
生成器函数参数
函数传参和 next 方法传参,两种方式
第一个 next 方法传递的参数不可输出,第二个 next 方法参数将作为第一个 yield 返回结果值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function* gen2(arg){ console.log(arg);//AAA let one = yield '111'; console.log(one);//BBB let two = yield '222'; console.log(two);//CCC let three = yield '333' console.log(three); } //执行获取迭代器对象 let paramGen = gen2("AAA"); console.log(paramGen.next('EEE'));//无输出 console.log(paramGen.next('BBB'));//next方法可以传入参数,BBB作为第一个yield返回结果 console.log(paramGen.next('CCC'));//CCC将作为第二个yield返回结果 console.log(paramGen.next('DDD'));
生成器实例 1 .回调地狱问题
js 异步编程 文件操作 网络操作 数据库操作
解决回调地狱问题
将异步任务放到 yield 语句后执行,调用 next 方法执行 yield 语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 function one(){ setTimeout(() => { console.log(111); iteratorHell.next(); }, 1000); } function two(params) { setTimeout(() => { console.log(222); iteratorHell.next(); }, 2000); } function three(params) { setTimeout(() => { console.log(333); // iterator.next(); }, 3000); } function* dealHellFun(params) { yield one(); yield two(); yield three(); } let iteratorHell = dealHellFun(); iteratorHell.next();
2 .模拟数据获取 用户数据 订单数据 商品数据
数据是有关联的,要先有用户,根据用户获取订单,在获取商品数据
1 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 27 28 function getUser(params) { setTimeout(() => { let data = '用户数据'; iteratorMall.next(data);//第二次调用next,传入的参数做为第一个yield语句返回结果 }, 1000); } function getOrders(params) { setTimeout(() => { let data = '订单数据'; iteratorMall.next(data); }, 1000); } function getGoods(params) { setTimeout(() => { let data = '商品数据'; iteratorMall.next(data); }, 1000); } function* gen3(){ let user = yield getUser(); console.log(user); let orders = yield getOrders(); console.log(orders); let goods = yield getGoods(); console.log(goods); } let iteratorMall = gen3(); iteratorMall.next();
Promise 基本语法 Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数 ,用来封装异步操作并可以获取其成功或失败的结果。
Promise 构造函数:Promise(excutor){}
Promise.prototype.then 方法
Promise.prototype.catch 方法
Promise 封装 Ajax
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 let p = new Promise((resolve, reject) => { //1.创建对象 let xhr = new XMLHttpRequest(); //2.初始化 xhr.open("get", "https://api.apiopen.top/getJoke"); //3.发送 xhr.send(); //4.绑定事件,处理相应结果 xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) { resolve(xhr.response); } } }; }); p.then(value => { console.log(value); }).catch(err => { console.log(err); });
Promise 的 then 方法
1 p.then(success=>{},err=>{}).then()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 var fs = require("fs"); const { resolve } = require("path"); var readPromise = new Promise((resolve, reject) => { fs.readFile("./data/readfile1.txt", function (err, data1) { // console.log(data1.toString()); resolve(data1); }); }); readPromise .then((value) => { return new Promise((resolve, reject) => { fs.readFile("./data/readfile2.txt", function (err, data2) { resolve([value, data2]); }); }); }) .then((value) => { fs.readFile("./data/readfile3.txt", function (err, data3) { value.push(data3); console.log(value.join("\r\n")); }); });
Set ES6 提供新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的 ,集合实现了 iterator 接口,所以可以使用扩展运算符和 for…of…进行遍历。
1 .集合的属性和方法:
size 返回集合的元素个数
add 增加一个新元素,返回当前集合
delete 删除元素,返回 bool 值
has 检测集合中是否包含某个元素,返回 bool 值
clear 清空集合
2 .应用
1 2 3 let setArr1 = [1,2,3,4,5,4,3,2,1]; let newArr1 = [...new Set(setArr1)]; console.log(newArr1);
1 2 3 4 5 let setArr2 = [4,5,6,5,4]; let unionArr = [...new Set(setArr1)].filter(item=>{ return new Set(setArr2).has(item); }) console.log(unionArr);
1 2 let result = [...new Set([...setArr1,...setArr2])]; console.log(result);
1 2 3 4 let diffArr = [...new Set(setArr1)].filter(item => !(new Set(setArr2).has(item))); console.log(diffArr);//[ 1, 2, 3 ] let diffArr2 = [...new Set(setArr2)].filter(item=>new Set(setArr1).has(item)); console.log(diffArr2);
Map ES6 提供了 Map 数据结构。
类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种各类型的值(包括对象)都可以当做键。
Map 也实现了 iterator 接口,所以可以使用扩展运算符和 for…of 进行遍历
Map 的属性和方法:
size 返回 Map 元素的个数
set 增加一个新元素,返回当前 Map
get 返回简明对象的键值
has 检测 Map 中是否包含某个元素,返回 bool 值
clear 清空结合,返回 undefined
class 类 作为对象模板,通过 class 关键字,可以定义类。
基本上,ES6 的 class 可以看做知识一个语法糖,他的绝大部分功能,ES5 都可以做到。
新的 class 写法只是让对象原型的写法更加清晰、更像面向对象的语法而已。
类定义
构造方法,名字必须为 constructor,不可修改
方法必须使用 ES6 方法,不能使用 ES5 的对象完整形式
1 2 3 4 5 6 7 8 9 10 11 class Phone { constructor(brand, price) { this.brand = brand, this.price = price; } call(){ console.log('打电话'); } } let phone = new Phone('Iphone','5毛'); console.log(phone);
class 静态成员
函数是一个对象,[函数名]为函数对象;[new 函数名]获得的对象是实例对象
属于函数对象而不属于实例对象的属性和方法,称之为静态成员。则静态成员属于类不属于实例对象
ES5 方式实例对象
1 2 3 4 5 6 7 8 9 10 11 //MPhone是函数对象,mPhone是实例对象 function MPhone(){ } MPhone.name = '小米'; MPhone.call = function(){ console.log('Hello mi fans'); } let mPhone= new MPhone(); //对象上没有构造函数上的属性方法 console.log(mPhone.name);//undefined
1 2 3 4 5 6 7 8 9 function MPhone(){ } MPhone.prototype.name = '小米';//给构造函数上添加属性 MPhone.prototype.call = function(){ console.log('Hello mi fans'); } let mPhone= new MPhone(); console.log(mPhone.name);//小米
ES6 中 class 静态成员
静态成员属于类不属于实例对象
1 2 3 4 5 6 7 8 9 class StaticPhone{ static name = 'shouji'; static change(){ console.log('static方法'); } } let nokia = new StaticPhone(); console.log(nokia.name);//undefined console.log(StaticPhone.name);//手机
对象继承
1 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 27 28 29 //父级 function MPhone(brand, price) { this.brand = brand; this.price = price; } MPhone.prototype.call3 = function () { console.log("打电话"); }; //子级 function SmartPhone(brand, price, color, size) { //调用父级构造函数初始化代码,避免代码重写 MPhone.call(this, brand, price); this.color = color; this.size = size; } //设置子级构造函数原型 SmartPhone.prototype = new MPhone(); //实例对象和构造函数原型上的属性方法是相通的 SmartPhone.prototype.constructor = SmartPhone; //声明子级的方法(注意:实例上并不会出现此方法) SmartPhone.photo1 = function () { console.log("函数对象(父级)方法"); }; //声明子级实例的方法 SmartPhone.prototype.photo = function () { console.log("实例对象(子级)方法"); }; //实例化 const hammer = new SmartPhone("锤子", 3333, "黑色", "5inch"); console.log(hammer);
ES6 中 class 对象继承
继承方式:class 子类名 extends 父类名{}
子类中添加 super()函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class FatherClass { constructor(brand, price) { this.brand = brand; this.price = price; } call3() { console.log('class父级方法'); } } class SonClass extends FatherClass { constructor(brand, price, color, size) { super(brand, price); this.color = color; this.size = size; } sonFun() { console.log('子类的方法'); } } let sonClass = new SonClass('iPhone', 333, '星空灰', '4inch'); console.log(sonClass);
子类对父类方法的重写
子类不可以直接调用父类同名方法,super 方法只能出现在 constructor
class 中 getter 和 setter
get 通常对对象的动态属性进行封装
set 添加更多的控制
1 2 3 4 5 6 7 8 9 10 11 12 class GetSetClass { get price() { console.log('获取价格'); return 'huoqu' } set price(newVal) { console.log('价格修改'); } } let getSetClass = new GetSetClass(); console.log(getSetClass.price); getSetClass.price = '124'
数值扩展
Number.EPSILON 是 JavaScript 表示的最小精度,接近 2.22E-16
二进制和八进制
二进制 0b 开头,八进制 0o 开头,十六进制 ox 开头
Number.isFinite 检测一个数值是否为有限数
Number.inNaN 检测一个数值是否为有限数
Number.parsInt Number.parseFloat 字符串转换
Number.isInteger 判断一个数是否为整数
Math.trunc 将数字的小鼠部分抹掉
Math.sign 判断一个数到底为正数 负数 还是零
对象方法扩展
Object.is 判断两个值是否完全相等
1 2 console.log(NaN===NaN);//false console.log(Object.is(NaN,NaN));//true
Object.assign 对象的合并
Object.setPrototypeof 设置原型对象 Object.getPrototypeof
ES6 模块化 模块化是将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来.
优点:
模块化规范产品
CommonJS—>Node Browserify
AMD —> requireJS
CMD —> seaJS
ES6 规范 —> 浏览器端规范
ES6 模块化语法 模块功能主要由两个命令构成:export 和 import
export 命令用于规定模块的对外接口
import 命令 用于输入其他模块提供的功能(html 中引入时要设置 script 标签的 type 属性为 module )
一、export 暴露方式:
分别暴露
1 2 3 4 export let name1 = '分别暴露方式'; export function exportFun1(){ console.log('分别暴露方式函数'); }
统一暴露
1 2 3 4 5 6 let name1 = '分别暴露方式2'; function exportFun1(){ console.log('分别暴露方式函数2'); } export {name1,exportFun1}
默认暴露
1 2 3 4 5 6 export default { name1: "default暴露方式", exportFun1: function () { console.log("default暴露方式"); }, };
二、引入模块
通用导入
1 import * as m1 from './js/export1.js'//通用的引入方式
解构赋值形式
1 2 3 4 5 6 7 8 //分别导出的引入 import {name1,exportFun1} from './js/export1.js'//解构赋值方式 //统一导出的引入 import {name1 as name,exportFun1 as fun} from './js/export2.js'//设置别名解决命名冲突 //default导出的引入 import {default as m3} from './js/export3.js'
简便形式,只能针对默认暴露
1 import m4 from './js/export3.js'//简便形式,只适合default导出的
ES6-浏览器使用 ES6 模块化方式
直接导入方式
–>app.js 方式
在 app.js 文件引入各个模块文件,然后在 html 文件中引入 app.js 文件
1 2 3 4 5 6 7 8 9 10 app.js import * as m1 from './export1.js'//通用的引入方式 import { name1 as name, exportFun1 as fun } from './export2.js' import { default as m3 } from './export3.js' import m4 from './export3.js'//简便形式,只适合default导出的 console.log(m1); console.log(name); console.log(m3); console.log(m4);
–>Babel 方式(ES6→ES5)
并非所有的浏览器支持 ES6 语法
ES6 模块化还不能对 npm 安装的模块进行导入
步骤:
安装工具 babel-cli(babel 命令行工具)、 babel-preset-env(预设包,把最新的 ES 特性转换为 ES5)、 browserify(webpack)
语法转换 npx babel 源文件目录 -d dist/js –preset=babel-preset-env
ES6 语法转换为 CommonJS 模块规范化语法
浏览器不识别 require 语法
打包 npx browserify dist/js -o dist/bundle.js
ECMAScript7 新特性
Array.prototype.includes
includes 方法用于检测数组中是否包含某个元素,返回布尔类型值
指数运算符
在 ES7 中引入指数运算符“**”,用来实现幂运算,功能与 Math.pow 结果相同
ECMAScript8 新特性 async 和 await 两种语法相结合可以让异步代码像同步代码一样
async 函数
async 函数的返回值为 promise 对象,此对象由此函数内部 return 的状态决定
promise 对象的结果由 async 函数执行的返回结果决定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 async function asyncTest() { //返回结果不是一个promise类型的对象,返回的结果就是成功Promise对象 // return;//状态成功 //返回一个字符串 // return 'async函数';//状态成功 //抛出错误,返回的结果是一个失败的Promise // throw new Error('出错啦');//状态失败 return new Promise((resolve, reject) => { // resolve('状态成功');//指此promise对象状态成功,则async函数状态成功 reject("状态失败");//意味着此promise对象状态失败,则async函数状态失败 }); } let asyncResult = asyncTest(); console.log(asyncResult);
await 表达式
await 必须写在 async 函数中
await 右侧的表达式一般为 promise 对象
await 返回的是 promise 对象成功的值
await 的 promise 失败了,就会抛出异常,需要通过 try…catch 捕获处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 let awaitPromise = new Promise((resolve, reject) => { // resolve('await后面一般为promise对象'); reject('失败'); }); //await函数写在async中 async function awaitFun() { try { let result = await awaitPromise; console.log('await返回的是promise对象成功的值:'); console.log(result); } catch (error) { console.log(error); } } awaitFun();
async 和 await 集合读取文件
1 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 27 28 29 30 31 32 33 34 35 36 37 38 const fs = require("fs"); function getFile1() { return new Promise((resolve, reject) => { fs.readFile("./data/readfile1.txt", function (err, data1) { // console.log(data1.toString()); if(err) reject(err) resolve(data1); }); }); } function getFile2() { return new Promise((resolve, reject) => { fs.readFile("./data/readfile2.txt", function (err, data1) { // console.log(data1.toString()); if(err) reject(err) resolve(data1); }); }); }; function getFile3() { return new Promise((resolve, reject) => { fs.readFile("./data/readfile3.txt", function (err, data1) { // console.log(data1.toString()); if(err) reject(err) resolve(data1); }); }); } async function getAllContent() { let data1 = await getFile1(); let data2 = await getFile2(); let data3 = await getFile3(); console.log(data1.toString()); console.log(data2.toString()); console.log(data3.toString()); } getAllContent();
async 和 await 结合封装 Ajax
1 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 27 28 29 30 function getData() { return new Promise((resolve, reject) => { // var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; //1.创建对象 let xhr = new XMLHttpRequest(); //2.初始化 xhr.open("GET", "https://api.apiopen.top/getJoke"); //3.发送 xhr.send(); //4.绑定事件,处理相应结果 xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) { resolve(xhr.response); } else { reject(); } } }; }); } //promise then 方式 // getData().then(value=>{console.log(value);},reason=>{ // console.log(reason); // }); async function main() { let result = await getData(); console.log(result); } main();
ES8 对象方法扩展
Object.values()方法返回一个给定对象的所有可枚举属性值的数组
Object.entries()方法返回一个给定对象自身可遍历属性[key,value]的数组
Object.getOwnPropertyDescriptors()方法返回指定对象所有自身属性的描述对象
1 2 3 4 5 6 7 8 9 10 const es8Obj = { url:'2.2.2.2', method:'get', host:'localhost' } console.log(Object.keys(es8Obj)); console.log(Object.values(es8Obj)); console.log(Object.entries(es8Obj)); console.log(Object.getOwnPropertyDescriptors(es8Obj));
ES9 扩展运算符与 rest 参数
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对数组。
在 ES9 在为对象提供了像数组一样的 rest 参数和扩展运算符
ES9 正则扩展 命名捕获分组 1 2 3 4 5 6 7 8 9 10 11 12 13 let url = '<a href="https:baidu.com">百度</a>'; let reg = /<a href="(.*)">(.*)<\/a>/; let result = reg.exec(url); console.log(result); console.log(result[0]); console.log(result[1]); console.log(result[2]); let reg2 = /<a href="(?<str>.*)">(?<name>.*)<\/a>/; let result2 = reg2.exec(url); console.log(result2); console.log(result2.groups.str); console.log(result2[1]);
反向断言 根据目标前后内容做唯一性识别
1 2 3 4 5 6 7 8 let str = "JS1234你知道么555啦啦啦";//匹配555 let reg = /\d+(?=啦)/; let result = reg.exec(str); console.log(result);//555 //反向断言 let reg2 = /(?<=么)\d+/ console.log(reg2.exec(str));//555
dotAll 模式 dot . 元字符–>匹配处换行符之外的任意字符
dotAll 模式使.可以匹配任意字符
ES10 Object.fromEntries
1 2 3 let arr = [['a','es10学习'],['b','es10对象扩展']]; let es10Obj = Object.fromEntries(arr); console.log(es10Obj);//{ a: 'es10学习', b: 'es10对象扩展' }
1 2 3 4 5 6 let map = new Map(); map.set("name", "aaa"); let e = Object.fromEntries(map); console.log(e); //{name:'aaa'} //fromEntries与entries逆操作 console.log(Object.entries(e)); //['name','aaa']
trimStart 与 trimEnd 用以清除字符前后的空白
flat 与 flatMap 数组的两个方法
flat 将多为数组转换为低维数组,参数为整数,表示深度,默认值为 1
flatMap()数组的方法,与 Array.map 类似,可以将遍历的 item 返回的结果降低维度
Symbol.prototype.description 获取 Symbol 函数参数值
ES11 私有属性 对属性的封装,私有属性用“#”标识
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Person{ //公有属性 name; //私有属性 #age; #weight; constructor(name,age,weight){ this.name = name; this.#age = age; this.#weight = weight; } intro(){ console.log(this.#age); } } let person = new Person('aa',13,22) console.log(person.intro()); // console.log(person.#age);//报错
Promise 批处理方法
Promise.allSettled()
接收 Promise 数组,返回 Promise 对象
返回的结果永远是成功的状态,结果为每一个 promise 状态和结果值
Promise.all()
接收 Promise 数组
返回结果由数组中每一个 promise 状态决定,全成功才成功
字符串扩展方法 matchAll String.prototype.matchAll 用来得到正则批量匹配得到的结果
可选链操作符
形式:?.的组合
对象类型参数层级比较深,此符号可避免层层判断
动态 import 实现按需加载
import()函数,传入资源路径,返回结果为 promise 对象
BigInt 用于大整数数值运算
在普通数字后加一个 n 即为大整型
转换为此类型方法 BigInt(),只能传入整数
不能与普通整数做运算,需要把普通整数转换为 BigInt 类型
globalThis 全局的 this,始终指向全局对象