学习计划
学习日志之ES6(完结)
2020/12/27一2021/1/19
用时24天
-
2020/12/27 es6 P27-P29
-
Promise
const P = new Promise((resolve,reject)=>{ settimeout(()=>{ resolve('用户数据');//成功 //reject('程序出错');//错误 },1000); }); //调用then()方法 //then()包含两个方法参数{1.当成功(resolve)时运行value方法2.当失败(reject)时运行reason方法}且赋值 P.then(value=>{ console.log(value); },reason=>{ console.error(reason); }); //调用catch()方法 //catch()与then()类似,但then()包含成功(value)和失败(reason)两个参数,而cantch()只有失败参数(reason) P.catch(reason=>{ console.error(reason); });
-
2020/12/29 es6 P30-P31
-
Set
//Set基本语法及属性 //去重性 const a = new Set(['张三','李四','王五','张三']);//'张三','李四','王五' const b = new Set(['111','222']); //向集合中添加一个对象 a.add('张飞');//'张三','李四','王五','张飞' //向集合中删除一个对象 a.delete('张三');//'李四','王五','张飞' //查看集合中是否包含一个对象 a.has('李四');//true a.has('李逵');//false //清除一个集合 a.clear(); //遍历一个集合 for(let v of b){ console.log(v); //111 //222 }
//Set集合实践 //设置两组数组 let a = [1,2,3,5,6,6]; let b = [2,3,4,5,7]; //a数组去重 const result = new Set(a);//1,2,3,5,6 //a与b交集 const result2 = [...new Set(a)].filter(item => { let b2 = new Set(b); if(b2.has(item))return true; else return false; }); console.log(result);//2,3,5 //简写语法 const r2 = [...new Set(a)].filter(item => new Set(b).has(item));//2,3,5 //a与b并集 const result3 = [...new Set(...a,...b)];//1,2,3,4,5,6,7 //a与b差集 const r2 = [...new Set(a)].filter(item => !(new Set(b).has(item)));//1,4,6,7
-
2020/12/31 es6 P32-P34
-
Map
//Map的基本语法及使用 //声明一个Map let m = new Map(); //给Map m添加一个普通类型的元素 m.set('name','kjkjkl');//第一个参数为键值key,第二个参数为值value //给Map m 添加一个对象键值类型的元素,值为方法 let n = { sex:'男' } m.set(n,function(){ console.log('我是一个方法'); }); //删除Map中的一个元素 m.delete('name'); //获取Map中的一个键的值 m.get(n);//f(); //声明一个变量用作存储Map中n键值的方法 let f = m.get(n); f();
-
Class
//声明一个Class class Phone{ //constructor方法(每个类中有且只有一个constructor方法,该方法采用固定名称)即:构造函数方法 constructor(brand,price){ this.brand = brand; this.price = price; } //声明一个功能方法 vivo(){ console.log('我是一部vivo手机'); } iphoneX(){ console.log('我是一部iphoneX,我比vivo手机贵'); } } //vivo手机初始化 let vivo = new Phone('vivo',1999); vivo.vivo();//我是一部vivo手机 //苹果X初始化 let iphonex = new Phone('iphoneX',9999); iphonex.iphoneX();//我是一部iphoneX,我比vivo手机贵
//class静态成员 //声明一个class class Phone{ //声明静态变量name static name = 'kjkjkl'; //生命静态方法f() static f(){ console.log('test test test'); } } //初始化类 let p = new Phone(); console.log(Phone.name);//kjkjkl console.log(p.name);//undefined Phone.f();//test test test p.f();//直接报错 //结论:静态化变量,方法,对象无法被赋值给初始化的对象直接读取
-
2021/1/1 es6 p35-p38
//class之类的继承 //声明一个父类Phone class Phone{ constructor(brand,price){ this.brand = brand; this.price = price; } call(){ console.log('我可以打电话'); } } //声明一个子类SmartPhone //固定写法extends class SmartPhone extends Phone{ constructor(brand,price,color,size){ //继承 固定写法super super(brand,price); this.color = color; this.size = size; } //生成成员函数 Photo(){ console.log('我可以照相'); } PlayGame(){ console.log('我可以打游戏'); } //继承/重写成员函数call() call(){ console.log('我可以打视频电话'); } } //实例化对象 let p = new SmartPhone('vivo',1200,'black',6.3); p.Photo();//我可以照相 p.PlayGame();//我可与打游戏 p.call();//我可以打视频电话 console.log(p);//SmartPhone{vivo,1200,black,6.3}Photo:f();PlayGame:f();/Phone:call():f()
//class中getter和setter设置 //声明一个类Phone class Phone{ //设置price的get get price(){ console.log('价格属性被读取了'); return '返回结果'; } //设置price的set //set中至少要有一个参数 set price(newVal){ console.log('价格参数被修改了'); } //实例化对象 let s = new Phone(); s.price = 'free';//价格参数被修改了 console.log(s.price);//1.价格参数被读取了2.返回结果 } //结论:使用场景{get:处理动态数据}{set:多种条件处理}
-
2021/1/2 es6 p39-p40
//数值扩展 //1.Javascript的最小精度 Number.EPSILON console.log(0.1 + 0.2);//0.3000000000004 非0.3 function eq(a,b){ if(Math.abs(a + b) < Number.EPSILON){ return true; }else{ return false; } } console.log(eq(0.1 + 0.2,0.3));//true //2.二进制和八进制 console.log(0b1010);//10 console.log(0o777);//511 console.log(100);//100 console.log(0xff);//255 //3.检测一个数是否为有限数 Number.isFinite console.log(Number.isFinite(100));//true console.log(Number.isFinite(0));//true console.log(Number.isFinite(Infinity));//false //4.检测一个数值是否为NaN Number.isNaN console.log(Number.isNaN(123));//false console.log(Number.isNaN(123/'test'));//true //5.字符串转整数,字符串转浮点数 Number.ParseInt||Number.parseFloat console.log(Number.ParseInt('123abc'));//123 console.log(Number.ParseFloat('1.23a'));//1.23 //6.判断一个数是否为整数 Number.isInteger console.log(Number.isInteger(10));//true console.log(Number.isInteger(10.2));//false //7.将数字的小数部分抹掉 Math.trunc console.log(Math.trunc(10.2));//10 //8.判断一个数字为正数 负数 还是0 Math.sign console.log(Math.sign(100),Math.sign(-100),Math.sign(0));//1 -1 0
//对象方法扩展 //1.判断两个值是否完全相等 Object.is console.log(Object.is(1,1));//true; console.log(Object.is(1,0));//false; console.log(Object.is(NaN,NaN));//true; console.log(NaN === NaN);//false //2.对象的合并 Object.assign let Config1 = { host:'127.0.0.1', port:8080, uid:'kjkjkl', pwd:'123456', add:'test' } let Config2 = { host:'localhost', port:80, uid:'lmf', pwd:'123' } Object.assign(Config1,Config2);//第一个对象属性会被第二个对象属性覆盖 console.log(Config1);//{host:'localhost',port:80,uid:'lmf',pwd:'123',add:'test'} //3.设置原型对象 setPrototypeOf let s1 = { name:'kjkjkl' } let s2 = { game:['CF','LOL','MC'] } Object.setPrototypeOf(s1,s2); console.log(s);//{name:'kjkjkl',_proto_:Object(play:['CF','LOL','MC'])} //获取原型对象 getPrototypeOf //截取上面例子 console.log(getPrototypeOf(s));//play:['CF','LOL','MC'],_proto_:Object
-
2021/1/4 es6 模块化
-
导出模块 export
//分别暴露 export let name = 'm1'; export function test(){ console.log('这里是m1,分别暴露'); }
//统一暴露 let name = 'm2'; function test(){ console.log('这里是m2,统一暴露'); } export { name, test }
//默认暴露 export default { name: 'm3', test: function(){ console.log('这里是m3,默认暴露'); } }
-
导入模块 import
//通用导入方法 import * as m1 from './这里填写模块文件路径/m1.js'; import * as m2 from './这里填写模块文件路径/m2.js'; import * as m3 from './这里填写模块文件路径/m3.js'; m1.test();//这里是m1,分别暴露 m2.test();//这里是m2,统一暴露 m3.default.test();//这里是m3,默认暴露 默认暴露的固定写法,方法或变量前加default
//解构赋值形式 import {name as m1_name,test as m1_test} from './这里填写模块文件路径/m1.js'; import {name as m1_name,test as m1_test} from './这里填写模块文件路径/m2.js'; import {default as m3} from './这里填写模块文件路径/m3.js'; m1_test();//这里是m1,分别暴露 m2_test();//这里是m2,统一暴露 m3.test();//这里是m3,默认暴露 //注意:解构赋值形式导入默认暴露固定写法default后必须加as 别名
//简便导入方式 --- 只针对于默认暴露 import m3 from './这里填写模块文件路径/m3.js'; m3.test();//这里是m3,默认暴露
以上方式用于在html文件内导入 <script>必须有type="module"属性
在js文件内导入方式如下↓
index.html使用m1.js的test方法
//m1.js
export default {
name: 'm1';
test: function(){
console.log('test');
}
}
//app.js
import m1 from './路径/m1.js';
m1.test();
<!--index.html-->
<html>
<head>
<title>ES6模块化</title>
</head>
<body>
<!--test-->
<script scr='./路径/app.js' type="module"></script>
</body>
</html>
-
2021/1/6 es7 featrue
//includes 查看一个数组中是否包含一个元素 包含返回true,不包含返回false //includes与indexOf相同作用,返回值不一样 indexOf包含返回0,不包含返回-1 const sdmz = ['西游记','水浒传','三国演义','红楼梦']; //includes console.log(sdmz.includes('西游记'));//true console.log(sdmz.includes('道德经'));//false //indexOf console.log(sdmz.indexOf('西游记'));//0 console.log(sdmz.indexOf('道德经'));//-1 //幂运算 //正常情况下 console.log(Math.pow(2, 10));//1024 表示2的10次方 //ES7 console.log(2 ** 10);//1024
-
2021/1/9 es8 async和await
-
async
//async函数一般情况下用来返回Promise的值 //生成async类型的函数Main() const Main = async()=>{ return new Promise((resolve,reject)=>{ resolve('Success!'); reject('Error~'); }); } const result = Main(); result.then(value=>{ console.log(value); },reason=>{ console.error(reason); }); Main(); //控制台:Success!
-
await
//await一般包含在async函数里 //await返回的是Promise成功的值 const P = new Promise((resolve,reject)=>{ resolve('Success'); reject('Error'); }); const Main = async()=>{ try{ const result = await P; console.log(result); }catch(e){ console.error(e); } } Main(); //控制台:Success
-
2021/1/10 es8 async和await结合使用案例
#### 使用Promise方法以及async和await新特性通过node('fs')模块读取.md文件
test1.md test2.md test3.md
//大体解题思路: //获取test1.md const fs = require('fs'); function gettest1(){ return new Promise((resolve, reject)=>{ fs.readFile('路径/test1.md',(err,data)=>{ if(err)reject(err); resolve(data); }) }); } //获取test2.md function gettest2(){ return new Promise((resolve, reject)=>{ fs.readFile('路径/test2.md',(err,data)=>{ if(err)reject(err); resolve(data); }) }); } //获取test3.md function gettest3(){ return new Promise((resolve, reject)=>{ fs.readFile('路径/test3.md',(err,data)=>{ if(err)reject(err); resolve(data); }) }); } //读取数据 async function Main(){ const test1 = await gettest1(); const test2 = await gettest2(); const test3 = await gettest3(); //输出结果 console.log(test1);//test1 console.log(test2);//test2 console.log(test3);//test3 } //执行函数 Main();
通过async和await封装ajax请求
//定义ajax请求 function ajax(url){ return new Promise((resolve, reject)=>{ const xhr = new XMLHttpRquest(); xhr.open('GET',url); xhr.send(); xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ resolve(xhr.response); } } }); } //调用请求并传参 async function Main(){ const shi = await ajax('http://poetry.apiopen.top/sentences'); console.log(JSON.Parse(shi).result.name);//白日依山尽,黄河入海流。 } //调用函数Main Main();
-
2021/1/12 es8 对象方法扩展
Object.keys(object)返回一个对象的所有键,返回类型为数组
const kjkjkl = { id: '1001', pwd: '123456', address: '山东淄博' } console.log(Object.keys(kjkjkl));//Array['id','pwd','address']
Object.values(object)返回一个对象的所有值,返回类型为数组
const kjkjkl = { id: '1001', pwd: '123456', address: '山东淄博' } console.log(Object.values(kjkjkl));//Array['1001','123456','山东淄博']
Object.entries(object)返回一个对象的所有元素,类型为数组包含键与值
const kjkjkl = { id: '1001', pwd: '123456', address: '山东淄博' } console.log(Object.entries(kjkjkl));//[Array{"id","1001"},Array{"pwd","123456"},Array{"address","山东淄博"}] //放入Map const m = new Map(Object.entries(kjkjkl)); //取出键为id的值 console.log(m.get('id'));//1001
Object.getOwnPropertyDescriptors(object)对象属性的描述对象
const kjkjkl = { id: '1001', pwd: '123456', address: '山东淄博' } console.log(Object.getOwnPropertyDescriptors(kjkjkl));//{id:{...},pwd:{...},address:{...}} //ps:其中...为value,writable,enumerable,configurable固定四个属性 //value 值,比如id{values:'1001'} //writable 是否可写|默认为true //configurable 是否可以删除|默认为true //enumerable 是否可以枚举|默认为true //定义一个对象,且设置属性 const obj = Object.create(null, { id: { value: '1001', writable: true, configurable: true, enumerable: true }, pwd: { value: '123' } }) console.log(obj);//{id: "1001", pwd: '123'}
-
2021/1/13 es9 对象展开|正则扩展
对象展开...
function connect({host,port,..user}){ console.log(host);//127.0.0.1 console.log(port);//80 console.log(user);//{userid: "1001",username: "kjkjkl",password: "123456"} } connect({ host: '127.0.0.1', port: '80', userid: '1001', username: 'kjkjkl', password: '123456' });
const skillOne = { q: '天音波' } const skillTwo = { w: '金钟罩' } const skillThree = { e: '天雷破' } const skillFour = { r: '猛龙摆尾' } const skillzhs = { d: '惩戒', f: '闪现' } const mangseng = {...skillOne, ...skillTow, ...skillThree, ...skillFour, ...skillzhs}; console.log(mangseng);//{q: '天音破',w: '金钟罩', e: '天雷破', r: '猛龙摆尾', d: '闪现', f: '惩戒'}
正则扩展---命名捕获分组
//声明一个数组 const baidu = '<a href="http://www.baidu.com">百度</a>'; //声明正则 const reg = /<a href=".*?">.*?<\/a>/; //执行匹配 const result = reg.exec(baidu); //输出结果 console.log(result);//三个元素 //0: "<a href="http://www.baidu.com">百度</a>" //1: "http://www.baidu.com" //2: "百度" //属性groups: undefined //进行分组 const bili = '<a href="http://www.bilibili.com">哔哩哔哩</a>'; const reg1 = /<a href="?<url>.*?">?<text>.*?<\/a>/;//在获取匹配数据的前面加?<组名称> //执行匹配 const result1 = reg1.exec(bili); //输出结果 console.log(result1.groups.url);//http://www.bilibili.com console.log(result1.groups.text);//哔哩哔哩
正则扩展---反向断言
-
//声明一个字符串str const str = 'yd10086联通10010电话'; //正向断言 => 匹配数字且后一位为‘电’ const reg = /\d+(?=电)/; //执行匹配 const result = reg.exec(str); //输出 console.log(result);//0:10010 //反向断言 => 条件为前面为‘通’ 匹配数字 const reg1 = /(?<=通)\d+/; console.log(reg.exec(str));//0:10010
正则扩展---dotAll模式
//要求:正则表达式获取a标签以及p标签内的内容 const str = `<ul> <li> <a>肖申克的救赎</a> <p>上映时间: 1994-09-10</p> </li> <li> <a>阿甘正传</a> <p>上映时间: 1994-07-06</p> </li> </ul>`; //普通模式 const reg1 = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/; //dotAll模式 单个匹配为s 全局匹配为gs const reg2 = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs; let result; let data = []; while(result = reg2.exec(str)){ data.push({title: result[1],time: result[2]}); } console.log(data); //0: {title: "肖申克的救赎", time: "上映时间: 1994-09-10"} //1: {title: "阿甘正传", time: "上映时间: 1994-07-06"}
-
2021/1/9 ES10-ES11
ES10 Object.fromEntries() 数组与对象之间的转化
//二维数组 console.log(Object.fromEntries([ ["name","kjkjkl"], ["love",'javascript,C#,Asp.Net'] ]));//{name: "kjkjkl",like: "javascript","C#","Asp.Net"}
//Map const m = new Map(); m.set('name','kjkjkl'); console.log(Object.fromEntries(m));//{name: "kjkjkl"}
//ES8 - Object.Entries console.log(Object.entries({ name: 'kjkjkl' }));//[Array(2) => 0:name,1:kjkjkl]
ES10 字符串扩展trimStart()和trimEnd()
//trim()去字符串所有空格 //trimStart()去字符串起始位置空格 //trimEnd()去字符串末尾空格 const str = ' test ';//前后各有三个空格 console.log(str.trim());//test; console.log(str.trimStart());//test ; console.log(str.trim()End);// test;
ES10 flat()和flatMap()
//flat 平 数组降维 => 三维降二维|二维降一维 const arr = [1,2,3,[4,5,6,[7]]]; //三维降二维 console.log(arr.flat());//[1,2,3,4,5,6,Array(1) => 0:7] //三维降二维再降一维 console.log(arr.flat().flat());//[1,2,3,4,5,6,7]
//flatMap将Map中的对象进行降维 const arr = [1,2,3,4,5]; console.log(arr.flatMap(item => (item*10)));//[10,20,30,40,50]
ES10 Symbol.prototype.description属性
//description去Symbol标签 let a = Symbol(123); console.log(typeof(a),typeof(a.description));//Symbol String console.log(a.description);//123
ES11 私有属性 (#)
//声明一个类 class Person{ //设置公有属性name name; //设置私有属性age,weight #age; #weight; //生成构造函数 constructor(name,age,weight){ //指向属性并赋值 this.name = name; this.#age = age; this.#weight = weight; } //私有属性只能进行内部调用 info(){ //因为是类的属性,所以前面必须要加this console.log(this.name);//小宇 console.log(this.#age);//17 console.log(this.#weight);//58kg } } //初始化类 let girl = new Person('小宇',17,'58kg'); //调用函数 girl.info(); //外部调用类的属性 console.log(girl.name);//小宇 //调用私有属性会报错 //console.log(girl.#age);//Uncaught SyntaxError: Private field '#age' must be declared in an enclosing class
ES11 Promise.allSettled()与Promise.all()
//定义两个Promise对象 const p1 = new Promise((resolve, reject)=>{ resolve('商品数据 -1'); }); const p2 = new Promise((resolve, reject)=>{ reject('出错啦'); }); //allSettled返回的结果永远为fulfilled 值为所有promise的携带参数,包含resolve和reject console.log(Promise.allSettled([p1, p2]));//state:fulfilled //all返回的结果:当一个Promise为reject时,返回rejected 值为reject中的参数 console.log(Promise.all([p1, p2]));//state:rejected
ES11 string.prototype.matchAll()
//要求:提取全局a标签和p标签的值 const 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; //给定一个字符串和一个正则表达式,.matchAll()为所有匹配的匹配对象返回一个迭代器 let result = str.matchAll(reg); //遍历内容并输出 for(let v of result){ console.log(v); }
ES11 可选链操作符?.
//?.检测属性是否存在 function main(config){ console.log(config?.db?.host); }; main({ db: { host: '192.168.1.11', username: 'kjkjkl' }, cache: { host: '127.0.0.1', usernmae: 'admin' } });
动态import
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>动态import</title> </head> <body> <script src="js/app_1.js" type="module"></script> </body> </html>
//app_1.js //局部引用方法,节省资源占用 import('./hello.js').then(module=>{ module.hello(); })
//hello.js export function hello(){ console.log('Hello World!'); }
ES11 - BigInt
//声明一个大整形n //大整形不可与整形直接运算 let n = 111n; console.log(n,typeof(n));//111n BigInt //大数值运算 //声明最大安全整数Number.MAX_SAFE_INTEGER let max = Number.MAX_SAFE_INTEGER; console.log(max);//9007199254740991 console.log(max +1);//9007199254740992 //转换为大整形 console.log(BigInt(max));//9007199254740991n //直接BigInt(max) +1会报错,必须转换为BigInt(1) console.log(BigInt(max) + BigInt(1));//9007199254740992n
ES11 - 全局对象globalThis
//任何环境下,globalThis 都是存在的,都可以从它拿到顶层对象,指向全局环境下的 this //浏览器里面,顶层对象是 window,但 Node 和 Web Worker 没有window //浏览器和 Web Worker 里面,self 也指向顶层对象,但是 Node 没有 self //Node 里面,顶层对象是 global,但其他环境都不支持 console.log(globalThis);