【Web】ES6学习笔记
目录
- 第1章 ECMASript 相关介绍
- 1.1.什么是 ECMA
- 1.2.什么是 ECMAScript
- 1.3.谁在维护 ECMA-262
- 1.4.为什么要学习 ES6
- 第 2 章 ECMASript 6 新特性
- 2.1.let 关键字
- 2.2. const 关键字
- let-实践案例
- 2.3.变量的解构赋值
- 2.4.模板字符串
- 2.5.简化对象写法
- 2.6.箭头函数
- 箭头函数的使用场景
- 2.7. rest 参数
- 2.8. spread 扩展运算符
- 2.9.Symbol
- 2.9.1.Symbol 基本使用
- 2.9.2.Symbol 内置值
- 2.10. 迭代器
- 2.11. 生成器
- 生成器函数实例
- 生成器函数实例2
- 2.12. Promise
- 2.13. Set
- 集合实践
- 2.14. Map
- 2.15. class 类
- 2.16. 数值扩展
- 2.16.1. 二进制和八进制
- 2.16.2. Number.isFinite() 与 Number.isNaN()
- 2.16.3. Number.parseInt() 与 Number.parseFloat()
- 2.16.4. Math.trunc
- 2.16.5. Number.isInteger
- 2.16.6. Math.sign
- 2.17. 对象扩展
- 2.17.1. Object.is
- 2.17.2. Object.assign
- 2.17.3. Object.setPrototypeOf
- 2.18. 模块化
- 2.18.1. 模块化的好处
- 2.18.2. 模块化规范产品
- 2.18.3. ES6 模块化语法
- 第 3 章 ECMASript 7 新特性
- 3.1.Array.prototype.includes
- 3.2.指数操作符
- 第 4 章 ECMASript 8 新特性
- 4.1.async 和 await
- 4.1.1.async 函数
- 4.1.2.await 表达式
- 4.1.3. -async和await结合读取文件
- 4.1.4. async和await封装AJAX请求
- 4.2.Object.values 和 Object.entries
- 第 5 章 ECMASript 9 新特性
- 5.1.Rest/Spread 属性
- 5.2.正则表达式命名捕获组
- 5.3.正则表达式反向断言
- 5.4.正则表达式 dotAll 模式
- 第 6 章 ECMASript 10 新特性
- 6.1.Object.fromEntries
- 6.2.trimStart 和 trimEnd
- 6.3.Array.prototype.flat 与 flatMap
- 6.4.Symbol.prototype.description
- 第 7 章 ECMASript 11 新特性
- 7.1.Promise.allSettled
- 7.2.类的私有属性
- 7.3.String.prototype.matchAll
- 7.4.可选链操作符
- 7.5.动态 import 导入
- 7.6.globalThis 对象
- 7.7.BigInt
第1章 ECMASript 相关介绍
1.1.什么是 ECMA
ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制
造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该
组织改名为 Ecma 国际。
1.2.什么是 ECMAScript
ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言。
1.3.谁在维护 ECMA-262
TC39(Technical Committee 39)是推进 ECMAScript 发展的委员会。其会员都是
公司(其中主要是浏览器厂商,有苹果、谷歌、微软、因特尔等)。TC39 定期
召开会议,会议由会员公司的代表与特邀专家出席
1.4.为什么要学习 ES6
⚫ ES6 的版本变动内容最多,具有里程碑意义
⚫ ES6 加入许多新的语法特性,编程实现更简单、高效
⚫ ES6 是前端发展趋势,就业必备技能
第 2 章 ECMASript 6 新特性
2.1.let 关键字
let a;let b,c,d;let e = 100;let f = 521, g = 'iloveyou', h = [];
let 关键字用来声明变量,使用 let 声明的变量有几个特点:
1)不允许重复声明
let star = '罗志祥';let star = '小猪'; //报错
- 块儿级作用域
if else while for {let girl = '周扬青';}console.log(girl); //报错
- 不存在变量提升
console.log(song);let song = '恋爱达人'; //报错
- 不影响作用域链
{let school = 'SHOOL';function fn(){console.log(school);}fn();}
应用场景:以后声明变量使用 let 就对了
2.2. const 关键字
const 关键字用来声明常量,const 声明有以下特点
const SCHOOL = 'SCHOOL';
- 声明必须赋初始值
const A; //报错
- 标识符一般为大写
const a = 100; //潜规则
- 不允许重复声明
const a = 100;const b = 200;` //报错
- 值不允许修改
SCHOOL = 'ATGUIGU'; //可以用作常数,如PI
- 块儿级作用域
{const PLAYER = 'UZI';}
- 对于数组和对象的元素修改, 不算做对常量的修改, 不会报错
const TEAM = ['UZI','MXLG','Ming','Letme'];TEAM.push('Meiko'); //不报错
let-实践案例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>点击 DIV 换色</title><link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css"rel="stylesheet"><style>.item {width: 100px;height: 50px;border: solid 1px rgb(42, 156, 156);float: left;margin-right: 10px;}</style>
</head><body><div class="container"><h2 class="page-header">点击切换颜色</h2><div class="item"></div><div class="item"></div><div class="item"></div></div><script>//获取div元素对象let items = document.getElementsByClassName('item');//遍历并绑定事件for(let i = 0;i<items.length;i++){items[i].onclick = function(){//修改当前元素的背景颜色// this.style.background = 'pink';items[i].style.background = 'pink';}}</script>
</body>
</html>
注意: 对象属性修改和数组元素变化不会出发 const 错误
应用场景:声明对象类型使用 const,非对象类型声明选择 let
2.3.变量的解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。
- 数组的解构
const F4 = ['小沈阳','刘能','赵四','宋小宝'];let [xiao, liu, zhao, song] = F4;console.log(xiao);console.log(liu);console.log(zhao);console.log(song);
- 对象的解构
const zhao = {name: '赵本山',age: '不详',xiaopin: function(){console.log("我可以演小品");}};let {name, age, xiaopin} = zhao;console.log(name);console.log(age);console.log(xiaopin);xiaopin();
let {xiaopin} = zhao;xiaopin();
注意:频繁使用对象方法、数组元素,就可以使用解构赋值形式
2.4.模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识,特点:
- 声明
let str = `我也是一个字符串哦!`;console.log(str, typeof str);
- 内容中可以直接出现换行符
let str = `<ul><li>沈腾</li><li>玛丽</li><li>魏翔</li><li>艾伦</li></ul>`;
输出也一样,带换行符:
- 变量拼接
let lovest = '魏翔';let out = `${lovest}是我心目中最搞笑的演员!!`;console.log(out);
2.5.简化对象写法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
let name = '大表哥';let change = function(){console.log('我可以改变你!!');}const school = {name,change,improve(){console.log("我可以提高你的技能");}}console.log(school);
注意:对象简写形式简化了代码,所以以后用简写就对了
2.6.箭头函数
ES6 允许使用「箭头」(=>)定义函数。
1.== 声明一个函数==
//普通函数let fn = function(a,b){return a + b;}//箭头函数let fn = (a,b) => {return a + b;}
- 调用函数
let result = fn(1, 2);console.log(result);
- this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值
function getName(){console.log(this.name);}//this指向这里let getName2 = () => {console.log(this.name);}//设置 window 对象的 name 属性window.name = '尚硅谷';const school = {name: "ATGUIGU"}//直接调用getName();getName2();//call 方法调用getName.call(school);//指向schoolgetName2.call(school); //始终指向window
- 不能作为构造实例化对象
let Person = (name, age) => {this.name = name;this.age = age;}let me = new Person('xiao',30);console.log(me);
- 不能使用 arguments 变量
let fn = () => {console.log(arguments);}fn(1,2,3);
- 箭头函数的简写
//1) 省略小括号, 当形参有且只有一个的时候let add = n => {return n + n;}
//2) 省略花括号, 当代码体只有一条语句的时候, 此时 return 必须省略let pow = n => n * n;console.log(pow(8));
注意:箭头函数不会更改 this 指向,用来指定回调函数会非常合适
箭头函数的使用场景
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>箭头函数实践</title><style>div {width: 200px;height: 200px;background: #58a;}</style>
</head>
<body><div id="ad"></div><script>//需求-1 点击 div 2s 后颜色变成『粉色』//获取元素let ad = document.getElementById('ad');//绑定事件ad.addEventListener("click", function(){//保存 this 的值// let _this = this;//定时器setTimeout(() => {//修改背景颜色 this// console.log(this);// _this.style.background = 'pink';this.style.background = 'pink';}, 2000);});//需求-2 从数组中返回偶数的元素const arr = [1,6,9,10,100,25];// const result = arr.filter(function(item){// if(item % 2 === 0){// return true;// }else{// return false;// }// });const result = arr.filter(item => item % 2 === 0);console.log(result);// 箭头函数适合与 this 无关的回调. 定时器, 数组的方法回调// 箭头函数不适合与 this 有关的回调. 事件回调, 对象的方法</script>
</body></html>
2.7. rest 参数
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
ES5 获取实参的方式
function date(){console.log(arguments);}date('白芷','阿娇','思慧');
- rest 参数
function date(...args){console.log(args);// filter some every map }date('阿娇','柏芝','思慧');
- rest 参数必须要放到参数最后
function fn(a,b,...args){console.log(a);console.log(b);console.log(args);}fn(1,2,3,4,5,6);
注意:rest 参数非常适合不定个数参数函数的场景
2.8. spread 扩展运算符
扩展运算符(spread)也是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。
//声明一个数组 ...const tfboys = ['德玛西亚之力','德玛西亚之翼','德玛西亚皇子'];// 声明一个函数function chunwan(){console.log(arguments);}chunwan(...tfboys);// chunwan('易烊千玺','王源','王俊凯')//展开对象let skillOne = {q: '致命打击',};let skillTwo = {w: '勇气'};let skillThree = {e: '审判'};let skillFour = {r: '德玛西亚正义'};let gailun = {...skillOne, ...skillTwo,...skillThree,...skillFour};
2.9.Symbol
2.9.1.Symbol 基本使用
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
- Symbol 的值是唯一的,用来解决命名冲突的问题
//创建Symbollet s = Symbol();// console.log(s, typeof s);let s2 = Symbol('张三');let s3 = Symbol('张三');//Symbol.for 创建let s4 = Symbol.for('李四');let s5 = Symbol.for('李四');
- Symbol 值不能与其他数据进行运算
let result = s + 100; //报错let result = s > 100;let result = s + s;
- 七大数据类型(复习)
// USONB you are so niubility u undefineds string s symbolo objectn null n numberb boolean
2.9.2.Symbol 内置值
除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行。
方法 | 作用 |
---|---|
Symbol.hasInstance | 当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法 |
Symbol.isConcatSpreadable | 对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于 Array.prototype.concat()时,是否可以展开。 |
Symbol.species | 创建衍生对象时,会使用该属性 |
Symbol.match | 当执行 str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值。 |
Symbol.replace | 当该对象被 str.replace(myObject)方法调用时,会返回该方法的返回值。 |
Symbol.search | 当该对象被 str.search (myObject)方法调用时,会返回该方法的返回值。 |
Symbol.split | 当该对象被 str.split(myObject)方法调用时,会返回该方法的返回值。 |
Symbol.iterator | 对象进行 for…of 循环时,会调用 Symbol.iterator 方法,返回该对象的默认遍历器。 |
Symbol.toPrimitive | 该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。 |
Symbol. toStringTag | 在该对象上面调用 toString 方法时,返回该方法的返回值 |
Symbol. unscopables | 该对象指定了使用 with 关键字时,哪些属性会被 with环境排除。 |
2.10. 迭代器
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
- ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费
//声明一个数组const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];//使用 for...of 遍历数组for(let v of xiyou){console.log(v);}let iterator = xiyou[Symbol.iterator]();//调用对象的next方法console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());
- 原生具备 iterator 接口的数据(可用 for of 遍历)
a) Array
b) Arguments
c) Set
d) Map
e) String
f) TypedArray
g) NodeList
- 工作原理(迭代器自定义遍历数据)
a) 创建一个指针对象,指向当前数据结构的起始位置
b) 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
c) 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
d) 每调用 next 方法返回一个包含 value 和 done 属性的对象
//声明一个对象const banji = {name: "终极一班",stus: ['xiaoming','xiaoning','xiaotian','knight'],[Symbol.iterator]() {//索引变量let index = 0;//let _this = this;return {next: function () {if (index < _this.stus.length) {const result = { value: _this.stus[index], done: false };//下标自增index++;//返回结果return result;}else{return {value: undefined, done: true};}}};}}//遍历这个对象 for (let v of banji) {console.log(v);}
注: 需要自定义遍历数据的时候,要想到迭代器。
2.11. 生成器
生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。
- * 的位置没有限制
- 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到
yield 语句后的值
//生成器其实就是一个特殊的函数//异步编程 纯回调函数 node fs ajax mongodb//函数代码的分隔符function * gen(){// console.log(111);yield '一只没有耳朵';// console.log(222);yield '一只没有尾部';// console.log(333);yield '真奇怪';// console.log(444);}let iterator = gen();console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());//遍历// for(let v of gen()){// console.log(v);//}
- yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next
方法,执行一段代码 - next 方法可以传递实参,作为 yield 语句的返回值
function * gen(arg){console.log(arg);let one = yield 111;console.log(one);let two = yield 222;console.log(two);let three = yield 333;console.log(three);}//执行获取迭代器对象let iterator = gen('AAA');console.log(iterator.next());//next方法可以传入实参console.log(iterator.next('BBB'));//第二个next传入的参数作为第一个yield的返回结果console.log(iterator.next('CCC'));//第三个next传入的参数作为第二个yield的返回结果console.log(iterator.next('DDD'));//第四个next传入的参数作为第三个yield的返回结果
生成器函数实例
// 异步编程 文件操作 网络操作(ajax, request) 数据库操作// 1s 后控制台输出 111 2s后输出 222 3s后输出 333 // 回调地狱//setTimeout(() => {//console.log(111);//setTimeout(() => {//console.log(222);//setTimeout(() => {//console.log(333);//}, 3000);//}, 2000);//}, 1000);function one(){setTimeout(()=>{console.log(111);iterator.next();//回调},1000)}function two(){setTimeout(()=>{console.log(222);iterator.next();},1000)}function three(){setTimeout(()=>{console.log(333);iterator.next();//回调},1000)}function * gen(){yield one();yield two();yield three();//回调}//调用生成器函数let iterator = gen();iterator.next();
生成器函数实例2
//模拟获取 用户数据 订单数据 商品数据 function getUsers(){setTimeout(()=>{let data = '用户数据';//调用 next 方法, 并且将数据传入iterator.next(data);}, 1000);}function getOrders(){setTimeout(()=>{let data = '订单数据';iterator.next(data);}, 1000)}function getGoods(){setTimeout(()=>{let data = '商品数据';iterator.next(data);}, 1000)}function * gen(){let users = yield getUsers();let orders = yield getOrders();let goods = yield getGoods();}//调用生成器函数let iterator = gen();iterator.next();
2.12. Promise
Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
- 基本使用
//实例化 Promise 对象const p = new Promise(function(resolve, reject){ //实例化Promise对象要传入一个参数,参数为一个函数,该函数的参数是resolve和reject,分别代表正常和异常的状态 setTimeout(function(){//// let data = '数据库中的用户数据';// resolve// resolve(data);let err = '数据读取失败';reject(err);}, 1000);});//调用 promise 对象的 then 方法p.then(function(value){ //返回resolve调用这个函数console.log(value);}, function(reason){ //返回reason调用这个函数console.error(reason); })
- Promise封装读取文件
//1. 引入 fs 模块const fs = require('fs');//2. 调用方法读取文件
// fs.readFile('./resources/为学.md', (err, data)=>{// //如果失败, 则抛出错误
// if(err) throw err;
// //如果没有出错, 则输出内容
// console.log(data.toString());
// });//3. 使用 Promise 封装const p = new Promise(function(resolve, reject){fs.readFile("./resources/为学.mda", (err, data)=>{//判断如果失败if(err) reject(err);//如果成功resolve(data);});});p.then(function(value){console.log(value.toString());}, function(reason){console.log("读取失败!!");});
- Promise封装AJAX
// 接口地址: https://api.apiopen.top/getJokeconst p = new Promise((resolve, reject) => {//1. 创建对象const xhr = new XMLHttpRequest();//2. 初始化xhr.open("GET", "https://api.apiopen.top/getJ");//3. 发送xhr.send();//4. 绑定事件, 处理响应结果xhr.onreadystatechange = function () {//判断if (xhr.readyState === 4) {//判断响应状态码 200-299if (xhr.status >= 200 && xhr.status < 300) {//表示成功resolve(xhr.response);} else {//如果失败reject(xhr.status);}}}})//指定回调p.then(function(value){console.log(value);}, function(reason){console.error(reason);});
- Promise.prototype.then 方法
//创建 promise 对象const p = new Promise((resolve, reject)=>{setTimeout(()=>{resolve('用户数据');// reject('出错啦');}, 1000)});//调用 then 方法 then方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果决定//1. 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值//2. 如果回调函数中返回的结果是 promise 类型的属性, 返回值为该 promise 返回的状态//3. 如果回调函数中返回的结果是抛出错误, 返回状态是失败const result = p.then(value => {console.log(value);//1. 非 promise 类型的属性return 'iloveyou';//2. 是 promise 对象return new Promise((resolve, reject)=>{resolve('ok');//reject('error');});//3. 抛出错误throw new Error('出错啦!');throw '出错啦!';}, reason=>{console.warn(reason);});//链式调用p.then(value=>{}).then(value=>{});
- Promise读取多个文件
//引入 fs 模块const fs = require("fs");// fs.readFile('./resources/为学.md', (err, data1)=>{// fs.readFile('./resources/插秧诗.md', (err, data2)=>{// fs.readFile('./resources/观书有感.md', (err, data3)=>{// let result = data1 + '\r\n' +data2 +'\r\n'+ data3;// console.log(result);// });// });// });//使用 promise 实现const p = new Promise((resolve, reject) => {fs.readFile("./resources/为学.md", (err, data) => {resolve(data);});});p.then(value => {return new Promise((resolve, reject) => {fs.readFile("./resources/插秧诗.md", (err, data) => {resolve([value, data]);});});}).then(value => {return new Promise((resolve, reject) => {fs.readFile("./resources/观书有感.md", (err, data) => {//压入value.push(data);resolve(value);});})}).then(value => {console.log(value.join('\r\n'));});
- Promise对象的catch方法
const p = new Promise((resolve, reject)=>{setTimeout(()=>{//设置 p 对象的状态为失败, 并设置失败的值reject("出错啦!");}, 1000)});// p.then(function(value){}, function(reason){// console.error(reason);// });p.catch(function(reason){console.warn(reason);});
2.13. Set
ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,集合的属性和方法:
- size 返回集合的元素个数
- add 增加一个新元素,返回当前集合
- delete 删除元素,返回 boolean 值
- has 检测集合中是否包含某个元素,返回 boolean 值
- clear 清空集合,返回 undefined
//声明一个 setlet s = new Set();let s2 = new Set(['大事儿','小事儿','好事儿','坏事儿','小事儿']);//元素个数console.log(s2.size);//添加新的元素s2.add('喜事儿');//删除元素s2.delete('坏事儿');//检测console.log(s2.has('糟心事'));//清空s2.clear();console.log(s2);for(let v of s2){console.log(v);}
集合实践
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,5,6];// let result = [...new Set(arr)].filter(item => {// let s2 = new Set(arr2);// 4 5 6// if(s2.has(item)){// return true;// }else{// return false;// }// });// let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));// console.log(result);//3. 并集// let union = [...new Set([...arr, ...arr2])];// console.log(union);//4. 差集let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));console.log(diff);
2.14. Map
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。Map 的属性和方法:
- size 返回 Map 的元素个数
- set 增加一个新元素,返回当前 Map
- get 返回键名对象的键值
- has 检测 Map 中是否包含某个元素,返回 boolean 值
- clear 清空集合,返回 undefined
//声明 Maplet m = new Map();//添加元素m.set('name','上官');m.set('change', function(){console.log("我们可以改变你!!");});let key = {school : 'ATGUIGU'};m.set(key, ['北京','上海','深圳']);//size// console.log(m.size);//删除// m.delete('name');//获取// console.log(m.get('change'));// console.log(m.get(key));//清空// m.clear();//遍历for(let v of m){console.log(v);}// console.log(m);
2.15. class 类
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对
象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是
一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象
原型的写法更加清晰、更像面向对象编程的语法而已。
ES5定义类相关操作:
//手机function Phone(brand, price){this.brand = brand;this.price = price;}//添加方法Phone.prototype.call = function(){console.log("我可以打电话!!");}//实例化对象let Huawei = new Phone('华为', 5999);Huawei.call();console.log(Huawei);
ES6定义类相关操作:
- class 声明类
- constructor 定义构造函数初始化
//classclass Shouji{//构造方法 名字不能修改constructor(brand, price){this.brand = brand;this.price = price;}//方法必须使用该语法, 不能使用 ES5 的对象完整形式call(){console.log("我可以打电话!!");}}let onePlus = new Shouji("1+", 1999);console.log(onePlus);
- extends 继承父类(ES6)
- super 调用父级构造方法
ES5语法:
//手机function Phone(brand, price){this.brand = brand;this.price = price;}Phone.prototype.call = function(){console.log("我可以打电话");}//智能手机function SmartPhone(brand, price, color, size){Phone.call(this, brand, price);this.color = color;this.size = size;}//设置子级构造函数的原型SmartPhone.prototype = new Phone;SmartPhone.prototype.constructor = SmartPhone;//声明子类的方法SmartPhone.prototype.photo = function(){console.log("我可以拍照")}SmartPhone.prototype.playGame = function(){console.log("我可以玩游戏");}const chuizi = new SmartPhone('锤子',2499,'黑色','5.5inch');console.log(chuizi);
ES6语法:
class Phone{//构造方法constructor(brand, price){this.brand = brand;this.price = price;}//父类的成员属性call(){console.log("我可以打电话!!");}}class SmartPhone extends Phone {//构造方法constructor(brand, price, color, size){super(brand, price);// Phone.call(this, brand, price)this.color = color;this.size = size;}photo(){console.log("拍照");}playGame(){console.log("玩游戏");}call(){console.log('我可以进行视频通话');}}const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');// console.log(xiaomi);xiaomi.call();xiaomi.photo();xiaomi.playGame();
- static 定义静态方法和属性
class Phone{//静态属性static name = '手机';static change(){console.log("我可以改变世界");}}let nokia = new Phone();console.log(nokia.name); //不可访问console.log(Phone.name); //可访问
- 父类方法可以重写
//父类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('诺基亚', '灰色', 230);const iPhone6s = new SmartPhone('苹果', '白色', 6088, '4.7inch','500w');//调用子类方法iPhone6s.playGame();//调用重写方法iPhone6s.call();//调用静态方法SmartPhone.run();
2.16. 数值扩展
2.16.1. 二进制和八进制
ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示。
//二进制和八进制let b = 0b1010;let o = 0o777;let d = 100;let x = 0xff;console.log(x); //255
2.16.2. Number.isFinite() 与 Number.isNaN()
Number.isFinite() 用来检查一个数值是否为有限的
Number.isNaN() 用来检查一个值是否为 NaN
//Number.isFinite 检测一个数值是否为有限数console.log(Number.isFinite(100));console.log(Number.isFinite(100/0));console.log(Number.isFinite(Infinity));//Number.isNaN 检测一个数值是否为 NaN console.log(Number.isNaN(123));
2.16.3. Number.parseInt() 与 Number.parseFloat()
ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变。
//Number.parseInt Number.parseFloat字符串转整数console.log(Number.parseInt('5211314love'));console.log(Number.parseFloat('3.1415926神奇'));
2.16.4. Math.trunc
用于去除一个数的小数部分,返回整数部分。
//Math.trunc 将数字的小数部分抹掉 console.log(Math.trunc(3.5));
2.16.5. Number.isInteger
Number.isInteger() 用来判断一个数值是否为整数
//5. Number.isInteger 判断一个数是否为整数console.log(Number.isInteger(5));console.log(Number.isInteger(2.5));
2.16.6. Math.sign
//Math.sign 判断一个数到底为正数 负数 还是零console.log(Math.sign(100));console.log(Math.sign(0));console.log(Math.sign(-20000));
2.17. 对象扩展
2.17.1. Object.is
//Object.is 判断两个值是否完全相等 console.log(Object.is(120, 120));// === console.log(Object.is(NaN, NaN));// === console.log(NaN === NaN);// ===
2.17.2. Object.assign
//Object.assign 对象的合并const config1 = {host: 'localhost',port: 3306,name: 'root',pass: 'root',test: 'test'};const config2 = {host: 'http://atguigu.com',port: 33060,name: 'atguigu.com',pass: 'iloveyou',test2: 'test2'}console.log(Object.assign(config1, config2)); //出现重名,后面参数属性覆盖前面
2.17.3. Object.setPrototypeOf
//Object.setPrototypeOf 设置原型对象const school = {name: '上官'}const cities = {xiaoqu: ['北京','上海','深圳']}Object.setPrototypeOf(school, cities);console.log(Object.getPrototypeOf(school));console.log(school);
2.18. 模块化
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
2.18.1. 模块化的好处
模块化的优势有以下几点:
- 防止命名冲突
- 代码复用
- 高维护性
2.18.2. 模块化规范产品
ES6 之前的模块化规范有:
- CommonJS => NodeJS、Browserify
- AMD => requireJS
- CMD => seaJS
2.18.3. ES6 模块化语法
模块功能主要由两个命令构成:export 和 import。
⚫ export 命令用于规定模块的对外接口
⚫ import 命令用于输入其他模块提供的功能
以下分别为三个独立的js文件:
1. 分别暴露
//分别暴露export let school = '上官';export function teach() {console.log("我们可以教给你开发技能");}
2. 统一暴露
//统一暴露let school = '上官';function findJob(){console.log("我们可以帮助你找工作!!");}//export {school, findJob};
3. 默认暴露
//默认暴露export default {school: 'ATSHANGGUAN',change: function(){console.log("我们可以改变你!!");}}
以下为html模块导入方式:(导入后可直接使用模块中的相关元素)
<script type="module">//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 shangguan, findJob} from "./src/js/m2.js";//as重命名import {default as m3} from "./src/js/m3.js";//3. 简便形式 针对默认暴露import m3 from "./src/js/m3.js";console.log(m3);
</script>
<script src="./src/js/app.js" type="module"></script>
以上为单独导入模块的方式,下面将介绍引入NPM包进行导入,本次打包上面单独打包的三个文件:
//入口文件//模块引入import * as m1 from "./m1.js";import * as m2 from "./m2.js";import * as m3 from "./m3.js";console.log(m1);console.log(m2);console.log(m3);m1.teach();m2.findJob();m3.default.change();//修改背景颜色为粉色import $ from 'jquery';// const $ = require("jquery");$('body').css('background','pink');
引入html之前的准备工作:
- 安装工具 npm i babel-cli babel-preset-env browserify(webpack) -D
- 编译 npx babel src/js -d dist/js --presets=babel-preset-env(babel进行格式转换)
- 打包 npx browserify dist/js/app.js -o dist/bundle.js
一番操作过后会在该目录下生成 dist/bundle.js 文件,在html中引入:
<script src="dist/bundle.js"></script>
即可使用该包中的所有元素。
第 3 章 ECMASript 7 新特性
3.1.Array.prototype.includes
Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值
// includes indexOf// const mingzhu = ['西游记','红楼梦','三国演义','水浒传'];//判断console.log(mingzhu.includes('西游记'));console.log(mingzhu.includes('金瓶梅'));
3.2.指数操作符
// **console.log(2 ** 10); //2的10次方console.log(Math.pow(2, 10));
第 4 章 ECMASript 8 新特性
4.1.async 和 await
async 和 await 两种语法结合可以让异步代码像同步代码一样
4.1.1.async 函数
- async 函数的返回值为 promise 对象
- promise 对象的结果由 async 函数执行的返回值决定
//async 函数async function fn(){// 返回一个字符串// return '上官';// 返回的结果不是一个 Promise 类型的对象, 返回的结果就是成功 Promise 对象// return;//抛出错误, 返回的结果是一个失败的 Promise// throw new Error('出错啦!');//返回的结果如果是一个 Promise 对象return new Promise((resolve, reject)=>{resolve('成功的数据');// reject("失败的错误");});}const result = fn();//调用 then 方法result.then(value => {console.log(value);}, reason => {console.warn(reason);})
4.1.2.await 表达式
- await 必须写在 async 函数中
- await 右侧的表达式一般为 promise 对象
- await 返回的是 promise 成功的值
- await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理
//创建 promise 对象const p = new Promise((resolve, reject) => {// resolve("用户数据");reject("失败啦!");})// await 要放在 async 函数中.async function main() {try {let result = await p;//console.log(result);} catch (e) {console.log(e);}}//调用函数main();
4.1.3. -async和await结合读取文件
//1. 引入 fs 模块const fs = require("fs");//读取『为学』function readWeiXue() {return new Promise((resolve, reject) => {fs.readFile("./resources/为学.md", (err, data) => {//如果失败if (err) reject(err);//如果成功resolve(data);})})}function readChaYangShi() {return new Promise((resolve, reject) => {fs.readFile("./resources/插秧诗.md", (err, data) => {//如果失败if (err) reject(err);//如果成功resolve(data);})})}function readGuanShu() {return new Promise((resolve, reject) => {fs.readFile("./resources/观书有感.md", (err, data) => {//如果失败if (err) reject(err);//如果成功resolve(data);})})}//声明一个 async 函数async function main(){//获取为学内容let weixue = await readWeiXue();//获取插秧诗内容let chayang = await readChaYangShi();// 获取观书有感let guanshu = await readGuanShu();console.log(weixue.toString());console.log(chayang.toString());console.log(guanshu.toString());}main();
4.1.4. async和await封装AJAX请求
// 发送 AJAX 请求, 返回的结果是 Promise 对象function sendAJAX(url) {return new Promise((resolve, reject) => {//1. 创建对象const x = new XMLHttpRequest();//2. 初始化x.open('GET', url);//3. 发送x.send();//4. 事件绑定x.onreadystatechange = function () {if (x.readyState === 4) {if (x.status >= 200 && x.status < 300) {//成功啦resolve(x.response);}else{//如果失败reject(x.status);}}}})}//promise then 方法测试// sendAJAX("https://api.apiopen.top/getJoke").then(value=>{// console.log(value);// }, reason=>{})// async 与 await 测试 axiosasync function main(){//发送 AJAX 请求let result = await sendAJAX("https://api.apiopen.top/getJoke");//再次测试let tianqi = await sendAJAX('https://www.tianqiapi.com/api/?version=v1&city=%E5%8C%97%E4%BA%AC&appid=23941491&appsecret=TXoD5e8P')console.log(tianqi);}main();
4.2.Object.values 和 Object.entries
- Object.values()方法返回一个给定对象的所有可枚举属性值的数组
- Object.entries()方法返回一个给定对象自身可遍历属性 [key,value] 的数组
//声明对象const school = {name:"尚硅谷",cities:['北京','上海','深圳'],xueke: ['前端','Java','大数据','运维']};//获取对象所有的键console.log(Object.keys(school));//获取对象所有的值console.log(Object.values(school));//entriesconsole.log(Object.entries(school));//创建 Mapconst m = new Map(Object.entries(school));console.log(m.get('cities'));//对象属性的描述对象console.log(Object.getOwnPropertyDescriptors(school));const obj = Object.create(null, {name: {//设置值value: '尚硅谷',//属性特性writable: true,configurable: true,enumerable: true} });
第 5 章 ECMASript 9 新特性
5.1.Rest/Spread 属性
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
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'});
5.2.正则表达式命名捕获组
ES9 允许命名捕获组使用符号『?』,这样获取捕获结果可读性更强
let str = '<a href="http://www.shangguan.com">上官</a>';const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;const result = reg.exec(str);console.log(result.groups.url);console.log(result.groups.text);
5.3.正则表达式反向断言
ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选。
//声明字符串let str = 'JS5211314 你知道么 555 啦啦啦';//正向断言const reg = /\d+(?=啦)/;const result = reg.exec(str);//反向断言const reg = /(?<=么)\d+/;const result = reg.exec(str);console.log(result);
5.4.正则表达式 dotAll 模式
正则表达式中点.匹配除回车外的任何单字符,标记『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);
第 6 章 ECMASript 10 新特性
6.1.Object.fromEntries
Object.fromEntries 方法用来创建一个对象,接收的参数是二维数组或者Map
const result = Object.fromEntries([['name','黑马'],['xueke', 'Java,大数据,前端,云计算']]);console.log(result);
const m = new Map();m.set('name','ATGUIGU');const result1 = Object.fromEntries(m);console.log(result1);
const arr = Object.entries({name: "尚硅谷"})console.log(arr);
6.2.trimStart 和 trimEnd
trimStart 方法用来删除字符串之前的空格,trimEnd 用来删除字符串后面的空格
let str = ' iloveyou ';console.log(str);console.log(str.trimStart());console.log(str.trimEnd());
6.3.Array.prototype.flat 与 flatMap
Array.prototype.flat 方法用于将二维数组降维,转化为一维数组,方法的参数可以是深度,可控制降维深度,flatMap 方法既可以降维,又可以对被操作的对象进行加工返回
//flat 平//将多维数组转化为低位数组const arr = [1,2,3,4,[5,6]];const arr = [1,2,3,4,[5,6,[7,8,9]]];//参数为深度 是一个数字console.log(arr.flat(2)); //flatMapconst arr = [1,2,3,4];const result = arr.flatMap(item => [item * 10]);console.log(result);
6.4.Symbol.prototype.description
Symbol.prototype.description 方法用来获取 Symbol 的字符串描述
//创建 Symbollet s = Symbol('尚硅谷');console.log(s.description);
第 7 章 ECMASript 11 新特性
7.1.Promise.allSettled
Promise.allSettled 方法接收一个Promise数组,返回一个Promise对象,并且返回的状态永远是成功的
//声明两个promise对象const p1 = new Promise((resolve, reject)=>{setTimeout(()=>{resolve('商品数据 - 1');},1000)});const p2 = new Promise((resolve, reject)=>{setTimeout(()=>{resolve('商品数据 - 2');// reject('出错啦!');},1000)});//调用 allsettled 方法const result = Promise.allSettled([p1, p2]);const res = Promise.all([p1, p2]);console.log(res);
7.2.类的私有属性
类似Java,类外不能直接访问,只能通过方法内部封装调用访问
class Person{//公有属性name;//私有属性#age;#weight;//构造方法constructor(name, age, weight){this.name = name;this.#age = age;this.#weight = weight;}intro(){console.log(this.name);console.log(this.#age);console.log(this.#weight);}}//实例化const girl = new Person('晓红', 18, '45kg');// console.log(girl.name);// console.log(girl.#age);// console.log(girl.#weight);girl.intro();
7.3.String.prototype.matchAll
String.prototype.matchAll 方法用来获得正则批量匹配的结果,可以将匹配对象,匹配结果按照数组的方式匹配出来
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>/sg//调用方法const result = str.matchAll(reg);// for(let v of result){// console.log(v);// }const arr = [...result];//返回匹配结果为可迭代对象,既可以用for...of遍历,也可以用扩展运算符进行展开console.log(arr);
7.4.可选链操作符
这个可以省区多层级获取对象属性的判断流程
// ?.function main(config){// const dbHost = config && config.db && config.db.host;const dbHost = config?.db?.host;console.log(dbHost);}main({db: {host:'192.168.1.100',username: 'root'},cache: {host: '192.168.1.200',username:'admin'}})
7.5.动态 import 导入
export function hello(){alert('Hello');}
// import * as m1 from "./hello.js";//获取元素const btn = document.getElementById('btn');btn.onclick = function(){import('./hello.js').then(module => {module.hello();});}
7.6.globalThis 对象
globalThis 指向全局对象,可以对全局对象进行操作
console.log(globalThis); //global(node.js)或者window(html)
7.7.BigInt
//大整形// let n = 521n;// console.log(n, typeof(n)); //bigint类型//函数let n = 123;console.log(BigInt(n));console.log(BigInt(1.2));//报错//大数值运算let max = Number.MAX_SAFE_INTEGER; //最大安全整数console.log(max);console.log(max + 1); console.log(max + 2); //不变,已经很大了console.log(BigInt(max))console.log(BigInt(max) + BigInt(1))console.log(BigInt(max) + BigInt(2)) //变化
【Web】ES6学习笔记相关推荐
- es6学习笔记-顶层对象_v1.0_byKL
es6学习笔记-顶层对象_v1.0 (虽然是笔记,但是基本是抄了一次ruan大师的文章了) 顶层对象 顶层对象,在浏览器环境指的是window对象,在Node指的是global对象. ES5之中,顶层 ...
- es6学习笔记-字符串的扩展_v1.0_byKL
es6学习笔记-字符串的扩展_v1.0 字符的Unicode表示法 JavaScript 允许使用uxxxx的形式表示一个字符,但在 ES6 之前,单个码点仅支持u0000到uFFFF,超出该范围的必 ...
- ES6学习笔记(五):轻松了解ES6的内置扩展对象
前面分享了四篇有关ES6相关的技术,如想了解更多,可以查看以下连接 <ES6学习笔记(一):轻松搞懂面向对象编程.类和对象> <ES6学习笔记(二):教你玩转类的继承和类的对象> ...
- ES6学习笔记(三):教你用js面向对象思维来实现 tab栏增删改查功能
前两篇文章主要介绍了类和对象.类的继承,如果想了解更多理论请查阅<ES6学习笔记(一):轻松搞懂面向对象编程.类和对象>.<ES6学习笔记(二):教你玩转类的继承和类的对象>, ...
- ES6学习笔记04:Set与Map
ES6学习笔记04:Set与Map JS原有两种数据结构:Array与Object,ES6新增两种数据结构:Set与Map 一.Set数据结构 Set类似于数组,但是成员值不允许重复,因此主要用于数据 ...
- ES6学习笔记03:变量的解构赋值
ES6学习笔记03:变量的解构赋值 如果想从复杂数据结构(数组.对象)中获取某一个数据,可能需要大量的遍历操作才能完成.通过解构赋值,这一过程可以得到简化. 1.字符串的解构赋值 其实,Python也 ...
- ES6学习笔记02:let 与 const
ES6学习笔记02:let 与 const 用var声明的变量会造成全局污染,于是就产生了新的声明方式. 1.let 用let声明变量,必须先声明后使用. 在for循环头里用let定义循环变量i,那么 ...
- ES6学习笔记01:Symbol数据类型
ES6学习笔记01:Symbol数据类型 1.Symbol定义 浏览demo01.html: 2.Symbol作对象属性名 Symbol函数可以接收一个字符串作为参数,表示对Symbol实例的描述,输 ...
- Web Components 学习笔记一: Web Components是什么?解决了什么问题?
公众号:妙蛙种子前端 文章原文地址:Web Components笔记一: Web Components是什么?解决了什么问题? | 妙蛙种子 - 记录WEB前端技术学习成长过程的博客 Web Comp ...
- Java web与web gis学习笔记(二)——百度地图API调用
系列链接: Java web与web gis学习笔记(一)--Tomcat环境搭建 Java web与web gis学习笔记(二)--百度地图API调用 JavaWeb和WebGIS学习笔记(三)-- ...
最新文章
- golang 短连接和长连接 超时处理
- Linux下Openssl的安装全过程
- Fiori Launchpad Tile点击后跳转的调试技巧
- Google Guava BloomFilter
- 手动创建线程更好哦_如何通过创建更好的工作流程找到下一个大想法
- coreos 搭建PHP,Linux_用Mac在CoreOS上搭建WordPress的教程,作者以自己的Mac笔记本为例, - phpStudy...
- TCP慢开始与拥塞避免
- MAC版文本编辑(记事本),连显示行号的功能都没有
- java 64位时间戳转换32位时间戳
- HTTP代理socks5哪个快
- w ndows10隐藏桌面设置,Win10双击桌面隐藏/显示图标?这个可以有
- excel文件损坏修复绝招_修复数据工具大盘点,让你快速掌握电脑数据恢复的秘密武器...
- python与开源gis空间分析_Python 与开源GIS:数据处理、空间分析与地图制图
- mac安装正在计算机,出现“无法在计算机上安装macOS”错误时该怎么办?
- 阿里云,AWS和DigitalOcean:云服务比较
- Star Way To Heaven 二分 + 并查集 + Prime
- 第五人格服务器维护中请稍后登录,第五人格:国际服维护重大故障,刚开精华二,却登录不了游戏...
- 阿里云视频点播相关代码
- 大数据的3V特性, 种类, 总量, 速度。
- openwrt 开启软看门狗
热门文章
- iviewui ajax,中后台UI库使用对比:Element/iview
- 滴滴云「于某声」在「服务器采购过程中」受贿累计超过 1000 万元:已移交公安机关
- [组件笔记]7.UnityEngine.MonoBehaviour
- [Machine Check机制]X86服务器Linux系统对于MCE的Log解析
- Greenplum 优化 - 分布式键,重建索引,序列
- Hacking Team泄露数据表明韩国、哈萨克斯坦针对中国发起网络攻击
- 低代码平台要怎么选?便宜其实也有好货!
- 圣诞树小程序,动态效果,八个小程序
- Redis Cluster集群节点间通信
- 程序员公司实行996,加班费却只有10块!网友:我们20块