ECMS相关介绍
什么是ECMA
ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制
造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该
组织改名为 Ecma 国际
什么是ECMAScript
ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言。
什么是ECMA-262
Ecma 国际制定了许多标准,而 ECMA-262 只是其中的一个,所有标准列表查看
http://www.ecma-international.org/publications/standards/Standard.htm
ECMA-262历史版本
ECMA-262(ECMAScript)历史版本查看网址
http://www.ecma-international.org/publications/standards/Ecma-262-arch.htm
- 从 ES6 开始,每年发布一个版本,版本号比年份最后一位大 1
谁在维护 ECMA-262
TC39(Technical Committee 39)是推进 ECMAScript 发展的委员会。其会员都是
公司(其中主要是浏览器厂商,有苹果、谷歌、微软、因特尔等)。TC39 定期
召开会议,会议由会员公司的代表与特邀专家出席
ES6兼容性
-
ES6 的版本变动内容最多,具有里程碑意义
-
ES6 加入许多新的语法特性,编程实现更简单、高效
-
兼容性
http://kangax.github.io/compat-table/es6/
ECMAScript 6
let变量声明以及特性
- 声明对象类型使用 const,非对象类型声明选择 let
变量不能重复声明
//声明变量
// let a;
// let b,c,d;
// let e = 100;
// let f = 521, g = 'iloveyou', h = [];
//1. 变量不能重复声明
let star = '罗志祥';
let star = '小猪';
//Identifier 'star' has already been declared
块级作用域
- 之前作用域: 全局, 函数, eval(eveal,es5严格模式才出现)
- 现在引入块级作用域if else while for 都是块级作用域
// if else while for 都是块级作用域
{
girl = '周扬青';
}
console.log(girl);
//girl is not defined
### 不存在变量提升
console.log(song);
let song = '恋爱达人';
// Cannot access 'song' before initialization
不影响作用域链
{
let school = 'wangkai';
function fn(){
console.log(school);
}
fn(); //wangkai
}
const声明常量以及特点
-
值不能修改的量叫常量
-
声明常量
const SCHOOL = '你好啊'; console.log(SCHOOL) //你好啊
一定要赋初始值
const A;
//Missing initializer in const declaration
一般常量使用大写(潜规则)
onst a = 100;
常量的值不能修改
const SCHOOL = '你好啊';
SCHOOL = 'ABCD';
// console.log(SCHOOL) //Assignment to constant variable.
块级作用域
{
const PLAYER = 'UZI';
}
console.log(PLAYER);
//PLAYER is not defined
改对象不会报错
- 对于数组和对象的元素修改, 不算做对常量的修改, 不会报错
const TEAM = ['UZI','MXLG','Ming','Letme'];
// TEAM.push('Meiko');
变量的解构赋值
- 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);
//ƒ (){ console.log("我可以演小品");}
// xiaopin(); //我可以演小品
// 以前:zhao.xiaopin();
// zhao.xiaopin();
// zhao.xiaopin();
// zhao.xiaopin(); //我可以演小品
// 现在:
let {xiaopin} = zhao; //我可以演小品
xiaopin();
模板字符串
``
- ES6引入了新的声明方式``
- 以前:
''
和" "
let str = `我也是一个字符串哦!`;
console.log(str, typeof str);
内容中可以直接出现换行
let str = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>魏翔</li>
<li>艾伦</li>
</ul>`;
console.log(str)
// <ul>
//<li>沈腾</li>
//<li>玛丽</li>
//<li>魏翔</li>
//<li>艾伦</li>
//</ul>
变量拼接
let lovest = '魏翔';
let M = '呵呵呵'
let out = `${lovest}是我心目中最搞笑的演员${M}!!`;
console.log(out);
// 魏翔是我心目中最搞笑的演员呵呵呵!!
简化对象写法
- ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁
let name = '尚硅谷';
let change = function(){
console.log('我们可以改变你!!');
}
const school = {
name, //属性名和变量名一样可以省略一个
change,
improve(){ //省略了function和:
console.log("我们可以提高你的技能");
}
}
console.log(school);
//{name: "尚硅谷", change: ƒ, improve: ƒ}
箭头函数
声明一个箭头函数
- ES6 允许使用「箭头」(=>)定义函数。
//声明一个函数
// let fn = function(){
// } //以前
let fn = (a,b) => {
return a + b;
}
//调用函数
let result = fn(1, 2);
console.log(result); //3
箭头函数的this
箭头函数适合与 this 无关的回调.
比如 :定时器, 数组的方法回调
头函数不适合与 this 有关的回调(只是说不适合)
事件回调, 对象的方法
- this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值
- 并没有自己的this
function getName(){
console.log(this.name); //普通方式的函数
}
let getName2 = () => {
console.log(this.name); //箭头函数
}
//设置 window 对象的 name 属性
window.name = '尚硅谷';
const school = {
name: "ATGUIGU"
}
//直接调用
getName(); //尚硅谷
getName2(); //尚硅谷
//call 方法调用
getName.call(school); //ATGUIGU 改变
getName2.call(school); //尚硅谷 箭头函数this静态的,不会变
不能作为构造实例化对象
let Person = (name, age) => {
this.name = name;
this.age = age;
}
let me = new Person('xiao',30);
console.log(me);
//Person is not a constructor
### 不能使用arguments变量
let fn = () => {
console.log(arguments);
}
fn(1,2,3);//arguments is not defined
省略小括号
- 当形参有且只有一个的时候,可以省略小括号
let add = n => {
return n + n;
}
console.log(add(9)); //18
省略花括号
- 当代码体只有一条语句的时候可以省略花括号, 此时 return 必须省略
- 而且语句的执行结果就是函数的返回值
let pow = n => n * n;
console.log(pow(8)); //64
实践
- 需求-1 点击 div 2s 后颜色变成『粉色』
//需求-1 点击 div 2s 后颜色变成『粉色』
//获取元素
let ad = document.getElementById('ad');
//绑定事件
ad.addEventListener("click", function(){
//以前保存 this 的值
// let _this = this;
//定时器
setTimeout(() => { //之前是function,现在是箭头函数
//修改背景颜色 this
// console.log(this); //window
//this找不到就像外层找,保存外部的this
// _this.style.background = 'pink';
this.style.background = 'pink';
//现在this指向外层作用域,外层的this指向ad
}, 2000);
});
- 从数组中返回偶数的元素
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); //(3) [6, 10, 100]
允许设置参数默认值
形参初始值
- ES6 允许给函数参数赋值初始值
- 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)
function add(a,c=10,b) {
return a + b + c;
}
let result = add(1,2);
// console.log(result); //NaN 有默认值不会
与解构赋值结合
function connect({host="127.0.0.1", username,password, port}){
console.log(host) //atguigu.com
console.log(username) //root
console.log(password) //root
console.log(port) //3306
}
connect({
host: 'atguigu.com',
username: 'root',
password: 'root',
port: 3306
})
rest参数
- ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
ES5 获取实参的方式
- 返回的是对象
function date(){
console.log(arguments);
}
date('白芷','阿娇','思慧');
// Arguments(3) ["白芷", "阿娇", "思慧", callee: ƒ, Symbol(Symbol.iterator): ƒ]
rest 参数
- 返回的是数组,可以对数组用下面方法
- 可以用数组的方法…filter some every map
function date(...args){
console.log(args);
//(3) ["阿娇", "柏芝", "思慧"]
//返回的是数组,可以对数组用下面方法
// filter some every map
}
### rest参数必须要放到参数最后
function fn(a,b,...args){
console.log(a);
console.log(b);
console.log(args);
}
fn(1,2,3,4,5,6); //1,2 (4) [3, 4, 5, 6]
spread扩展运算符
…扩展元素运算符
...
扩展运算符能将数组转换成为逗号分隔的参数序列
const tfboys = ['易烊千玺','王源','王俊凯'];
// => '易烊千玺','王源','王俊凯'
// 声明一个函数
function chunwan(){
console.log(arguments);
}
chunwan(...tfboys);// chunwan('易烊千玺','王源','王俊凯')
//rest ...是放在了形参,而这个是实参
------扩展运算符的应用------
数组的合并
const kuaizi = ['王太利','肖央'];
const fenghuang = ['曾毅','玲花'];
// const zuixuanxiaopingguo = kuaizi.concat(fenghuang); //以前方法
//(4) ["王太利", "肖央", "曾毅", "玲花"]
const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];
console.log(zuixuanxiaopingguo);
// //(4) ["王太利", "肖央", "曾毅", "玲花"]
数组的克隆
- 是一个浅拷贝
const sanzhihua = ['E','G','M'];
const sanyecao = [...sanzhihua];
console.log(sanyecao);// ['E','G','M']
### 将伪数组转为真正的数组
const divs = document.querySelectorAll('div');
console.log(divs);
// __proto__(Nodelist).__proto__ (Object)
const divArr = [...divs];
console.log(divArr);
//__proto__(Array).__proto__ (Object)
Symbol
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
symbol特点
- Symbol 的值是唯一的,用来解决命名冲突的问题
- Symbol 值不能与其他数据进行运算
Symbol 定义 的 对象属 性 不能 使 用 for…in 循 环遍 历 ,但 是可 以 使 用Reflect.ownKeys 来获取对象的所有键名
- 遇到唯一性的场景时要想到 Symbol
创建Symbol
let s = Symbol(); //函数
console.log(s, typeof s);
//Symbol() "symbol"
Symbol唯一性
let s2 = Symbol('尚硅谷');
let s3 = Symbol('尚硅谷');
// console.log(s2 === s3) //false
Symbol.for创建
let s4 = Symbol.for('尚硅谷'); //函数对象
let s5 = Symbol.for('尚硅谷');
console.log(s4,typeof s4)
//Symbol(尚硅谷) "symbol"
// console.log(s4 === s5) //true
不能与其他数据进行运算
let result = s + 100;
let result = s > 100;
let result = s + s;
//Identifier 'result' has already been declared
七种数据类型
USONB you are so niubility
u undefined
s string symbol
o object
n null number
b boolean
------❥给对象添加Symbol属性的两种方式❥------
Symbol作用 给对象添加属性和方法(独一无二)
第一种
//向对象中添加方法 up down
let game = {
name:'俄罗斯方块',
up: function(){},
down: function(){}
};
//声明一个对象
let methods = {
up: Symbol(),
down: Symbol()
};
game[methods.up] = function(){
console.log("我可以改变形状");
}
game[methods.down] = function(){
console.log("我可以快速下降!!");
}
console.log(game);
//{name: "俄罗斯方块", up: ƒ, down: ƒ, Symbol(): ƒ, Symbol(): ƒ}
第二种
let youxi = {
name:"狼人杀",
[Symbol('say')]: function(){
console.log("我可以发言")
},
[Symbol('zibao')]: function(){
console.log('我可以自爆');
}
}
console.log(youxi)
//{name: "狼人杀", Symbol(say): ƒ, Symbol(zibao): ƒ}
------❥Symbol内置属性❥------
Symbol.hasInstance
class Person{
static [Symbol.hasInstance](param){
console.log(param);
console.log("我被用来检测类型了");
return false;
}
}
let o = {};
console.log(o instanceof Person);
// {}
//我被用来检测类型了
//false
Symbol.isConcatSpreadable
const arr = [1,2,3];
const arr2 = [4,5,6];
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));
//(4) [1, 2, 3, Array(3)]
Iterator 迭代器
- 需要自定义遍历数据的时候,要想到迭代器。
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
-
Iterator接口 就是对象里的一个属性,这个属性的名字叫做[Symbol.iterator]
-
ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费
-
原生具备 iterator 接口的数据(可用 for of 遍历)
- Array
- Arguments
- Set
- Map
- String
- TypedArray
- NodeList
for…of 遍历数组
//声明一个数组
const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
// 使用 for...of 遍历数组
for(let v of xiyou){
console.log(v); //唐僧 孙悟空 猪八戒 沙僧
}
console.log(xiyou)
//[(4) ["唐僧", "孙悟空", "猪八戒", "沙僧"].__proto__
//Symbol(Symbol.iterator): ƒ values()]
迭代器工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
- 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
- 每调用 next 方法返回一个包含 value 和 done 属性的对象
const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
let iterator = xiyou[Symbol.iterator]();
// console.log(iterator)
//Array Iterator {}.__proto__
//next: ƒ next()
//调用对象的next方法
console.log(iterator.next());
//{value: "唐僧", done: false}
console.log(iterator.next());
//{value: "孙悟空", done: false}
console.log(iterator.next());
//{value: "猪八戒", done: false}
console.log(iterator.next());
//{value: "沙僧", done: false}
console.log(iterator.next());{value:
//undefined, done: true} true表示遍历循环完成
自定义迭代器遍历对象
//声明一个对象
const banji = {
name: "终极一班",
stus: [
'xiaoming',
'xiaoning',
'xiaotian',
'knight'
],
// 加上Iterator接口(方法)
[Symbol.iterator]() {
//索引变量
let index = 0;
//
let _this = this;
//返回一个对象(对应1.创建一个指针对象,指向当前数据结构的起始位置)
return {
//添加next方法(对应4.每调用 next 方法返回一个包含 value 和 done 属性的对象)
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); //xiaoming,xiaoning,xiaotian,knight
}
生成器函数
- 生成器函数是 ES6 提供的一种异步编程解决方案
生成器本身是一个函数
生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同
生成器其实就是一个特殊的函数(声明特殊,执行特殊,调next方法才运行)
异步编程 纯回调函数 node fs ajax mongodb
yield算作函数代码的分隔符
生成器函数的声明
- 代码说明
- * 的位置没有限制
- 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到yield 语句后的值
- yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next方法,执行一段代码
- next 方法可以传递实参,作为 yield 语句的返回值
function * gen(){
console.log(111);
yield '一只没有耳朵';
//(yield后面跟表达式或者跟字面量)
console.log(222);
yield '一只没有尾部';
console.log(333);
yield '真奇怪';
console.log(444);
}
// let iterator = gen();
// iterator.next(); //111
// iterator.next(); //222
// iterator.next(); //333
// iterator.next(); //444
// console.log(iterator.next());
// 111
//{value: "一只没有耳朵", done: false}
// console.log(iterator.next());
//222
//{value: "一只没有尾部", done: false}
// console.log(iterator.next());
//333
//{value: "真奇怪", done: false}
// console.log(iterator.next());
//444
//{value: undefined, done: true}
//遍历
for(let v of gen()){
console.log(v);
}
//111
//一只没有耳朵
//222
//一只没有尾部
//333
//真奇怪
//444
### 生成器函数的调用
function * gen() {
yield 111;
yield 222;
yield 333;
}
//执行获取迭代器对象
let iterator = gen();
console.log(iterator.next())
//{value: 111, done: false}
console.log(iterator.next())
//{value: 222, done: false}
console.log(iterator.next())
//{value: 333, done: false}
console.log(iterator.next())
//{value: undefined, done: true}
生成器函数传参
- 生成器整体函数传参
- next方法也是可以传参的(实参),而且我们这个方法(实参)作为上一个yield语句的返回结果
- 第二次调用next,yield传入的参数作为第一个yield语句整体返回结果
function * gen(arg) {
console.log(arg) //undefined
let one = yield 111;
console.log(one) //BBB
let two = yield 222;
console.log(two)//CCC
let three = yield 333;
console.log(three)//DDD
}
let iterator = gen() //undefined
console.log(iterator.next('kkk'))
//经过测试,第一次传参无用
//{value: 111, done: false}
console.log(iterator.next('BBB'))
//{value: 222, done: false}
console.log(iterator.next('CCC'))
//{value: 333, done: false}
console.log(iterator.next('DDD'))
//{value: undefined, done: true}
回调地狱
异步编程:比如: 1.文件操作 2.网络操作(ajax, request) 3.数据库操作
- 需求:1s后控制台输出 111 2s后输出 222 3s后输出 333
setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
}, 3000);
}, 2000);
}, 1000);
生成器函数解决回调地狱
需求: 1s后控制台输出 111 2s后输出 222 3s后输出 333
- 生成器函数解决
- 声明三个函数.分别完成三个异步任务
//输出1任务
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)
}
function * gen(){
yield one();
yield two();
yield three();
}
//调用生成器函数
let iterator = gen();
iterator.next();
// 不在任务重加iterator.next()只输出111
//111/222/333
生成器函数在异步任务的表现
- 模拟获取 用户数据 订单数据 商品数据
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();
console.log(users) //用户数据
let orders = yield getOrders();
console.log(orders) //订单数据
let goods = yield getGoods();
console.log(goods) //商品数据
}
//调用生成器函数
let iterator = gen();
iterator.next();
Promise
Promise 是 ES6 引入的异步编程的新解决方案(主要解决回调地狱问题)。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
实例化Promise对象
- 成功状态
const p = new Promise(function(resolve,reject) {
setTimeout(function() {
let data = '数据库中的用户数据';
// 调用resovle方法
resolve(data)
//调用resolve函数以后,这个Promise对象状态就会变为成功
//对象有三个状态: 初始化 成功 失败
},1000);
});
//调用promise对象的then方法
//成功的形参叫value,失败的形参叫reason
p.then(function(value){
console.log(value); //数据库中的数据
},function(){
})
- 失败状态
const p = new Promise(function(resolve,reject) {
setTimeout(function() {
let data = '数据库中的用户数据';
// 调用resovle方法
reject(data)
//调用resolve函数以后,这个Promise对象状态就会变为成功
//对象有三个状态: 初始化 成功 失败
},1000);
});
//调用promise对象的then方法
//成功的形参叫value,失败的形参叫reason
p.then(function(value){
console.log(value); //数据库中的数据
},function(reason){
console.error(reason); //数据库中的用户数据
})
Promise封装读取文件
- 调用方法读取文件
//1. 引入 fs 模块
const fs = require('fs');
fs.readFile('./resources/为学.md', (err, data)=>{
//如果失败, 则抛出错误
if(err) throw err;
//如果没有出错, 则输出内容
// console.log(data); //buffer
console.log(data.toString()); //一首诗
});
- 使用Promise封装
const p = new Promise(function(resolve, reject){
fs.readFile("./resources/为学.md", (err, data)=>{
//判断如果失败
if(err) reject(err);
//如果成功
resolve(data);
});
});
p.then(function(value){
console.log(value.toString()); //一首诗
}, function(reason){
console.log("读取失败!!");
});
Promise封装AJAX
- 发送ajax请求
<script>
// 接口地址: https://api.apiopen.top/getJoke
const p = new Promise((resolve, reject) => {
//1. 创建对象
const xhr = new XMLHttpRequest();
//2. 初始化
xhr.open("GET", "https://api.apiopen.top/getJok(e)");
//3. 发送
xhr.send();
//4. 绑定事件, 处理响应结果
xhr.onreadystatechange = function () {
//判断
if (xhr.readyState === 4) {
//判断响应状态码 200-299
if (xhr.status >= 200 && xhr.status < 300) {
//表示成功
// console.log(xhr.response); 文本
resolve(xhr.response);
} else {
//如果失败
// console.error(xhr.status); 404
reject(xhr.status);
}
}
}
})
//指定回调
p.then(function(value){
console.log(value);
}, function(reason){
console.error(reason);
});
</script>
Promise.prototype.then
<script>
//创建 promise 对象
const p = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('用户数据');
// reject('出错啦');
}, 1000)
});
// 调用then方法
const result = p.then(value => {
console.log(value);
return '王凯';
},reason => {
console.warn(reason);
})
console.log(result)
//Promise {<pending>}
// __proto__: Promise
//[[PromiseStatus]]: "fulfilled"
//[[PromiseValue]]: undefined
//调用 then 方法 then方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果决定
//1. 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值
// const result = p.then(value => {
// console.log(value);
// //1. 非 promise 类型的属性
// // return 'iloveyou';
// //2. 是 promise 对象
// // return new Promise((resolve, reject)=>{
// // // resolve('ok'); then方法就chegng,返回值then成功的值
// // reject('error'); //then方法就失败,返回的值就是then方法的值
// // });
// //3. 抛出错误
// // throw new Error('出错啦!');
// throw '出错啦!';
// }, reason=>{
// console.warn(reason);
// });
//链式调用 then方法可以返回一个promise对象,所以可以链式调用
// p.then(value=>{
// }).then(value=>{
// });
</script>
实践–读取多个文件
//引入 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方法
<script>
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);
});
</script>
Set 集合
ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,集合的属性和方法:
### new Set()
- 声明set
let s = new Set();
console.log(s,typeof s)
//Set(0) "object"
set会自动去重
s2 = new Set(['大事儿','小事儿','好事儿','坏事儿','小事儿']);
console.log(s2)
//它会自动去重
//Set(4) {"大事儿", "小事儿", "好事儿", "坏事儿"}
.size
- 元素的个数
- 返回集合的元素个数
console.log(s2.size);
//4
.add()
- 添加元素
- 增加一个新元素,返回当前集合
s2.add('喜事儿');
console.log(s2)
//Set(5) {"大事儿", "小事儿", "好事儿", "坏事儿", "喜事儿"}
.delete()
- 删除元素
- 删除元素,返回boolean值
s2.delete('坏事儿');
console.log(s2)
//Set(4) {"大事儿", "小事儿", "好事儿", "喜事儿"}
.has()
- 检测
- 检测集合中是否包含某个元素,返回 boolean 值
console.log(s2.has('糟心事'));
// false
.clear()
- 清空
- 清空集合,返回 undefined
// s2.clear();
// console.log(s2);
//Set(0) {}
for…of
for(let v of s2){
console.log(v);
}
//大事儿, 小事儿, 好事儿, 喜事儿
❥集合实践❥(
数组去重
let arr = [1,2,3,4,5,4,3,2,1];
let result = [...new Set(arr)];
console.log(result);
//(5) [1, 2, 3, 4, 5]
交集
let arr = [1,2,3,4,5,4,3,2,1];
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;
}
});
// console.log(result) //(2) [4, 5]
let arr = [1,2,3,4,5,4,3,2,1];
let arr2 = [4,5,6,5,6];
let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
// console.log(result); // 4 5
并集
let arr = [1,2,3,4,5,4,3,2,1];
let arr2 = [4,5,6,5,6];
let union = [...new Set([...arr, ...arr2])];
console.log(union);
//[1, 2, 3, 4, 5, 6]
差集(和交集相反)
let arr = [1,2,3,4,5,4,3,2,1];
let arr2 = [4,5,6,5,6];
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
console.log(diff);
//(3) [1, 2, 3]
Map
- 升级版的对象
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。
new Map()
- 声明Map
let m = new Map();
console.log(m)
//Map(0) {}
.set()
- 增加一个新元素,返回当前 Map
m.set('name','尚硅谷');
console.log(m)
//Map(1) {"name" => "尚硅谷"}
//key: "name"
//value: "尚硅谷"
m.set('change', function(){
console.log("我们可以改变你!!");
});
//{"change" => function(){ console.log("我们可以改变你!!"); }}
//key: "change"
let key = {
school : 'ATGUIGU'
};
m.set(key, ['北京','上海','深圳']);
//key: {school: "ATGUIGU"}
//value: (3) ["北京", "上海", "深圳"]
.size
- 返回Map的元素个数
console.log(m.size);
//3
.delte()
- 删除
m.delete('name');
console.log(m)
//Map(2) {"change" => ƒ, {…} => Array(3)}
.get()
- 返回键名对象的键值
console.log(m.get('change'));
//ƒ (){
//console.log("我们可以改变你!!");
//}
console.log(m.get(key));
//(3) ["北京", "上海", "深圳"]
.has()
- 检测 Map 中是否包含某个元素,返回 boolean 值
.clear()
- 清空集合,返回 undefined
m.clear();
//Map(0){}
for…of
for(let v of m){
console.log(v);
}
// console.log(m);
//(2) ["name", "尚硅谷"]
//Map.html:65 (2) ["change", ƒ]
//Map.html:65 (2) [{…}, Array(3)]
class 类
- class 声明类
- constructor 定义构造函数初始化
- extends 继承父类
- super 调用父级构造方法
- static 定义静态方法和属性
- 父类方法可以重写
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
- ES5实例化对象
//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);
//Phone brand: "华为" price: 5999 __proto__: Object
声明class
- 构造方法 名字不能修改 必须叫constructor
- 使用new加类型的时候,会自动执行实例对象上的constructor方法
- 方法必须使用该语法, 不能使用 ES5 的对象完整形式
- 方法名+()+{} 没有function 和 :
class Shouji{
//构造方法 名字不能修改 必须叫constructor
//使用new加类型的时候,会自动执行实例对象上的constructor方法
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//方法必须使用该语法, 不能使用 ES5 的对象完整形式
//方法名+()+{} 没有function 和 :
call(){
console.log("我可以打电话!!");
}
}
let onePlus = new Shouji("1+", 1999);
console.log(onePlus);
//Shouji {brand: "1+", price: 1999} brand: "1+" price: 1999 __proto__: Object
static 类的静态成员
- 静态属性
- static标注的属性和方法它属于类而不属于实例对象
class Phone{
//静态属性
//static标注的属性和方法它属于类而不属于实例对象
static name = '手机';
static change(){
console.log("我可以改变世界");
}
}
let nokia = new Phone();
console.log(nokia.name); //undefined
console.log(Phone.name); //手机
- ES5里面
- 实例对象是实例对象 函数对象是函数对象 他们的属性是不通的
- 实力对象里面的属性 和函数对象里面的属性是不通的
function Phone(){
}
Phone.name = '手机';
Phone.change = function(){
console.log("我可以改变世界");
}
//上面这些属性属于函数对象的,并不属于实例对象 称为静态成员
Phone.prototype.size = '5.5inch';
let nokia = new Phone();
console.log(nokia.name);
//undefined
nokia.change();
console.log(nokia.size);
//nokia.change is not a function
console.log(nokia.size)
//5.5inch
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指向SmartPhone里面的this,也就是SmartPhone实例化对象
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);
extends 继承父类
- extends 继承父类
<script>
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();
</script>
子类是不能调用父类的同名方法的
<script>
//js语法里子类是不能调用父类的同名方法的
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();
</script>
class的set 和 get
<script>
// get 和 set
class Phone{
get price(){
console.log("价格属性被读取了");
return 'iloveyou';
}
set price(newVal){
console.log('价格属性被修改了');
}
}
//实例化对象
let s = new Phone();
// console.log(s.price);
s.price = 'free';
</script>
数值扩展
Number.EPSILON
- Number.EPSILON 是 JavaScript 表示的最小精度
- EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16
function equal(a, b){
if(Math.abs(a-b) < Number.EPSILON){
return true;
}else{
return false;
}
}
// console.log(0.1 + 0.2 === 0.3); false
// console.log(equal(0.1 + 0.2, 0.3)) //true
0b 0o
- ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示。
//1. 二进制和八进制
let b = 0b1010; //10
let o = 0o777; //511
let d = 100; //100
let x = 0xff; //255
// console.log(x);
Number.isFinite()
- 用来检查一个数值是否为有限数
nsole.log(Number.isFinite(100)); //true
console.log(Number.isFinite(100/0)); //false
console.log(Number.isFinite(Infinity)); //false
Number.isNaN()
- 用来检查一个值是否为 NaN
console.log(Number.isNaN(123)); //false
Number.parseInt()
- ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变。
console.log(Number.parseInt('5211314love')); //5211314
Number.parseFloat()
console.log(Number.parseFloat('3.1415926神奇')); //3.1415926
Math.trunc()
- 用于去除一个数的小数部分,返回整数部分。
console.log(Math.trunc(3.5)); //3
Number.isInteger()
- 用来判断一个数值是否为整数
console.log(Number.isInteger(5)); //true
console.log(Number.isInteger(2.5)); //false
Math.sign()
- 判断一个数到底为正数 负数 还是零
console.log(Math.sign(100)); //1
console.log(Math.sign(0)); //0
console.log(Math.sign(-20000)); //-1
对象方法扩展
ES6 新增了一些 Object 对象的方法
- Object.is 比较两个值是否严格相等,与『===』行为基本一致(+0 与 NaN)
- Object.assign 对象的合并,将源对象的所有可枚举属性,复制到目标对象
- proto、setPrototypeOf、 setPrototypeOf 可以直接设置对象的原型
Object.is
- 判断两个值是否完全相等
console.log(Object.is(120, 120));// 类似于=== true
console.log(Object.is(NaN, NaN));// 区别=== true
console.log(NaN === NaN);// === //false
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));
//{host: "http://atguigu.com", port: 33060, name: "atguigu.com", pass: "iloveyou", test: "test", …}
Object.setPrototypeOf
- 设置原型对象,并不建议这样去做
const school = {
name: '尚硅谷'
}
const cities = {
xiaoqu: ['北京','上海','深圳']
}
Object.setPrototypeOf(school, cities);
console.log(Object.getPrototypeOf(school));
console.log(school);//{xiaoqu: Array(3)}
- Object.getPrototypeof
模块化
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来
模块化的好处
- 防止命名冲突
- 代码复用
- 高维护性
模块化规范产品
- ES6之前的模块化规范有
CommonJS | NodeJS、Browserify |
---|---|
AMD | requireJS |
CMD | seaJS |
使用ES6模块化引入模块
❥通用的导入方式❥
- 浏览器使用ES6模块化引入模块
<script type="module">
//引入wk.js模块内容
import * as wk from './wk.js'
console.log(wk);
</script>
export 分别暴露
export let name = 'wangkai';
export function home() {
console.log('万科欢迎您');
}
<script type="module">
//引入wk.js模块内容
import * as wk from './wk.js'
console.log(wk);
wk.default.home() //万科欢迎您
</script>
export{} 统一暴露
let name = 'wangkai';
function home() {
console.log('万科欢迎您');
}
export{name,home}
<script type="module">
//引入wk.js模块内容
import * as wk from './wk.js'
console.log(wk);
wk.default.home() //万科欢迎您
</script>
export default{} 默认暴露
- 花括号里面可以使任意类型 值
- 调用方法需要将加default : xxx.default.xxx()
export default{
name : 'wangkai',
home:function() {
console.log('万科欢迎您');
}
}
<script type="module">
//引入wk.js模块内容
import * as wk from './wk.js'
console.log(wk);
wk.default.home() //万科欢迎您
</script>
### ❥解构赋值形式引入❥
export 分别暴露
import {name,home} from './wk.js';
// console.log(name); //wangkai
// console.log(home); //ƒ home() { console.log('万科欢迎您');}
export let name = 'wangkai';
export function home() {
console.log('万科欢迎您');
}
export{} 统一暴露
- Identifier ‘name’ has already been declared
- 使用as 加别名,就不会和上面name冲突
import {name as namee,house} from './wkk.js';
// console.log(name); //wangkai
// console.log(home); //ƒ home() { console.log('万科欢迎您');}
let name = 'wangkai';
function home() {
console.log('万科欢迎您');
}
export{name,home}
export default{} 默认暴露
//default必须使用别名
import {default as kgg} from './wkkk.js';
console.log(kgg); //{name: "wangkai", home: ƒ}
// console.log(name); //wangkai
// console.log(home); //ƒ home() { console.log('万科欢迎您');}
- 花括号里面可以使任意类型 值
- 调用方法需要将加default : xxx.default.xxx()
export default{
name : 'wangkai',
home:function() {
console.log('万科欢迎您');
}
}
简便形式,只能针对默认形式
import wkkk from './wkkk.js';
console.log(wkkk); //{name: "wangkai", home: ƒ}
单独创建一个文档
- html
<script src="./app.js" type="module"></script>
- js
// 入口文件
// 模块引入
import * as wk from './wk.js';
import * as wkk from './wkk.js';
import * as wkkk from './wkkk.js';
console.log(wk);
console.log(wkk);
console.log(wkkk);
ES6-ES6模块化引入NPM包
<!--
1. 安装工具 npm i babel-cli babel-preset-env browserify(webpack) -D
2. 编译 npx babel src/js -d dist/js --presets=babel-preset-env
3. 打包 npx browserify dist/js/app.js -o dist/bundle.js
-->
//修改背景颜色为粉色
import $ from 'jquery';// const $ = require("jquery");
$('body').css('background','pink');
ECMAScript7
.includes
- Array.prototype.includes
- Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值
// includes indexOf(以前用indexOf)
const mingzhu = ['西游记','红楼梦','三国演义','水浒传'];
//判断
console.log(mingzhu.includes('西游记'));
//true
console.log(mingzhu.includes('金瓶梅'));
//false
** 幂运算符
- 在 ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同
console.log(2 ** 10);// 1024
//效果一样的 **更简单
console.log(Math.pow(2, 10));//1024
ECMAScript8
- async 和 await 两种语法结合可以让异步代码像同步代码一样
async 函数
- async用来声明一个特殊的函数
- async 函数的返回值为 promise 对象,
- promise 对象的结果由 async 函数执行的返回值决定
<script>
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);
})
</script>
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() {
// let result = await p;
// console.log(result) //用户数据
try {
let result = await p; //用户数据
//
console.log(result);
} catch (e) {
console.log(e); //失败啦!
}
}
//调用函数
main();
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();
async和await封装AJAX请求
<script>
// 发送 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 测试 axios
async 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();
</script>
//声明对象
const school = {
name:"尚硅谷",
cities:['北京','上海','深圳'],
xueke: ['前端','Java','大数据','运维']
};
//获取对象所有的键
console.log(Object.keys(school));
//0: "name"1: "cities"2: "xueke"
Object.values
- Object.values()方法返回一个给定对象的所有可枚举属性值的数组
//获取对象所有的值
// console.log(Object.values(school));
//["尚硅谷", Array(3), Array(4)]
Object.entries
- Object.entries()方法返回一个给定对象自身可遍历属性 [key,value] 的数组
console.log(Object.entries(school));
// (3) [Array(2), Array(2), Array(2)]
// 0: (2) ["name", "尚硅谷"]
// 1: (2) ["cities", Array(3)]
// 2: (2) ["xueke", Array(4)]
//创建 Map
// const m = new Map(Object.entries(school));
// console.log(m.get('cities'));
Object.getOwnPropertyDescriptors
- Object.getOwnPropertyDescriptors
- 该方法返回指定对象所有自身属性的描述对象
//对象属性的描述对象
console.log(Object.getOwnPropertyDescriptors(school));
//{name: {…}, cities: {…}, xueke: {…}}
// const obj = Object.create(null, {
// name: {
// //设置值
// value: '尚硅谷',
// //属性特性
// writable: true,
// configurable: true,
// enumerable: true
// }
// });
ECMAScript9
Rest/Spread属性
- Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
//rest 参数
function connect({host, port, ...user}){
console.log(host); //127.0.0.1
console.log(port); //3306
console.log(user); //{username: "root", password: "root", type: "master"}
}
connect({
host: '127.0.0.1',
port: 3306,
username: 'root',
password: 'root',
type: 'master'
});
对象合并
const skillOne = {
q: '天音波'
}
const skillTwo = {
w: '金钟罩'
}
const skillThree = {
e: '天雷破'
}
const skillFour = {
r: '猛龙摆尾'
}
const mangseng = {...skillOne, ...skillTwo, ...skillThree, ...skillFour};
console.log(mangseng)
//{q: "天音波", w: "金钟罩", e: "天雷破", r: "猛龙摆尾"}
// ...skillOne => q: '天音波', w: '金钟罩'
正则命名分组
let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
//分组命名
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result = reg.exec(str);
console.log(result.groups.url);
//http://www.atguigu.com
console.log(result.groups.text);
//尚硅谷
- 以前办法
//声明一个字符串
let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
//提取 url 与 『标签文本』
const reg = /<a href="(.*)">(.*)<\/a>/;
// //执行
const result = reg.exec(str);
console.log(result);
//["<a href="http://www.atguigu.com">尚硅谷</a>", "http://www.atguigu.com", "尚硅谷", index: 0, input: "<a href="http://www.atguigu.com">尚硅谷</a>", groups: undefined]
console.log(result[1]);
//http://www.atguigu.com
console.log(result[2]);
// 尚硅谷
正则 正向断言
//声明字符串
let str = 'JS5211314你知道么555啦啦啦';
//正向断言
const reg = /\d+(?=啦)/;
const result = reg.exec(str);
console.log(result)
//["555", index: 13, input: "JS5211314你知道么555啦啦啦", groups: undefined]
正则 反向断言
//反向断言
const reg = /(?<=么)\d+/;
const result = reg.exec(str);
console.log(result);
//["555", index: 13, input: "JS5211314你知道么555啦啦啦", groups: undefined]
. dotAll模式
-
dot . 元字符 除换行符以外的任意单个字符
-
正则表达式中点.匹配除回车外的任何单字符,标记『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>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/;
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);
ECMAScript10
Object.fromEntries
-
Object.entries和它相反
-
二维数组
const result = Object.fromEntries([
['name','尚硅谷'],
['xueke', 'Java,大数据,前端,云计算']
]);
console.log(result)
//Object
//name: "尚硅谷"
//xueke: "Java,大数据,前端,云计算"
- Map
const m = new Map();
m.set('name','ATGUIGU');
const result = Object.fromEntries(m);
console.log(result)
//{name: "ATGUIGU"}
- Object.entries和它相反
const arr = Object.entries({
name: "尚硅谷"
})
console.log(arr);
//[Array(2)]
//0: (2) ["name", "尚硅谷"]
//length: 1
trimStart 和 trimEnd
- 清除左边和右边空白
<script>
// trim
let str = ' iloveyou ';
console.log(str);
console.log(str.trimStart());
console.log(str.trimEnd());
</script>
Array.prototype.flat
-
flat 平
-
将多维数组转化为低位数组
-
参数为深度 是一个数字
- 三维转1维输入2
- 默认值是1
const arr = [1,2,3,4,[5,6]];
console.log(arr.flat());
(6) [1, 2, 3, 4, 5, 6]
const arr = [1,2,3,4,[5,6,[7,8,9]]];
console.log(arr.flat());
(7) [1, 2, 3, 4, 5, 6, Array(3)]
const arr = [1,2,3,4,[5,6,[7,8,9]]];
console.log(arr.flat(2));
//(9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
flatMap
-
跟Map很像,只是把维度降低
-
两个操作结合
const arr = [1,2,3,4];
const result = arr.map(item => item * 10);
console.log(result)
//(4) [10, 20, 30, 40]
----------------------------------------------------
const arr = [1,2,3,4];
const result = arr.map(item => [item * 10]);
console.log(result)
//0: [10]
//1: [20]
//2: [30]
//3: [40]
--------------------------------------------------------------
const arr = [1,2,3,4];
const result = arr.flatMap(item => [item * 10]);
console.log(result);
//(4) [10, 20, 30, 40]
Symbol.prototype.description
- 获取Symbol的描述字符串
<script>
//创建 Symbol
let s = Symbol('尚硅谷');
console.log(s.description);
//尚硅谷
</script>
ECMAScript11
类的私有属性
<script>
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);
//Private field '#age' must be declared in an enclosing class
girl.intro(); //晓红 18 45
</script>
Promise.allSettled
- 接收promise一个数组,返回的promise结果也是对象,不过返回的结果永远是一个成功的状态.而且成功的值是里边每一个promise状态和结果
<script>
//声明两个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);
</script>
String.prototype.matchAll
- 用来得到正则批量匹配的结果
<script>
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];
console.log(arr);
</script>
.? 可选链操作符
<script>
// ?.
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'
}
})
</script>
动态 import 导入
<body>
<button id="btn">点击</button>
<script src="./js/app.js" type="module"></script>
</body>
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();
});
}
BigInt 大整形
- 不能直接与数值计算
- 不能使用浮点数计算
<script>
//大整形
let n = 521n;
console.log(n, typeof(n));
//521n "bigint"
//函数
let n = 123;
console.log(BigInt(n)); //123n
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))
</script>
绝对全局对象globalThis
- 始终指向全局对象
<script>
console.log(globalThis); //window
</script>
console.log(globalThis); //globakThis