ES6:ECMAScript6

一、ES6新特性

1.let变量声明以及声明特性

1.1 let

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

let a;
let b,c,d;
let e = 100;
let f = 521,g= 'iloveyou',h = [];

1.变量不能重复声明

let star = '离歌笑';
let star = '李逍遥';

2.块级作用域 全局,函数,eval

//if else while  for
{let girl = '赵灵儿';
}
console.log(girl);

3.不存在变量提升

console.log(song);
let song = '仙剑奇侠传';

4.不影响作用域链

{let school = '仙一';function fn(){console.log(school);}fn();
}

1.2案例

需求:点击div更换背景颜色

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><div  style="width: 50px;height: 50px; margin: 10px; border: 1px solid black; "></div><div  style="width: 50px;height: 50px; margin: 10px; border: 1px solid green; "></div><div  style="width: 50px;height: 50px; margin: 10px; border: 1px solid yellow;"></div>
</body>
<script>//获取div元素对象let items = document.querySelectorAll("div");for(let i = 0;i<items.length;i++){items[i].onclick = function(){items[i].style.backgroundColor = 'pink';} }console.log(windows.i)  //3 // 当var=3的时候,点击事件开始向外层作用域找,找不到,就是windows.i,此时是3,如果是let i,具有块级作用域,所以每一次触碰事件的i都是不同的。
</script>
</html>

1.3const

const 关键字用来声明常量,const 声明有以下特点:
(常量的含义是指向的对象不能修改,但是可以改变对象内部的属性)

1.一定要赋初始值

const A;

2.一般变量使用大写(潜规则)

const a = 100;

3.常量的值不能修改

SCHOOL = 'LIGEXIAO';

4.块级作用域

{const PLAYER = 'UZI';
}
console.log(PLAYER);

5.对于数组和对象的元素修改,不算做对常量的修改,不会报错

    const TEAM = ['UZI','MXLG','Ming','Letme'];TEAM.push('LGX');console.log(TEAM);

6.不允许重复声明

const FRUIT = "apple"
const FRUIT = "apple" // 报错,不可重复声明

1.4解构赋值

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

1.数组的结构

const F4 = ['李逍遥','林月如','赵灵儿','刘晋元'];
let[li,lin,zhao,liu] = F4;
console.log(li);
console.log(lin);
console.log(zhao);
console.log(liu);

2.对象的解构

const li = {name:'离歌笑',age:'18',sing:function(){console.log('六月的雨');}
}
let{name,age,sing} = li;
console.log(name);
console.log(age);
console.log(sing);
sing();

注意:

  • 在let{name,age,sing} = li的{ } 中,里面的变量名需要和对象中的属性名相同
  • 可以通过let {sing} = li只获取里面的sing方法,之后也是通过sing()调用

2. 模板字符串

使用一对反引号 ` ` 声明的字符串,特性如下:

1.声明

let str = `一曲离歌笑江湖`;
console.log(str,typeof str);//一曲离歌笑江湖 string

2.里面可以直接使用换行

let str = ` <ul><li>离歌笑</li><li>李逍遥</li><li>赵灵儿</li></ul>`;
console.log(str);

3.变量拼接(替换/插入)

使用${变量名}定位插入的元素位置

let name = '离歌笑';
let out =  `一曲${name}江湖`;
console.log(out);//一曲离歌笑江湖

3. 对象的简化写法

ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法,这样的书写更加简洁

let name = '离歌笑';
let sing = function(){console.log('一曲离歌啸江湖');
}

原来:

const cos = {name:name,sing:sing,ligexiao:function(){console.log('一曲离歌啸江湖');}
} 

ES6:

const cos = {name,sing,ligexiao(){console.log('行如止水,心无旁骛');}
}

4. 箭头函数

ES6允许使用箭头 =>定义函数

函数声明:

//  let fn = function() {
//      ...
//  }let fn = (a,b) => {return a + b
}
// 调用函数
console.log(fn(2,3))  // 5

1.this是静态的,this始终指向函数声明时所在作用域下的this的值

function getName(){console.log(this.name);
}
let getName2 = ()=>{console.log(this.name);
}
window.name = '离歌笑';
const school = {name :'LIGEXIAO',
}
//直接调用
getName();//离歌笑
getName2();//离歌笑//call方法调用
getName.call(school);//LIGEXIAO
getName2.call(school);//离歌笑

2.不能作为构造函数实例化对象

let Person =(name,age)=>{this.name = name;this.age = age;
}
let me = new Person('ligexiao','30');
console.log(me);//Uncaught TypeError: Person is not a constructor

3.不能使用arguments 变量

let fn = () =>{console.log(arguments);//Uncaught ReferenceError: arguments is not defined
}
fn(1,2,3);

4.箭头函数的简写
(1) 省略小括号,当形参有且只有一个的时候可以省略小括号。

// let add = (n) => {
//   console.log(n + n)
// }
// add(3)  // 6// 简写:
let add = n => {console.log(n + n)
}
add(3)  // 6

(2) 省略花括号 { },仅当函数语句只有一条语句时。此时,'return' 也需要省略,结果即是返回值

let pow = n => n * n
console.log(pow(8))    // 64

实践练习

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>8.箭头函数练习</title><style>#ad{width: 200px;height: 200px;background:blue;}</style>
</head>
<body><div id="ad"></div><script>let ad = document.querySelector("#ad");//1.改变元素背景颜色ad.addEventListener('click',function(){//定时器setTimeout(()=>{//修改背景颜色this.style.backgroundColor = '#c00';},1000)})//2.从数组中返回偶数的元素const arr =[1,6,9,10,100,25];// const result = arr.filter(function(value){//     if(value%2===0)//     {//         return true;//     }//     else{//         return false;//     }// })// const result = arr.filter((value)=>{//     if(value%2===0)//     {//         return true;//     }//     else{//         return false;//     }// })// const result = arr.filter(value=>value%2===0);// console.log(result);//[6, 10, 100]//箭头函数适合与this无关的回调、定时器、数组的方法回调//箭头函数不适合与this有关的回调,事件回调,对象的方法// {//     name:'离歌笑',//     getName:()=>{//         this.name;//     }// }</script>
</body>
</html>

箭头函数适合与this无关的回调、定时器、数组的方法回调

箭头函数不适合与this有关的回调,事件回调,对象的方法


5. 函数参数默认值

ES6允许给函数参数赋值初始值

特性:

  1. 可以给形参赋初始值,一般位置要靠后(潜规则)
function add(a,b,c=12){return a+b+c;
}
let result = add (1,2)
console.log(result) // 15

如果上面代码没有给 形参c赋初始值,则执行add (1,2)时,形参c没有对应的参数,默认为NaN,所以add (1,2)的执行结果为NaN

2.与解构赋值结合

function ap({host='127.0.0.1', username, password, port}){console.log(host,username,password,port)    //
}
ap({host: 'localhost',username:'admin',password:'000000',port:3000})// 执行结果:localhost admin 000000 3000

6. rest参数

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

  • rest参数:以...为前缀,例如下面的...args

 原来的arguments

function date(){console.log(arguments);
}
date('离歌笑','李逍遥','赵灵儿');//Arguments(3) ['离歌笑', '李逍遥', '赵灵儿', callee: ƒ, Symbol(Symbol.iterator): ƒ]

现在的rest参数

function date(...arg){console.log(arg);
}
date('离歌笑','李逍遥','赵灵儿');//['离歌笑', '李逍遥', '赵灵儿']

rest参数必须要放到参数最后

function fn(a,b,...arg){console.log(a);console.log(b);console.log(...arg);
}
fn(1,2,3,4,5,6,7);//1 // 2//3 4 5 6 7

7. 扩展运算符

扩展运算符... ,能将数组转换为逗号分隔的参数序列

const tfboys=['易烊千玺','王源','王俊凯']
function show(){console.log(arguments)
}
show(tfboys)    // 一个参数,数组:['易烊千玺', '王源', '王俊凯']
show(...tfboys) //0: "易烊千玺"  1: "王源" 2: "王俊凯"

应用:

1.数组的合并

const arr1 = ['李逍遥','离歌笑'];
const arr2 = ['林月如','赵灵儿'];
// const arr = arr1.concat(arr2);//['李逍遥', '离歌笑', '林月如', '赵灵儿']
const arr = [...arr1,...arr2];
console.log(arr);//['李逍遥', '离歌笑', '林月如', '赵灵儿']

2.数组的克隆

const arr3 = ['李逍遥', '离歌笑', '林月如', '赵灵儿'];
const arr4 = [...arr3];//['李逍遥', '离歌笑', '林月如', '赵灵儿']
console.log(arr4);//['李逍遥', '离歌笑', '林月如', '赵灵儿']

如果数组里面有引用类型的数据,则整个为浅拷贝 ;否则,就是完全拷贝

const divs = document.querySelectorAll("div");
const divArr = [...divs];
console.log(divArr);// [div, div, div]

8. Symbol


语法

直接使用 Symbol() 创建新的 symbol 类型,并用一个可选的字符串作为其描述。

Symbol([description])

description (可选) 字符串类型。对symbol的描述,可用于调试但不是访问symbol本身。请注意,即使传入两个相同的字符串,得到的 symbol 也不相等。

const symbol1 = Symbol();
const symbol2 = Symbol(42);

Symbol()与Symbol.for()的区别

Symbol() :调用相同的symbol多次,会生成多个symbol

Symbol.for():调用相同的symbol多次,仍只会执行第一次的symbol

Symbol.for(key) 方法会根据给定的键 key,来从运行时的 symbol 注册表中找到对应的 symbol,如果找到了,则返回它,否则,新建一个与该键关联的 symbol,并放入全局 symbol 注册表中。

key:一个字符串,作为 symbol 注册表中与某 symbol 关联的键(可重复调用)

Symbol.for访问的是一个全局的submbol表,如果有了就访问相应对象,没有就重新创建

Symbol.keyFor()方法:
此方法会获取对应Symbol值的键。

全局定义拿得到symbol的值,普通定义拿不到

let cms = Symbol.for('lgx');//全局定义拿得到symbol的值
console.log(Symbol.keyFor(cms));//lgx
let lxy = Symbol('lxy');//普通定义拿不到
console.log(Symbol.keyFor(lxy));//undefined

 原来:(内容相同使用[]读取内容只能读取到第一个)

let user1 = '离歌笑';
let user2 = '离歌笑';
let grade = {[user1]:{js:100,css:89},[user2]:{js:50,css:26}
};
console.log(grade);

现在

// let user1 = '离歌笑';//{js: 100, css: 89}
// let user2 = '离歌笑';
let user1 = {name:'离歌笑',key:Symbol(),
}
let user2 = {name:'离歌笑',key:Symbol(),
}
let grade = {[user1.key]:{js:100,css:89},[user2.key]:{js:50,css:26}
};
console.log(grade[user1.key]);//{js: 100, css: 89}

Symbol取值和赋值都要加[]

私有属性

对象,属性如果不想公布到外部可以用symbol

由于任何两个 symbol 都是不相等的,在 JavaScript 里可以很方便地用来模拟私有属性。symbol` 不会出现在 Object.keys() 的结果中,因此除非你明确地 export 一个 symbol,或者用 Object.getOwnPropertySymbols() 函数获取,否则其他代码无法访问这个属性。

Object.keys()返回属性key,但不包括不可枚举的属性
Reflect.ownKeys()返回所有属性key

let symbol = Symbol("一曲离歌笑江湖");
let lgx = {name:'李逍遥',[symbol]:'离歌笑',
}
// for (const key in lgx)//普通遍历遍历不了symbol的值
// {
//     console.log(key);
// }
// for(const key of Object.getOwnPropertySymbols(lgx)){//只能遍历到symbol类型
//     console.log(key);
// }
// for(const key of Reflect.ownKeys(lgx))//返回所有属性key
// {
//     console.log(key);
// }let site = Symbol('一曲离歌啸江湖');
class User{constructor(name){this.name = name;this[site] = '离歌笑';}getName(){return `${this[site]} ${this.name}`;}
}
let lxy = new User('绿巨人');
// console.log(lxy.getName());
// for(let key in lxy)
// {
//     console.log(key);
// }

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

  • Symbol的值是唯一的,用来解决命名冲突的问题

  • Symbol值不能与其他数据进行运算

  • Symbol定义的对象属性不能使用for…in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名

特性:

  1. 创建
//创建Symbol
let s = Symbol();
// console.log(s,typeof s);//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===s5);//true

2.不能与其他数据进行运算(不可运算、比较)

let result = s+100;
let result = s>100;
let result = s+s;//Uncaught TypeError: Cannot convert a Symbol value to a number

3.数据类型的种类

字符串(String)、数字(Number)、布尔(Boolean)、数组(Array)、对象(Object)、空(Null)、未定义(Undefined),Symbol

应用:

  1. 给对象添加方法方式一:
let game= {name:'俄罗斯方块',up:function(){console.log('向上');},down:function(){console.log('向下');}
}
//声明一个对象
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(): ƒ}
console.log(game[methods.down]());//我可以快速下降!!!

2.给对象添加方法方式二:

let  youxi = {name:'离歌笑',[Symbol('lgx')]:function(){console.log('一曲离歌笑江湖');},[Symbol('lxy')]:function(){console.log('行如止水,心无旁骛');}
}
console.log(youxi);//{name: '离歌笑', Symbol(lgx): ƒ, Symbol(lxy): ƒ}

想读取Symbol方法的内容

let lgx = Symbol('lgx');
let lxy = Symbol('lxy');
let  youxi = {name:'离歌笑',lgx:function(){console.log('一曲离歌笑江湖');},lxy:function(){console.log('行如止水,心无旁骛');}
}
youxi.lxy()//行如止水,心无旁骛

symbol 内置属性

1.Symbol.hasInstance(自己控制类型检测)

//自己控制类型检测
class Person{static [Symbol.hasInstance](param){console.log(param);console.log('我被用来检测类型了');return false;}
}
let o = {};
console.log(o instanceof Person);

2.Symbol.isConcatSpreadable(该属性决定了当前对象作为concat的参数时是否可以展开)

const arr = [1,2,3];
const arr2 = [4,5,6];
arr2[Symbol.isConcatSpreadable]=false;
console.log(arr.concat(arr2));

9. 迭代器

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

ES6创造了一种新的遍历命令for…of循环,lterator接口主要供 for…of消费
    原生具备iterator接口的数据(可用for of遍历)

for ... offor ... in

for(let v in xiyou){console.log(v);//0 1 2 3
}
//使用for...of遍历数组
for(let v of xiyou){console.log(v);//李逍遥 赵灵儿 林月如 刘晋元
}

迭代器原理

  1. 创建一个指针对象,指向数据结构的起始位置
  2. 第一次调用next()方法,指针自动指向数据结构第一个成员
  3. 接下来不断调用next(),指针一直往后移动,直到指向最后一个成员
  4. 每次调用next()返回一个包含valuedone属性的对象
const xiyou = ['李逍遥','赵灵儿','林月如','刘晋元'];
//使用for...of遍历数组
// for(let v of xiyou){
//     console.log(v);//李逍遥 赵灵儿 林月如 刘晋元
//     for in保存的是键名,for of保存的是键值
// }
let iterator = xiyou[Symbol.iterator]();
//调用对象的iterator方法,done: true,指针指向最后一个,结束
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}
  • done的值为true的时候表示循环完成了
  • 需要自定义遍历数组的时候,要想到迭代器

 实践练习

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>17.迭代器自定义遍历对象</title>
</head>
<body><script>//声明一个对象const people = {name:'仙剑奇侠传一',stus:['lixiaoyao','zhaolinger','lingyueru','liujingyuan'],[Symbol.iterator](){//索引变量let index = 0;let that = this;return {next:function(){if(index < that.stus.length){const result = {value:that.stus[index],done:false}//下标自增index++;//返回结果return result;}else{return {value:undefined,done:true}}}}}}for(let key of people){console.log(key);}let iterator = people[Symbol.iterator]();console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());</script>
</body>
</html>

10. 生成器

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

一个generator看上去像一个函数,但可以返回多次。
    generator和函数不同的是,generator由function * 定义(注意多出的*号),并且,除了return语句,还可以用yield返回多次。

 回调地狱

setTimeout(()=>{console.log('1秒');setTimeout(()=>{console.log('2秒');setTimeout(()=>{console.log('3秒');setTimeout(()=>{console.log('4秒');setTimeout(()=>{console.log('5秒');},5000)},4000)},3000)},2000)
},1000)
function * generator (){    //函数名和function中间有一个 * yield '耳朵'      //yield是函数代码的分隔符yield '尾巴' yield '真奇怪'
}
let iterator = generator()
console.log(iteretor.next())
//{value:'耳朵',done:false} next()  // 执行第一段,并且返回yield后面的值
console.log(iteretor.next())  //{value:'尾巴',done:false}
console.log(iteretor.next())  //{value:'真奇怪',done:false}
function * gen(){console.log(111);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());
// console.log(iterator.next());
// console.log(iterator.next());
// console.log(iterator.next());//遍历
for(let v of iterator)
{console.log(v);111 一只没有耳朵 222 一只没有眼睛 333 真奇怪444
}

1. 生成器函数的参数传递

第二次调next方法传入的实参将作为第一个yield语句的整体返回结果

当前next方法传入的实参将作为 上一个yield语句的整体返回结果

function * gen(args){
console.log(args) //AAA
let one = yield 111  //111 (将 yield 111 返回的值赋给one)
console.log(one) //BBB
let two = yield 222 //222
console.log(two) //CCC
let three = yield 333 //333
console.log(three) //DDD
}let iterator = gen('AAA')
console.log(iterator.next())
console.log(iterator.next('BBB'))   //next中传入的BBB将作为yield 111的返回结果
console.log(iterator.next('CCC'))   //next中传入的CCC将作为yield 222的返回结果
console.log(iterator.next('DDD'))   //next中传入的DDD将作为yield 333的返回结果

2. 实例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() //111yield two() //222yield three() /333
}let iterator = gen()
iterator.next()

3.实例2:模拟异步获取数据

异步编程:文件操作 网络操作(ajax,request) 数据库操作 定时器

//模拟获取 用户数据 订单数据 商品数据
function getUsers(){setTimeout(()=>{let data = '用户数据';iterator.next(data);},1000)
}
function getOrders(){setTimeout(()=>{let data = '订单数据';iterator.next(data);},1000)
}
function getGoods(){setTimeout(()=>{let data = '商品数据';iterator.next(data);},1000)
}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();

11. Promise

Promise是ES6引入的异步编程的新解决方案。语法上 Promise是一个构造函数,用来封装异步操作并可以获取其成功失败的结果。

 const p = new Promise((resolve, reject) => {setTimeout(()=>{let data='数据库数据'// resolve(data) reject(data) })})p.then(function (value){   // 成功则执行第一个回调函数console.log(value)
},function (reason){      // 失败则执行第二个console.error(reason)
})

Promise读取文件

//1.引入fs模块
const fs = require('fs');
fs.readFile('./resource/content.txt',function(err,data){if(err)throw err;console.log(data);
})const p = new Promise(function(resolve,reject){require('fs').readFile('./resource/content.txt',function(err,data){if(err) reject(err);resolve(data);})
})
p.then(function(value){console.log(value.toString())
},function(reason){console.error('error真成功');
})   

Promise封装Ajax请求

//接口地址:https://api.apiopen.top/getJoke
const p = new Promise(function(resolve,reject){//1.创建对象const xhr = new XMLHttpRequest();//2.初始化xhr.open('GET', 'https://api.apiopen.top/geoke');//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((value)=>{console.log(value);
},
(reason)=>{console.error(reason);
})

Promise.then()方法

const p =new Promise((resolve, reject) =>{setTimeout(() => {resolve('用户数据') })
});//then()函数返回的实际也是一个Promise对象
//1.当回调后,返回的是非Promise类型的属性时,状态为fulfilled,then()函数的返回值为对象的成功值,如reutnr 123,返回的Promise对象值为123,如果没有返回值,是undefined//2.当回调后,返回的是Promise类型的对象时,then()函数的返回值为这个Promise对象的状态值//3.当回调后,如果抛出的异常,则then()函数的返回值状态也是rejected
let result = p.then(value => {console.log(value)//1.非Promise类型的属性// return 123 //2.是Promise对象// return new Promise((resolve, reject) => {// resolve('ok');// reject('error');//rejected(失败)// })//3.抛出错误// throw new Error('出错啦!');// throw '出错啦!!!';
},reason => {console.log(reason)
})
console.log(result)

链式回调

p.then(value=>{}).then(value=>{})

案例 Promise读取多个文件

//引入fs模块
const fs = require('fs');
//回调地狱
// fs.readFile('./resource/草.txt',(err,data1)=>{
//     fs.readFile('./resource/无题.txt',(err,data2)=>{
//         fs.readFile('./resource/题雁塔.txt',(err,data3)=>{
//             let result = `${data1}
//             ${data2}
//             ${data3} `;
//              console.log(result.toString());
//         })
//     })
// })
const p = new Promise((reslove,reject)=>{fs.readFile('./resource/草.txt',(err,data)=>{reslove(data);})
})
p.then(value=>{return  new Promise((reslove,reject)=>{fs.readFile('./resource/无题.txt',(err,data)=>{reslove([value,data]);})})
}).then(value=>{return  new Promise((reslove,reject)=>{fs.readFile('./resource/题雁塔.txt',(err,data)=>{//压入value.push(data);reslove(value);})})
}).then(value=>{console.log(value.join('\r\n'));
})

Promise.catch()方法

const p = new Promise((resolve, reject) => {setTimeout(()=>{reject('出错啦')},1000)
})p.catch(reason => {console.log(reason)
})

12. 集合

12.1 Set

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

集合的属性和方法:

  • .size返回集合的元素个数
  • .add()增加一个新元素,返回当前集合
  • .delete()删除元素,返回boolean值
  • .has()检测集合中是否包含某个元素,返回boolean值
let s = new Set();
let s2 = new Set(['A','B','C','D'])//元素个数
console.log(s2.size) //添加新的元素E
s2.add('E') //删除元素A
s2.delete('A')//检测是否有 C
console.log(s2.has('C')) //清空
s2.clear()console.log(s2)

应用:

let arr = [1,2,3,4,5,4,3,2,1];
//1.数组去重
// let result = [...new Set(arr)];
// console.log(result);//[1, 2, 3, 4, 5]
//2.交集
let arr2 = [4,5,6,5,6];
let s2 = new Set(arr2);//4 5 6
// let result  = [...new Set(arr)].filter(item=>{
//     if(s2.has(item))
//     {
//         return true;
//     }
//     else{
//         return false;
//     }
// })
let result = [...new Set(arr)].filter(item=>s2.has(item))
console.log(result);//[4, 5]
//3.并集
let union = [...new Set([...arr,...arr2])];
console.log(union);//[1, 2, 3, 4, 5, 6]
//4.差集
let diff = [...new Set(arr)].filter(item=>!(s2.has(item)))
console.log(diff);// [1, 2, 3]

12.2 Map

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

Map的属性和方法:

  • .size 获取Map的键值对数量(最外层)
  • .set(key,value) 添加键值对
  • .delete(key) 删除键为key的键值对
  • .get(key) 获取键为key的值
  • for...of 遍历里面的每一个键值对
let m = new Map();
//添加元素
m.set('name','离歌笑');
m.set('lgx',function(){console.log('我可以改变世界');
})
let key = {school:'xianyi'
}
m.set(key,['杭州','长安','仙灵']);//size
console.log(m.size);//删除键为name的键值对,会返回修改后的Map集合
// m.delete(key);
m.delete('name');//获取
console.log(m.get('lgx'));
console.log(m.get(key));//清空
// m.clear();console.log(m);
//遍历里面的每一个键值对
for(let v of m)
{console.log(v);
}

13. 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('华为','2000');
console.log(Huawei);
Huawei.call();//ES6的构造函数 Class
class iPhone{//构造方法,名字不能修改constructor(brand,price){this.brand = brand;this.price = price;}//方法必须使用该语法,不能使用ES5的对象完整形式call(){console.log('我可以打电话');}
}
let onePlus = new iPhone("1+",1999);
onePlus.call();
console.log(onePlus);

结果:

13.1 静态成员

ES5静态成员

function Phone(){}
Phone.iname='手机';//静态成员,不能被实例化对象调用
Phone.change= function(){console.log("我可以改变世界,但是先要改变自己");
}
Phone.prototype.size = '5.5inch';
let nokia = new Phone();
console.log(Phone.iname);//手机
Phone.change();//我可以改变世界,但是先要改变自己
console.log(nokia.iname);//undefined
console.log(nokia.size);//5.5inch

ES6静态成员

class Phone{// 声明静态成员变量static name = '手机';static change(){console.log("我可以改变世界,但是先要改变自己");}
}
let nokia = new Phone();
console.log(nokia.name);//undefined
console.log(Phone.name);//手机

13.2 构造函数继承

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();
//如果利用对象的形式修改了原型对象,别忘了利用constructor指回原来的原型对象
SmartPhone.constructor = SmartPhone;
SmartPhone.prototype.photo = function(){console.log('我可以拍照');
}
SmartPhone.prototype.playGame = function(){console.log('我可以玩游戏');
}let chuizi = new SmartPhone('chuizi',2499,'黑色','5.5inch');
console.log(chuizi);

结果:

13.3 Class类继承

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('我可以玩游戏');}
}
let xiaomi = new SmartPhone('小米',1999,'黑色','4.7inch');
console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();

结果:

13.4 子类对父类方法的重写

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('我可以视频通话');}
}
let xiaomi = new SmartPhone('小米',1999,'黑色','4.7inch');
console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();

结果:

13.5 get和set设置

class Phone{get price(){console.log('价格属性被读取了');return '10000yuan';}set price(newVal){console.log('价格属性被修改了');}
}
//实例化对象
let s = new Phone();
console.log(s.price);//10000yuan
s.price = "free";

结果:


14 数值扩展

// Number.EPSILON是 JavaScript的最小精度,属性的值接近于 2.22044...E-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//1.二进制和八进制
let b = 0b1010;//10  //2进制
let o = 0o777;//511 //8进制
let d = 100   //100  //10进制
let x = 0xff  //255  //16进制
console.log(x);//2.检测一个数是否为有限数
console.log(Number.isFinite(100));//true
console.log(Number.isFinite(100/0));//false
console.log(Number.isFinite(Infinity));//false//3.检测一个数值是否为NaN
console.log(Number.isNaN(123));//false//4.字符串转整数
console.log(Number.parseInt('5454545love'));//5454545
console.log(Number.parseFloat('5.123123神奇'));//5.123123//5.判断是否为整数
console.log(Number.isInteger(5));//true
console.log(Number.isInteger(2.5));//false//6.将小数部分抹除
console.log(Math.trunc(3.5));//3//7.检测一个数到底是正数、负数、还是0
console.log(Math.sign(100));//1
console.log(Math.sign(0));//0
console.log(Math.sign(-20000));//-1

结果:


15.对象方法扩展

//1.Object.is 判断两个值是否完全相等
console.log(Object.is(120,120));//===  //true
console.log(Object.is(isNaN,isNaN));//===  //true
console.log(NaN===NaN);//false//2.Object.assign 对象的合并
const config1={
host:'localhost',
port:'3306',
name:'root',
pass:'root',
test:'test'
}
const config2={
host:'http://xianyi.com',
port:'33060',
name:'xianyi.com',
pass:'lixiaoyao',
}
console.log(Object.assign(config1,config2));//{host: 'http://xianyi.com', port: '33060', name: 'xianyi.com', pass: 'lixiaoyao', test: 'test'}//3.Object.setPrototypeOf 设置原型对象 Object.getPrototypeof
const school = {
name:'离歌笑'
}
const cities = {
renming:['李逍遥','赵灵儿','林月如']
}
Object.setPrototypeOf(school,cities);
console.log(Object.getPrototypeOf(school));//{renming: Array(3)}
console.log(school);//{name: '离歌笑'}

16. 模块化

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。

1. 模块化的好处:

  • 防止命名冲突
  • 代码复用
  • 高维护性
  • 模块化规范产品

2. ES6之前的模块化规范有:

  • CommonJS ====> NodeJS、Browserify
  • AMD ====> requireJS
  • CMD ====> seaJS

3. 语法:

  • 模块功能主要有两个命令构成:exportimport
  • export命令用于规定模块的对外接口
  • import命令用于输入其他模块提供的功能

16.1 暴露语法

16.1.1.分别暴露

// 下面js代码放在./js/m1.js文件中
//分别暴露
export let school = '离歌笑';
export function teach(){console.log('一曲离歌笑江湖');
}
<!-- html代码 -->
<script type="module">
//引入模块化内容
import * as m1 from "./js/m1.js";
console.log(m1);
</script>

 结果:

16.1.2. 统一暴露

let school = '清华大学';
function findjob(){console.log('找工作吧');
}
//统一暴露
export {school, findjob}
<script type="module">  import * as m1 from "./js/m1.js" console.log(m1) console.log(m1.school)m1.findJob()
</script>

结果:

 16.1.3. 默认暴露(多变量暴露)

//默认暴露 export default
export default {school:'清华大学',change:function(){console.log('可以改变人的一生!')}
}
<script type="module">  import * as m1 from "./js/m1.js" console.log(m1.default) console.log(m1.default.school)console.log(m1.default.change())
</script>

结果:

16.2 引入语法

16.2.1. 通用导入方式

import * as m1 from "./js/m1.js"
import * as m2 from "./js/m2.js"
import * as m3 from "./js/m3.js"

 16.2.2. 解构赋值方式

import {school,teach} from "./js/m1.js";
import {school as s ,findJob} from "./js/m2.js";
import {default as m3} from "./js/m3.js";
console.log(school,teach);
console.log(s,findJob);
console.log(m3);

结果:

 16.2.3. 简便形式(只针对默认暴露)

import m3 from "./js/m3.js";
console.log(m3);//{school: '清华大学', change: ƒ}

16.3 模块化方式2

// 下面js代码放在./js/app.js文件中
//入口文件//模块引入
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);
<!-- html代码 -->
<script type="module" src="./js/app.js"></script>

 结果:

 16.4 bael对es6模块化代码转换

Babel概述:
Babel 是一个 JavaScript 编译器;
Babel 能够将新的ES规范语法转换成ES5的语法;
因为不是所有的浏览器都支持最新的ES规范,所以,一般项目中都需要使用Babel进行转换;
步骤:使用Babel转换JS代码——打包成一个文件——使用时引入即可;

步骤

第一步:安装工具babel-cli(命令行工具) babel-preset-env(ES转换工具) browserify(打包工具, 项目中使用的是webpack);

第二步:初始化项目

npm init -y
第三步:安装
npm i babel-cli babel-preset-env browserify -D
第四步:使用babel转换
npx babel js(js目录)  -d dist/js (转化后的js目录) --presets=babel-preset-env

第五步:打包
npx browserify dist/js/app.js -o dist/bundle.js
第六步:在使用时引入bundle.js
<script src="./js/bundle.js" type="module"></script>
转换前后对比:
转换前:
//分别暴露
export let school = '离歌笑';
export function teach(){console.log('一曲离歌笑江湖');
}

转换后:
'use strict';Object.defineProperty(exports, "__esModule", {value: true
});
exports.teach = teach;
//分别暴露
var school = exports.school = '离歌笑';
function teach() {console.log('一曲离歌笑江湖');
}

16.5 ES6模块化引入NPM包

第一步:安装jquery:

npm i jquery

第二步:在app.js使用jquery

//修改背景颜色为粉色
import $ from 'jquery';//const $ = require("jquery");
$('body').css("background","pink");

第三步:重新转换和打包

npx babel js(js目录)  -d dist/js (转化后的js目录) --presets=babel-preset-env

npx browserify dist/js/app.js -o dist/bundle.js


二、ES7新特性

1Array.prototype.includes

概述:
Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值;
判断数组中是否包含某元素,语法:arr.includes(元素值);

const renming = ['李逍遥','赵灵儿','林月如','刘晋元'];
console.log(renming.includes('李逍遥'));//true
console.log(renming.includes('离歌笑'));//false

2、指数操作符

概述:
在 ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同;
幂运算的简化写法,例如:2的10次方:2**10;
//**(指数操作符)
console.log(2**10);//1024
console.log(Math.pow(2,10));//1024

三、ES8的新特性

1async await

概述:
async 和 await 两种语法结合可以让异步代码看起来像同步代码一样;
简化异步函数的写法;

3.1.1async函数

概述:
1. async 函数的返回值为 promise 对象;
2. promise 对象的结果由 async 函数执行的返回值决定;

1.返回的结果不是一个Promise类型的对象,返回的结果就是成功的Promise对象

2.抛出错误,返回的结果是一个失败的Promise

3.返回的结果如果是一个Promise对象,结果成功就是成功,失败就是失败

// async函数
async function fn(){//返回一个字符串// return '离歌笑';//fulfilled//返回的结果不是一个Promise类型的对象,返回的结果就是成功的Promise对象// return; //抛出错误,返回的结果是一个失败的Promise// throw new Error('出错啦!');//返回的结果如果是一个Promise对象return new Promise((resolve,reject)=>{resolve('成功的数据');//fulfilled//   reject('失败的数据');//rejected})
}
const result = fn();
// console.log(result);
//调用then方法
result.then(value=>{console.log(value);
},(reason)=>{console.warn(reason);
})

3.1.2await 表达式

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

//创建Promise对象
const p = new Promise((resolve,reject)=>{// resolve('成功啦哦哦');reject('失败的原因很复杂');
})    //await 要放在async函数中
async function main(){try{const result = await p;console.log(result);}catch(e){console.log(e);//失败的原因很复杂}
}
//调用函数
main();

 3.1.3async 和 await 读取文件

const fs = require('fs');
function readCao(){return new Promise((reslove,reject)=>{fs.readFile('./resource/草.txt',(err,data)=>{if(err){reject(err);}reslove(data);})})
}
function readWuTi(){return new Promise((reslove,reject)=>{fs.readFile('./resource/无题.txt',(err,data)=>{if(err){reject(err);}reslove(data);})})
}
function readTiYanTa(){return new Promise((reslove,reject)=>{fs.readFile('./resource/题雁塔.txt',(err,data)=>{if(err){reject(err);}reslove(data);})})
}async function main(){//文章1try{let cao = await readCao();console.log(cao.toString());}catch(e){console.log(e);}//文章2try{let wuti = await readWuTi();console.log(wuti.toString());}catch(e){console.log(e);}//文章3try{let tiyanta = await readTiYanTa();console.log(tiyanta.toString());}catch(e){console.log(e);}
}
main();

结果:


3.1.4async await 结合发送ajax请求

//发送Ajax请求,返回的结果是Pomise对象
function sendAJAX(url) {return new Promise((resolve,reject)=>{//1.创建对象const xhr = new XMLHttpRequest();//2.初始化xhr.open('GET',url);//3.发送xhr.send();//4.事件绑定xhr.onreadystatechange = ()=>{if(xhr.readyState === 4){if(xhr.status>=200 && xhr.status<300){//成功resolve(xhr.response);}else{//失败reject(xhr.status);}}}})
}//Promise then方法测试
// sendAJAX('https://api.apiopen.top/getJoke').then((value)=>{
//     console.log(value);
// },(reason)=>{
//     console.log(reason);
// })//使用async与await
async function main(){//发送AJAX请求let result =  await sendAJAX('https://api.apiopen.top/getJoke');console.log(result);
}
main();

2、对象方法扩展

Object.values、Object.entries和

Object.getOwnPropertyDescriptors:

1. Object.values()方法:返回一个给定对象的所有可枚举属性值的数组;
2. Object.entries()方法:返回一个给定对象自身可遍历属性 [key,value] 的数组; (对象变数组)
3. Object.getOwnPropertyDescriptors()该方法:返回指定对象所有自身属性的描述对象;
//声明对象
const school = {name:'离歌笑',cities:['杭州','长安','汴梁'],zhiye:['daxia','taifu','gongzhu']
}    //获取对象所有的键
console.log(Object.keys(school));//['name', 'cities', 'zhiye']
//获取对象所有的值
console.log(Object.values(school));//['离歌笑', Array(3), Array(3)]0: "离歌笑"1: (3) ['杭州', '长安', '汴梁']2: (3) ['daxia', 'taifu', 'gongzhu']length: 3[[Prototype]]: Array(0)
//entries
console.log(Object.entries(school));//[Array(2), Array(2), Array(2)]
//创建Map
const m = new Map(Object.entries(school));
console.log(m.get('cities'));//['杭州', '长安', '汴梁']//对象属性的描述对象
console.log(Object.getOwnPropertyDescriptors(school));//{name: {…}, cities: {…}, zhiye: {…}}const obj = Object.create(null,{name:{//设置值value:'离歌笑',writable:true,//值是否可以重写。true|false 默认为falseconfigurable:true,//目标属性是否可以被删除或是否可以再次修改特特性 true|false 默认为falseenumerable:true,//目标属性是否可以被枚举。true|false 默认为false}
})

结果:

五、ES9 新特性

1Rest 参数与 spread 扩展运算符

概述:
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中
为对象提供了 像数组一样的 rest 参数和扩展运算符;

// Rest参数与spread扩展运算符
// Rest 参数与 spread 扩展运算符在 ES6 中已经引入,
// 不过 ES6 中只针对于数组,在 ES9 中为对象提供了像
// 数组一样的 rest 参数和扩展运算符
function connect({name,age,...user}){console.log(name);console.log(age);console.log(user);
}connect({name:'离歌笑',age:20,price:5000,wuli:10000000
})
const skillOne = {x:'仙风云体术'
}
const skillTwo = {z:'醉仙望月步',a:'爱无限'
}
const skillThree = {q:'七诀剑气'
}
const skillFour = {y:'御剑术'
}const lixiaoyao = {...skillOne,...skillTwo,...skillThree,...skillFour};//对象的合并
console.log(lixiaoyao);//{x: '仙风云体术', z: '醉仙望月步', q: '七诀剑气', y: '御剑术'}

结果:


2、正则扩展:命名捕获分组

概述:
ES9 允许命名捕获组使用符号『?』,这样获取捕获结果可读性更强;
//声明一个字符串
let str = '<a href="http://baidu.com">离歌笑</a>';//提取url 与[标签文本]
const reg = /<a href="(.*)">(.*)<\/a>///执行
const result = reg.exec(str);
console.log(result[1]);//http://baidu.com
console.log(result[2]);//离歌笑let str1 = '<a href="http://baidu.com">离歌笑</a>';
const reg1 = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result1 = reg.exec(str1);
// console.log(result1);
console.log(result1.groups.url);//http://baidu.com
console.log(result1.groups.text);//离歌笑

3、正则扩展:反向断言

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

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

4、正则扩展:dotAll 模式

概述:
正则表达式中点.匹配除回车外的任何单字符,标记『s』改变这种行为,允许行终止符出现;
//dot . 元字符 除换行符以外的任意单个字符
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);

结果:

六、ES10 新特性

1Object.fromEntries

概述:
将二维数组或者map转换成对象;
之前学的Object.entries是将对象转换成二维数组;

// Object.fromEntries:将二维数组或者map转换成对象
// 之前学的Object.entries是将对象转换成二维数组
// 此方法接收的是一个二维数组,或者是一个map集合
// 二维数组
const result = Object.fromEntries([
['name','离歌笑'],
['city','长安,余杭,仙灵']
]);
console.log(result);//{name: '离歌笑', city: '长安,余杭,仙灵'}
//Map
const m = new Map();
m.set('name','ligexiao')
console.log(m);//Map(1) {'name' => 'ligexiao'}
const result1 = Object.fromEntries(m);
console.log(result1.name);//ligexiao
console.log(result1);//{name: 'ligexiao'}
//Object.entries ES8
const arr = Object.entries({
name:'绿儿'
});
console.log(arr);

 结果:

2trimStart trimEnd

概述:
去掉字符串前后的空白字符;
//trim
let str = '   ligexiao   ';
console.log(str);//   ligexiao
console.log(str.trim());//ligexiao
console.log(str.trimStart());//ligexiao
console.log(str.trimEnd());//   ligexiao

 结果:

3Array.prototype.flat flatMap

概述:
将多维数组转换成低维数组;
//flat 平
//将多维数组转化为低维数组
// const arr = [1,2,3,[4,5,6]];// [1, 2, 3, 4, 5, 6]
// const arr = [1,2,3,4,[5,6,7,[8,9,0]]];// [1, 2, 3, 4, 5, 6, 7, Array(3)]    Array(3):[8, 9, 0]
const arr = [1,2,3,4,[5,6,7,[8,9,0]]];
//参数为深度,是一个数字
console.log(arr.flat(2));// [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]//flatMap 将map得出的多维数组转化为低维数组
const arr1 = [1,2,3,4];
const result0 = arr1.map(item=>item * 10);//[10, 20, 30, 40]
const result1 = arr1.map(item=>[item*10]);//Array(1), Array(1), Array(1), Array(1)] -> [10][20][30][40]
const result2 = arr1.flatMap(item=>item * 10);//[10, 20, 30, 40]
console.log(result0);
console.log(result1);
console.log(result2);

 结果:

4Symbol.prototype.description

概述:
获取Symbol的描述字符串;
//创建Symbol
let s = Symbol('离歌笑');
console.log(s.description);//离歌笑

七、ES11 新特性

1String.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];
// console.log(arr);

 结果:

2、类的私有属性

概述:
私有属性外部不可访问直接; (可以在内部使用,不能在外部使用)
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','40kg');
console.log(girl);
console.log(girl.name);
console.log(girl.#age);
console.log(girl.#weight);
girl.intro();

3Promise.allSettled

概述:
获取多个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]);
console.log(result);
const res = Promise.all([p1,p2]);//两个都为成功才算成功,一个失败则为失败
console.log(res);

 结果:

调用allSettled方法

调用all方法

4、可选链操作符

概述:
?.
如果存在则往下走,省略对对象是否传入的层层判断;
//?.
function main(config)
{const dbHost = config && config.db && config.db.host;console.log(dbHost);//192.168.0.1const cacheHost = config?.cache?.host;console.log(cacheHost);//192.168.0.2
}
main({db:{host:'192.168.0.1',username:'root'},cache:{host:'192.168.0.2',username:'admin',}
})

5、动态 import 导入

概述:

动态导入模块,什么时候使用时候导入;

html页面:

<script type="module" src="./js/app1.js"></script>
<button id="btn">北京欢迎你</button>

app.js:

//静态import
import * as m1 from './hello.js';
const btn = document.getElementById('btn');
btn.onclick = function(){// m1.hello2();//动态importimport('./hello.js').then(module=>{module.hello();})
}

hello.js:

export function hello(){alert('贝贝 晶晶 欢欢 迎迎 妮妮');
}
export function hello2(){alert('贝贝 晶晶 欢欢 迎迎 妮妮2');
}

6BigInt

概述:
更大的整数;
//大整形
let n = 521n;
console.log(n,typeof(n));//521n 'bigint'//函数:普通整形转大整形
let x = 123;
console.log(BigInt(n));//521n
// console.log(BigInt(1.2)); //出错了,BigInt不能用浮点数计算//用于更大数值的运算
let max = Number.MAX_SAFE_INTEGER;
console.log(max);//9007199254740991
console.log(max+1);//9007199254740992
console.log(max+2);//9007199254740992 出错了max+1为最大计算console.log(BigInt(max));//9007199254740991n
console.log(BigInt(max)+BigInt(1));//9007199254740992n
console.log(BigInt(max)+BigInt(2));//9007199254740993n

 结果:

7globalThis 对象

概述:
始终指向全局对象window;
console.log(globalThis);

 结果:

ES6(ECMAScript6)-ES11 从入门到修仙相关推荐

  1. 有人把编程写成了修仙小说

    很多小伙伴刚开始接触编程的时候,都会觉得学编程非常枯燥,很难入门.但是如果将 编程教材 和 修仙小说 相结合,可能会使你夜不能眠,越学越上瘾! 前两天大雄在线上社群看到有小伙伴分享了两张截图,乍一看还 ...

  2. 绝了!“修仙模式”学编程是什么体验?

    这两天突然有一本书火了,为什么能火? 看看第一章第一节: 不就一修仙小说么,开头也一般般,除了主角名字跟张小凡差个姓之外,也没啥特别啊! 慢着!再仔细看看!什么鬼,JavaScript甲等资质? 原来 ...

  3. 漫谈架构师之路的修仙之法

    从小有一个武侠梦,长大从事了IT,空闲时间看了很多修仙小说.就萌生了一个想法:把IT之路和修仙之路联系到一起. 于是参照<凡人修仙传>的各个修仙阶段,对比IT之路进行了对照,才有了这篇文章 ...

  4. 2年6个月11天,外包到阿里的修仙之路

    前言 估计有同学会有疑问,为什么要精确到天?是为了装逼吗? 答:仅仅是为了证明咱的严谨(其实就是为了装逼) 肯定有同学心里会吐槽:真的是外包吗?估计又是个标题党,吹牛逼,*&¥%¥ 答:真的是 ...

  5. 2 年 6 个月 11 天,外包到阿里的修仙之路!| 原力计划

    作者 | 程序员囧辉 责编 | 王晓曼 出品 | CSDN博客 前言 估计有同学会有疑问,为什么要精确到天?是为了装逼吗? 答:仅仅是为了证明咱的严谨(其实就是为了装逼) 肯定有同学心里会吐槽:真的是 ...

  6. 大数据生态系统 修仙之道 Hadoop Blog

    大数据生态系统 修仙之道 Hadoop Blog @(2019-01-22)[Docs Language:简体中文 & English|Programing Language:Hadoop|W ...

  7. 程序员的修仙之路-筑基篇

    也许很多人都被这个文章的标题吓到.吸引或者迷惑,那我告诉你,这篇文章不是一个程序员的穿越玄幻,不是一个程序员的无聊之谈,里面没有算法公式,亦无程序员的心路历程.它只是一套学习方法与学习工具的使用.这只 ...

  8. 最强Java修仙之路【附赠BAT修炼资源】,这些核心技能是你必须要掌握的!!

    代码尽头谁为峰,一见秃头道成空. 编程修真路破折,一步一劫渡飞升. 众所周知,编程修真有八大境界: Javase-练气筑基 数据库-结丹 web前端-元婴 Javaweb-化神 Javaweb项目-炼 ...

  9. 前端修仙路-Babel 7.x 详解

    前端修仙路-Babel 7.x 详解 前言:Babel 是一个 JavaScript 编译器,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便 ...

最新文章

  1. 【CSS练习】IT修真院--练习4-移动端界面
  2. uva 707(记忆化搜索)
  3. Jquery中正确使用trim方法以及避免遇到坑
  4. 在驱动和应用程序间共享内存
  5. (2)MongoDB副本集自动故障转移原理(含客户端)
  6. C++中的函数汇总(新手必知)!
  7. [置顶] 状态压缩DP 简单入门题 11题
  8. 宏定义与预处理、函数和函数库
  9. shellcraft新姿势
  10. mysql里面可以用正则吗_Mysql中使用正则表达式
  11. python 线程(一)理论部分
  12. cocos2dx 3.x(移动修改精灵坐标MoveTo与MoveBy)
  13. python 简单的接口测试框架
  14. 01 牛顿迭代公式
  15. 用的上的商学课1-50课学习笔记
  16. html 跑步比赛小游戏,跑步比赛小班游戏教案
  17. “蔚来杯“2022牛客暑期多校训练营1 J Serval and Essay(图的启发式合并)
  18. 关系型数据库设计原则
  19. kali下安装gvm(原openvas)
  20. STM32CubeMX学习笔记(9)——I2C接口使用(读写EEPROM AT24C02)

热门文章

  1. 智慧金融系统软件需求规格说明(3.20终版)
  2. Linux系统有哪些?盘点常用的 8 个Linux系统!
  3. pandas常用命令
  4. iphone 扩容测试软件,给iPhone扩容!闪迪手机U盘测评
  5. Java 已知三边求三角形求面积
  6. 计算机网络实验报告哈工大_哈工大计算机网络实验报告之二
  7. Easycwmp_源码分析
  8. 安装sulley注意点
  9. 基于TCP的通信为什么需要RETRY
  10. java503错误是什么_打开网页后出现503 service unavailable等字样,什么意思