ES6

1. let

1.1 let 变量声明及声明特性

let 用来声明变量,具有以下特性:

一、相较于 var ,let 变量不能重复声明

let a = 'a';
let a = 'a'; // 此时会报错

二、块级作用域(es5 中共有三种作用域:全局、函数、eval),即 let 定义的变量只在块级作用域内有效

{
let a = 'a';
}
console.log(a); // is not defined

三、不存在变量提升

console.log(a);		// cannot access 'a' before initialization
let a = 'a';

四、不影响作用域链

{
let a = 'a';
function func(){
console.log(a);
}
func();
}

1.2 let 经典案例实践

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>切换颜色</title>
<style>
body{
margin: 0;
padding: 0;
background: #ccc;
}
h2{
margin: 10px;
font-size: 40px;
}
.item{
display: flex;
float: left;
margin: 20px;
border: 2px solid #000;
width: 200px;
height: 100px;
background: #fff;
}
</style>
</head>
<body>
<h2>
点击切换颜色
</h2>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<script>
var items = document.getElementsByClassName('item');
/*
for(var i = 0; i < items.length; i++){
items[i].onclick = function(){
this.style.background = 'pink';
}
}
*/
//使用 let 代替上述 Code
for(let i = 0; i < items.length; i++){
items[i].onclick = function(){
items[i].style.background = 'pink';
}
}
</script>
</body>
</html>

2. const

2.1 const 变量声明及声明特性

一、必须要赋初始值

二、一般常量使用大写(非必须)

三、常量的值不能修改

四、块级作用域

五、对于数组和对象的元素修改不算对常量的修改,不会报错

const TEAM = ['a', 'b'];
TEAM.push('c');
// TEAM = 100; 这句话会报错

3.变量的解构赋值

ES6 允许按照一定模式从数组和对象中提取一些值,对变量进行赋值

3.1数组的解构

const arr = ['a', 'b', 'c', 'd'];
// 定义四个变量,依次对应上面数组的值
let [A, B, C, D] = arr;
console.log(A);
console.log(B);
console.log(C);
console.log(D);

3.2对象的解构

const obj = {
str: 'abc',
num: 25,
fun: function(){
console.log("Output");
}
}
// 与上面的 Code 格式相同,都要使用花括号
let {str, num, fun} = obj;
console.log(str);
console.log(num);
console.log(fun); fun();
/*
let {fun} = obj;
fun();
*/

4.模板字符串

一、声明上,相比 ES5,ES6 引入了新的字符串声明符号——反引号,与单双引号区别不大。

二、反引号中的内容可以直接出现换行符,举例,

let str = `abc
def
ghi`;
console.log(str);

三、变量拼接

let s1 = "Hello,";
let s2 = `${s1}World!`;
console.log(s2);

5.对象的简化写法

ES6 允许在大括号里面直接写入变量和函数,作为对象的属性和方法。

let name = "user";
let func = function(){
console.log("abc");
}
const obj = {
name,
func
}
console.log(obj);

还有方法声明的简化,

const obj1 = {
name: "abc",
improve: function(){
console.log("abc");
}
}
// 以下为简化版
const obj2 = {
name: "def",
improve(){
console.log("def");
}
}

6.箭头函数

6.1箭头函数及声明特点

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

let func = (a, b) => {
return a + b;
}
func(1, 1);

箭头函数的特性:

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

function getName1(){
console.log(this.name);
}
let getName2 = () => {
console.log(this.name);
} window.name = "abc";
const obj = {
name: "def"
} // 直接调用函数
getName1(); //> abc
getName2(); //> abc //call 方法调用
getName1.call(obj); //> def
getName2.call(obj); //> abc

二、不能作为构造函数实例化对象

let Person = (name, age) => {
this.name = name;
this.age = age;
}
let me = new Person('abc', 20);
console.log(me); // 报错

三、不能使用 arguments 变量(该变量一般用来保存实参)

四、箭头函数简写

(1)当形参有且仅有一个时,可以省略小括号;

let add = n => {
return n + n;
}
console.log(add(1));

(2)当代码体仅有一条语句时,可以同时省略花括号和 return 语句;

let pow = n => n*n;
console.log(pow(2));

6.2箭头函数的实践与应用

例一,点击 div 2s 后变色

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
body{
margin: 0;
padding: 0;
background: #ccc;
}
div{
width: 200px;
height: 200px;
background: #58a;
}
</style>
</head>
<body>
<div id="ad"></div>
<script>
let ad = document.getElementById('ad');
ad.addEventListener("click", function(){
/* 方法一
let _this = this;
setTimeout(function(){
_this.style.background = 'pink';
}, 2000);
*/
setTimeout(() => {
this.style.background = 'pink';
}, 2000);
});
</script>
</body>
</html>

例二,从数组中返回偶数元素

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
body{
margin: 0;
padding: 0;
background: #ccc;
}
div{
width: 200px;
height: 200px;
background: #58a;
}
</style>
</head>
<body>
<div id="ad"></div>
<script>
let ad = document.getElementById('ad');
ad.addEventListener("click", function(){
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);
});
</script>
</body>
</html>

由此可得以下结论,

一、箭头函数适合与 this 无关的回调(定时器、数组等)

二、箭头函数不适合与 this 有关的回调(DOM 事件回调、对象方法等)

7.函数参数的默认值设置

7.1形参的初始值

function add(a, b, c){
return a + b + c;
}
let result1 = add(1, 2);
console.log(result1); //> NaN function sub(a, b, c = 10){
return c - b - a;
}
let result2 = sub(1, 2);
console.log(result2); //> 7

带默认参数的函数的位置一般靠后。

7.2与解构赋值结合

function connect({host="127.0.0.1", username, password, port}){
console.log(host);
console.log(username);
console.log(password);
console.log(port);
}
connect({
// host: 'localhost',
username: 'root',
password: 'root',
port: 3306
})

8. rest 参数

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

function date1(){
console.log(arguments);
}
date('abc','def','ghi'); // 对象 function date2(...args){
console.log(args);
}
date('abc','def','ghi'); // 数组

利用 rest 创造的数组就可以使用与数组相关的 API 方法,如 filter,some,every,map 等。

rest 参数必须要放到参数的最后,例如,

function fun(a, b, ...args){
console.log(a); //> 1
console.log(b); //> 2
console.log(args); //> [3, 4, 5, 6]
}
fun(1, 2, 3, 4, 5, 6);

9.扩展运算符( ... )

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

const arr = ['abc', 'def', 'ghi'];
function fun(){
console.log(arguments);
}
fun(arr); //> 0: ['abc', 'def', 'ghi']
fun(...arr); //> 0: 'abc' 1: 'def' 2: 'ghi'

应用:

一、数组的合并

const arr1 = ['abc', 'def'];
const arr2 = ['123', '456']; //ES5
const arr3 = arr1.concat(arr2);
console.log(arr3); //ES6
const arr4 = [...arr1, ...arr2];
console.log(arr4);

二、数组的克隆

const arr1 = ['abc', 'def'];
const arr2 = [...arr1];

-----》(引用数据问题?)《-----

三、将伪数组转换为真正的数组

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div></div>
<div></div>
<div></div>
<script>
const divs = document.querySelectorAll('div')
console.log(divs); // 对象 const divArr = [...divs];
console.log(divArr); // 数组
</script>
</body>
</html>

10. Symbol 数据类型

ES6 引入了一种新的原始数据类型——Symbol,用来表示独一无二的值。

它是 JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。

10.1特点

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

二、Symbol 的值不能与其他数据进行运算

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

10.2创建 Symbol

// 方法一,此时 Symbol 是一个函数
let s1 = Symbol();
console.log(s1, typeof s1); //> Symbol() 'symbol' let s2 = Symbol('abc');
let s3 = Symbol('abc');
console.log(s2 === s3); //> false // 方法二,此时 Symbol 是一个对象
let s4 = Symbol.for('abc');
console.log(s4, typeof s4); //> Symbol(abc) 'symbol' let s5 = Symbol.for('abc');
let s6 = Symbol.for('abc');
console.log(s5 === s6); //> true
总结:JavaScript 的七种数据类型 “USONB”

U:undefined S:string symbol O:object N:null number B:boolean

10.3给对象添加 Symbol 类型的属性

let obj = {
name: 'abc'
};
let ud = {
up: Symbol(),
down: Symbol()
};
obj[ud.up] = function(){
console.log("up");
}
obj[ud.down] = function(){
console.log("down");
}
let obj = {
name: 'abc',
[Symbol('say')]: function(){
console.log("def");
},
[Symbol('sby')]: function(){
console.log("ghi");
}
}
console.log(obj);

10.4 Symbol 内置值

所谓内置值,即为 Symbol 对象的属性(共 11 个)。

内置值 描述
Symbol.hasInstance 当其他对象调用 instanceof 运算符,判断是否为该对象的实例时,回调用这个方法
Symbol.isConcatSpreadable 对象的该属性等于的是一个布尔值,表示该对象用于 Array.prototype.concat() 时,是否可以展开
Symbol.unscopables 该对象指定了使用 with 关键字时,哪些属性会被 with 环境排除
Symbol.match 当执行 str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值
Symbol.replace 当该对象被 str.replace(Object) 方法调用时,会返回该方法的返回值
Symbol.search 当该对象被 str.search(Object) 方法调用时,会返回该方法的返回值
Symbol.split 当该对象被 str.split(Object) 方法调用时,会返回该方法的返回值
Symbol.iterator 对象进行 for...of 循环时,会调用 Symbol.iterator 方法,返回该对象的默认遍历器
Symbol.toPrimitive 该对象被转为原始类型的值,会调用这个方法,返回该对象对应的原始类型值
Symbol.toStringTag 在该对象上面调用 toString 方法时,返回该方法的返回值
Symbol.species 创建衍生对象时,会使用该属性
10.4.1 Symbol.hasInstance
class Person{
static [Symbol.hasInstance](param){
console.log(param);
console.log("abc"); //> abc
//return true;
}
}
let o = {};
console.log(o instanceof Person); //> false
10.4.2 Symbol.isConcatSpreadable
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
arr2[Symbol.isConcatSpreadable] = false; //不可展开
const arr3 = arr1.concat(arr2);
console.log(arr3); //> [1, 2, 3, [4, 5, 6]]
console.log(arr3.length); //> 4

11.迭代器

迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。

任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。

12.生成器

13. Promise*

Promise 是 ES6 引入异步编程的新解决方案。

语法上,Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。

(关于异步编程,主要指的是 IO 的代码,包括文件IO、数据库IO、网络请求IO等)

13.1实例化 Promise 对象

对象的三种状态:初始化,成功,失败。

const p = new Promise(function(resolve, reject){
// 封装异步操作
setTimeout(function(){
let data = '数据库中的用户数据';
resolve(data);
let err = '数据读取失败';
reject(err);
}, 1000);
}); // 调用 Promise 对象的 then 方法
p.then(function(value){
// 异步成功执行
console.log(value);
}, function(reason){
// 异步失败执行
console.error(reason);
});

13.2使用 Promise 封装读取文件

(注:涉及 Node.js)

// 1.引入 fs 模块
const fs = require('fs'); // 2.调用方法
fs.readFile('./aha/aaa.md', (err, data)=>{
//err:报错 data:读取结果
if(err) throw err;
console.log(data); //> <Buffer 61 61 61 09 e4 b8 80 e4 ba 8c e4 b8 89>
console.log(data.toString()); //> aaa 一二三
}); // 3.使用 Promise 封装
const p = new Promise(function(resolve, reject){
fs.readFile("./aha/aaa.md", (err, data)=>{
if(err) reject(err);
resolve(data);
});
});
p.then(function(value){
console.log(value.toString()); //> aaa 一二三
}, function(reason){
console.log("读取失败!!");
});

(上述 Code 在 PowerShell 中,使用 node FileName.js 命令调试)

13.3使用 Promise 封装 Ajax 请求

const p = new Promise((resolve, reject)=>{
// 1.创建对象
const xhr = new XMLHttpRequest(); // 2.初始化
xhr.open("GET", "https://api.apiopen.top/getJoke"); // 3.发送
xhr.send(); // 4.绑定事件,处理响应结果
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
// 判断响应状态码 200-299表示成功
if(xhr.status >= 200 && xhr.status < 300){
resolve(xhr.response);
}else{
reject(xhr.status);
}
}
}
});
// 指定回调
p.then(function(value){
console.log(value);
}, function(reason){
console.err(reason);
});

13.4 Promise.prototype.then 方法

const p = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('用户数据');
}, 1000)
});
// 调用 then 方法
const result = p.then(value => {
console.log(value);
}, reason => {
console.log(reason);
});
console.log(result);

then 方法的返回结果是 Promise 对象,对象状态由回调函数的执行结果决定。

一、如果回调函数中返回结果是非 Promise 类型的数据,此时状态为成功。

二、如果是 Promise 对象,则按该 Promise 的情况返回成功或失败。

三、抛出(throw)错误,此时状态为失败。

此时说明 then 方法可以链式调用。

13.5实践练习

多文件读取。

const fs = require("fs");

fs.readFile('./aaa.aaa', (err, data1)=>{
fs.readFile('./bbb.bbb', (err, data2)=>{
fs.readFile('./ccc.ccc', (err, data3)=>{
let result = `${data1}\r\n${data2}\r\n${data3}`;
console.log(result);
});
});
}); // 使用 Promise 实现
const p = new Promise((resolve, reject) => {
fs.readFile("./aaa.aaa", (err, data) => {
resovle(data);
});
}); p.then(value => {
console.log(value.toString());
return new Promise((resolve, reject) => {
fs.readFile("./bbb.bbb", (err, data) => {
resolve([value, data]);
});
})
}).then(value => {
console.log(value.toString());
return new Promise((resolve, reject) => {
fs.readFile("./ccc.ccc", (err, data) => {
// 压入
value.push(data);
resolve(value);
});
})
}).then(value => {
console.log(value.join('\r\n'));
})

13.6 catch 方法

const p = new Promise((resolve, reject) => {
setTimeout(() => {
reject("ERROR");
}, 1000)
}); p.then(function(value){
console.log(value);
}, function(reason){
console.err(reason);
}) p.catch(function(reason){
console.warn(reason);
})

14. Set

14.1集合 Set 的创建与方法

ES6 提供了新的数据结构——Set(集合),它类似于数组,但成员的值是唯一的。

集合实现了 iterator 接口,所有可以使用扩展运算符与for...of遍历。

方法 描述
size 返回集合的元素个数
add 增加一个新元素并返回当前集合
delete 删除元素并返回当前集合
has 检测集合中是否包含某个元素并返回 boolean 值
clear 清空当前集合并返回 undefined
let s = new Set();
console.log(typeof s); //> 'object' // Set 内可传入数组或可迭代数据
let s2 = new Set(['abc', 'def', 'abc']);
console.log(s2); //> {'abc', 'def'} (会自动去重) console.log(s2.size); //> 2
s2.add('ghi');
console.log(s2); //> {'abc', 'def', 'ghi'}
s2.delete('abc');
console.log(s2); //> {'def', 'ghi'}
console.log(s2.has('def')); //> true
s2.clear();
console.log(s2); //> undefined let s3 = new Set(['123', '456', '789']);
// 遍历集合
for(let v of s3){
console.log(v);
}

14.2集合 Set 的实践

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

15. Map

ES6 提供了 Map 数据结构,它类似于对象,也是键值的集合。

“键”的范围不局限于字符串。

Map 也实现了 iterator 接口,所有可以使用扩展运算符与for...of遍历。

方法 描述
size 返回 Map 的元素个数
set 增加一个新元素,返回当前 Map
get 返回键名对象的键值
has 检测 Map 中是否包含某个元素并返回 boolean 值
clear 清空 Map 内所有元素并返回 undefined
let m = new Map();

// 添加元素
m.set('name', 'abc');
m.set('change', function(){
console.log("123");
});
let key = {
school: 'def'
};
m.set(key, ['A', 'B']);
console.log(m); // 元素个数
console.log(m.size); //> 3 // 删除元素
m.delete('name');
console.log(m); // 获取
console.log(m.get(key)); // 遍历
for(let v of m){
console.log(v);
} // 清空
m.clear();

16. Class

17.数值扩展

17.1 Number.EPSILON

Number.EPSILON 是 JavaScript 表示的最小精度

console.log(0.1 + 0.2 === 0.3);	//> false
function equal(a, b){
if(Math.abs(a - b) < Number.EPSILON){
return true;
}else{
return false;
}
}
console.log(equal(0.1 + 0.2, 0.3)); //> true

17.2二、八、十、十六进制

//二进制
let b = 0b1010;
console.log(b); //> 10 //八进制
let o = 0o1010;
console.log(o); //> 520 //十进制
let d = 1010;
console.log(d); //> 1010 //十六进制
let x = 0x1010;
console.log(x); //> 4112

17.3 Number.isFinite

Number.isFinite 检测一个数是否为有限数

console.log(Number.isFinite(100));		//> true
console.log(Number.isFinite(100/0)); //> false

17.4 Number.isNaN

Number.isNaN 检测一个数是否为 NaN

17.5字符串转整数 / 浮点数

Number.parseInt Number.parseFloat

console.log(Number.parseFloat('12.34aaa'));	//> 12.34

17.6 Number.isInteger

Number.isInteger 检测一个数是否为整数

17.7 Math.trunc

Math.trunc 将数字的小数部分删除

17.8 Math.sign

Math.sign 检测一个数是正数、负数还是零

console.log(Math.sign(10));		//> 1
console.log(Math.sign(-10)); //> -1
console.log(Math.sign(0)); //> 0

18.对象方法的扩展

18.1 Object.is

Object.is 判断两个值是否完全相等

console.log(Object.is(1, 1));	//> true
console.log(Object.is(1, 2)); //> false // 与 === 的区别
console.log(Object.is(NaN, NaN)); //> true
console.log(NaN === NaN); //> false

18.2 Object.assign

Object.assign 对象的合并

const config1 = {
host: 'localhost',
port: 3306,
user: 'name'
};
const config2 = {
host: 'xxx.com',
port: 33060
};
// config2 覆盖 config1
console.log(Object.assign(config1, config2));
/*
输出结果:
{host: 'xxx.com', port: 33060, user: 'name'}
*/

18.3关于原型对象

Object.setPrototypeOf 设置原型对象

Object.getPrototypeOf 获取原型对象

const obj1 = {
a : 'abc'
}
const obj2 = {
b : ['1', '2', '3']
}
Object.setPrototypeOf(obj1, obj2);
console.log(obj1);
console.log(Object.getPrototypeOf(obj1));

19.模块化

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

19.1好处

(1)防止命名冲突

(2)代码复用

(3)高维护性

19.2模块化规范产品

(1)CommonJS => NodeJS、Browserify

(2)AMD => requireJS

(3)CMD => seaJS

19.3 ES6 模块化语法

19.3.1 export 和 import

模块化功能主要由两个命令构成:export 和 import。

export 命令用于规定模块的对接口。(暴露)

import 命令用于输入其他模块提供的功能。(导入)

// File name: m1.js
// 分别暴露
export let school = 'abc';
export function fun(){
console.log("output");
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="module">
// 引入 m1.js 模块
import * as mdl from "./src/js/m1.js";
</script>
</body>
</html>
19.3.2暴露模块数据语法汇总
19.3.2.1分别暴露
// File name: m1.js

export let school = 'abc';
export function fun(){
console.log("output");
}
19.3.2.2统一暴露
// File name: m2.js
let school = 'abc';
function fun(){
console.log("output");
} export { school, fun };
19.3.2.3默认暴露
// File name: m3.js

export default{
school: 'abc',
change: function(){
console.log("output");
}
}
19.3.3导入模块数据语法汇总
19.3.3.1通用导入
<script type="module">
import * as m1 from "./src/js/m1.js";
</script>
19.3.3.2解构赋值形式导入
<script type="module">
import { school, fun } from "./src/js/m1.js"; // 变量重名处理方法
// 使用 as 将重名的键取别名化处理
import { school as school2, fun } from "./src/js/m2.js"; // 导入默认暴露的方法
import { default as m3 } from "./src/js/m3.js";
</script>
19.3.3.3简便形式导入(仅针对默认暴露)
<script type="module">
import m3 from "./src/js/m3.js";
</script>
19.3.4浏览器使用 ES6 模块化方式

通过新建 JavaScript 入口文件来导入模块。

// File name: app.js
import * as m1 from "./m1.js";
<script src="./src/js/app.js" type="module">
</script>
19.3.5 babel 对 ES6 模块化代码的转换

转换:

babel src/js -d dist/js --presets=babel-preset-env

打包:

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

导入:

<script src="dist/bundle.js"></script>

19.4模块化引入 npm 包(涉及 jQuery,跳过)

npm i jquery

ES7

20. ES7 新特性

20.1 Array.Prototype.includes

includes 方法用来检测数组中是否包含某个元素并返回 boolean 值。

const a = ['a', 'b', 'c'];
console.log(a.includes('a')); //> true
console.log(a.includes('d')); //> false

20.2指数操作符

ES7 引入指数操作符( ** )用来实现幂运算,功能与 Math.pow 结果相同。

console.log(2**4);		//> 16
console.log(4**0.5); //> 2

ES8

21. async 与 await

async 和 await 两种语法结合可以让异步代码像同步代码一样。

21.1 async 函数

一、async 函数的返回值为 Promise 对象

//
async function fun(){
return 'abc';
}
const result1 = fun();
console.log(result1); //
async function fun(){
throw new Error("W");
}
const result2 = fun();
console.log(result2); //
async function fun(){
return new Promise((resolve, reject) => {
resolve('Success');
});
}
const result3 = fun();
console.log(result3);
result3.then(value => {
console.log(value);
}, reason => {
console.log(reason);
})

(1)如果返回的结果不是一个 Promise 类型的对象,那么 Promise 的结果就是成功。

(2)当抛出错误时,Promise 就是失败。

(3)如果返回的结果是一个 Promise 类型的对象

二、Promise 对象的结果由 async 函数执行的返回值决定

21.2 await 表达式

一、await 必须写在 async 函数中

二、await 右侧的表达式一般为 Promise 对象

三、await 返回的是 Promise 成功的值

四、await 的 Promise 失败了,就会抛出异常,需要通过 try...catch 捕获处理

// 成功
const p = new Promise((resolve, reject) => {
resolve("Success");
});
async function fun(){
let result = await p;
console.log(result);
}
fun();
// 失败
const p = new Promise((resolve, reject) => {
reject("Wrong");
});
async function fun(){
try{
let result = await p;
console.log(result);
}catch(e){
console.log(e);
}
}
fun();

21.3 async 和 await 结合读取文件

const fs = require("fs");

function reada(){
return new Promise((resolve, reject) => {
fs.readFile("./aaa.aaa", (err, data) => {
if(err) reject(err);
resovle(data);
})
})
}
function readb(){
return new Promise((resolve, reject) => {
fs.readFile("./bbb.bbb", (err, data) => {
if(err) reject(err);
resovle(data);
})
})
}
function readc(){
return new Promise((resolve, reject) => {
fs.readFile("./ccc.ccc", (err, data) => {
if(err) reject(err);
resovle(data);
})
})
} async function fun(){
let aa = await reada();
let bb = await readb();
let cc = await readc(); console.log(aa.toString());
console.log(bb.toString());
console.log(cc.toString());
}
fun();

21.4 async 和 await 封装 Ajax 请求

发送 Ajax 请求并返回 Promise 对象。

function sendAjax(url){
return new Promise((resolve, reject) => {
// 1.创建对象
const xhr = new XMLHttpRequest(); // 2.初始化
xhr.open('GET', url); // 3.发送
xhr.send(); // 4.事件绑定
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(x.status >=200 && x.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 fun(){
let result = await sendAjax("https://api.apiopen.top/getJoke");
console.log(result);
}
fun();

22.对象方法扩展

22.1 Object.values

Object.values() 方法返回一个给定对象的所有可枚举属性值的数组。

const obj = {
name: 'abc',
age: 20
};
// 获取对象所有键
console.log(Object.keys(obj));
// 获取对象所有键值
console.log(Object.values(obj));

22.2 Object.entries

Object.entries() 方法返回一个给定对象自身可遍历属性 [ key , value ] 的数组。

const obj = {
name: 'abc',
age: 20
};
console.log(Object.entries(obj));

由此可以看出,该方法有利于创建 Map 数据结构。

const obj = {
name: 'abc',
age: 20
};
const m = new Map(Object.entries(obj))
console.log(m);

22.3 Object.getOwnPropertyDescriptors

该方法返回指定对象所有自身属性的描述对象。

const obj = {
name: 'abc',
age: 20
};
console.log(Object.getOwnPropertyDescriptors(obj));
const obj = Object.create(null, {
name: {
//设置值
value: 'abc',
//设置属性特性
writable: true, // 可写
configurable: true, // 可删
enumerable: true // 可枚举
}
});
console.log(Object.getOwnPropertyDescriptors(obj));

ES9

23.扩展运算符与 rest 参数

ES9 为对象提供了像数组一样的扩展运算符和 rest 参数。

function connect({host, port, ...user}){
console.log(host);
console.log(port);
console.log(user);
}
connect({
host: '127.0.0.1',
port: 3306,
username: 'root',
password: 'root'
});
const obj1 = {
a: 'a'
}
const obj2 = {
b: 'b'
}
const obj3 = {
c: 'c'
}
const tot = {...obj1, ...obj2, ...obj3};
console.log(tot);

24.正则扩展

24.1命名捕获分组

// 未进行命名捕获分组
let str = '<a href="https://www.xxx.com">xxx</a>'; // 提取 url 与标签文本
const reg = /<a href="(.*)">(.*)<\/a>/; // 执行
const result = reg.exec(str);
console.log(result); // groups 是 undefined 状态
console.log(result[1]); //> https://www.xxx.com
console.log(result[2]); //> xxx
// 进行命名捕获分组
let str = '<a href="https://www.xxx.com">xxx</a>';
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result = reg.exec(str);
console.log(result); // groups 被定义
console.log(result.groups.url); //> https://www.xxx.com
console.log(result.groups.text); //> xxx

24.2反向断言

断言:判断匹配结果正确与否。

let str = 'J123aaa456bbb';
// 正向断言
const reg1 = /\d+(?=b)/;
const res1 = reg1.exec(str);
console.log(res1); // 反向断言
const reg2 = /(?<=a)\d+/;
const res2 = reg2.exec(str);
console.log(res2);

24.3 dotAll 模式

dot 是指正则表达式中的元字符( . ),代表除换行符以外任意单个字符

let str = `
<ul>
<li>
<a>AAA</a>
<p>aaa</p>
</li>
<li>
<a>BBB</a>
<p>bbb</p>
</li>
</ul>`; // g/s :模式修正符
// g: 全局匹配
// s: dot 匹配任意字符
const reg = /.<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs; let result;
let arr = [];
while(result = reg.exec(str)){
console.log(result);
arr.push({
x: result[1],
y: result[2]
});
}
console.log(arr);

编辑于 2022/9/17

-End-

ES6~ES9的更多相关文章

  1. ES6、ES7、ES8、ES9、ES10

    ES6新特性(2015) ES6的特性比较多,在 ES5 发布近 6 年(2009-11 至 2015-6)之后才将其标准化.两个发布版本之间时间跨度很大,所以ES6中的特性比较多.在这里列举几个常用 ...

  2. ES6、ES7、ES8、ES9、ES10新特性

    ES6新特性(2015) ES6的特性比较多,在 ES5 发布近 6 年(2009-11 至 2015-6)之后才将其标准化.两个发布版本之间时间跨度很大,所以ES6中的特性比较多. 在这里列举几个常 ...

  3. javascript的ES6学习总结(第二部分)

    1.数组循环 介绍数组循环之前,先回顾一下ES5数组的循环 (1)数组遍历(代替普通的for):arr.forEach(callback(val,index,arr){todo}) //val是数组的 ...

  4. javascript的ES6学习总结(第一部分)

    ES6(ESNext学习总结——第一部分) ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准,2015.06 发版. ECMA每年6月份,发布一个版本 201 ...

  5. ES9新内容概括

    本文主要介绍ES2018 新出的一些特性 1.异步迭代 允许 async/await 与 for-of 一起使用,以串行的方式运行异步操作,达到异步函数的迭代效果. async function pr ...

  6. ES6语法知识

    let/const(常用) let,const用于声明变量,用来替代老语法的var关键字,与var不同的是,let/const会创建一个块级作用域(通俗讲就是一个花括号内是一个新的作用域) 这里外部的 ...

  7. ES9新特性

    这篇文章主要介绍ES2018(ES9)的新特性, 以及使用方法 JS是一门跨平台的语言, ES6也就是ECMAScript 2015 花费了5年的时间敲定, 是一次非常大的改版, 之后每年都有一个小版 ...

  8. 谈谈 ES7、ES8、ES9 和 Stage 3 的那些事儿

    ES6 作为多年来 JavaScript 的重大版本变革,受到 JavaScript 开发者们的普遍欢迎. 也正是从 ES6 (ES2015) 开始,JavaScript 版本发布变为年更,即每年发布 ...

  9. 细解JavaScript ES7 ES8 ES9 新特性

    题记:本文提供了一个在线PPT版本,方便您浏览 细解JAVASCRIPT ES7 ES8 ES9 新特性 在线PPT ver 本文的大部分内容译自作者Axel Rauschmayer博士的网站,想了解 ...

  10. javascript的ES6学习总结(第三部分)

    1.ES6中的面向对象的类 1.1.定义类 在ES5中,我们写一个类,通常是这么写的 function Person(name,age){ this.name = name; this.age = a ...

随机推荐

  1. [Linux] Linux 自动挂载mount --bind 实现类似目录硬链的效果 (包含ZFS方案)

    说明 这个命令用以将一个目录挂载到另一个目录,以实现类似于硬链的操作 但是这个命令只是在内存中建立了一个映射,重启系统之后挂载就消失了 而linux是不支持目录硬链的,具体原因见linux为什么不能硬 ...

  2. 【架构师视角系列】QConfig配置中心系列之Server端(三)

    声明 原创文章,转载请标注.https://www.cnblogs.com/boycelee/p/17993697 <码头工人的一千零一夜>是一位专注于技术干货分享的博主,追随博主的文章, ...

  3. great [ɡreɪt] ɡr 然后 eɪt 单词发音 r和前面的辅音连读

    great [ɡreɪt] ɡr 然后 eɪt 单词发音 r和前面的辅音连读

  4. 关于初始化page入参的设计思路

    最近在重构老的代码,在写的过程中发现之前的逻辑如果遇到没有入参pageNo会Npe,于是乎我想找找公司项目有啥方式处理page入参的有两种如下 使用三元表达式直接判断是否null,然后赋值 使用map ...

  5. linux下find命令根据系统时间查找文件用法

    find 命令有几个用于根据您系统的时间戳搜索文件的选项.这些时间戳包括 mtime 文件内容上次修改时间 atime 文件被读取或访问的时间 ctime 文件状态变化时间 mtime 和 atime ...

  6. 25_H.264编码

    本文主要介绍一种非常流行的视频编码:H.264. 计算一下:10秒钟1080p(1920x1080).30fps的YUV420P原始视频,需要占用多大的存储空间? (10 * 30) * (1920 ...

  7. ts-对象数组reduce-数组转对象数组

    将字符串数组转化成{name:xxx,count:xxx}[]数组的代码 #定义数据类型 interface CartInfo{ name:string, count:number } let raw ...

  8. Jest快速使用指南

    1. 引言 写了几个函数,怎么知道写得对不对呢? 可以通过测试函数,当然开发中测试的意义不只是这个 Jest是常用的JavaScript测试框架 官网为:Jest · Delightful JavaS ...

  9. 记录--uni-app在不同平台下拨打电话

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 场景 在App中拨打电话是一个比较常见的应用场景,但是我们通过搜索文章,发现,大部分的博文都是uni-app官网的copy, copy u ...

  10. 大模型时代的PDF解析工具

    去年(2023年)是大模型爆发元年.但是大模型具有两个缺点:缺失私有领域知识和幻觉.缺失私有领域知识是指大模型训练时并没有企业私有数据/知识,所以无法正确回答相关问题.并且在这种情况下,大模型会一本正 ...