ES6学习笔记

ES6
ECMAScrip?
ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言
ECMA-262?
Ecma 国际制定了许多标准,而 ECMA-262 只是其中的一个.
ECMAScript 与 JavaScript
ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现.
为什么要学习 ES6?
- ES6 的版本变动内容最多,具有里程碑意义;
- ES6 加入许多新的语法特性,编程实现更简单、高效;
- ES6 是前端发展趋势,就业必备技能;
ES6 兼容性
查看网址:http://kangax.github.io/compat-table/es6
前置知识
- JavaScript
- AJAX
- NodeJS
ES6新特性
let
声明局部变量
1
2
3
4let a;
let b,c,d;
let e = 100;
let f = 100,g='test',h=[];不能重复声明
与之相对应 var可以重复声明1
2
3//错误写法
let a = 111;
let b = 222;块级作用域
只在当前代码块生效1
2
3
4
5
6{
var a = 111;
let b = 222;
}
console.log(a);
console.log(b);//报错不存在变量提升
不允许let变量声明之前就调用1
2
3
4console.log(test)//不报错
var test = '111';
console.log(test1)//报错
let test1 = '222';不影响作用域链
1
2
3
4
5
6
7{
let test = 123;
function fn() {
console.log(test);//输出123(正常)
}
fn();
}
const
const 关键字用来声明常量,const 声明有以下特点:
声明必须赋初始值
1
2const A;//错误写法
const B = 12;标识符一般为大写(习惯)
1
2const test = 'test';//不建议
const TEST = 'test';不允许重复声明
1
2const TEST = 'test';
const TEST = 'test1';//错误写法值不允许修改
1
2
3
4
5const TEST = 'test';
TEST = 'test2';//错误写法
const ITEM = [1,2,3];
ITEM.push(4);//允许写法,因为常量存的是ITEM的头指针块儿级作用域(局部变量)
变量解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值
数组的解构赋值
1
2
3const F4 = ["一","二","三","四"];
let [a,b,c,d] = F4;
console.log(a + b + c + d); // 一二三四对象的解构赋值
1
2
3
4
5
6
7
8
9
10
11const F3 = {
name : "大哥",
age : 22,
sex : "男",
xiaopin : function(){ // 常用
console.log("我会演小品!");
}
}
let {name,age,sex,xiaopin} = F3; // 注意解构对象这里用的是{}
console.log(name + age + sex + xiaopin); // 大哥22男
xiaopin(); // 此方法可以正常调用
模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识,特点:
字符串中可以出现换行符
可以使用 ${xxx} 形式引用变量
声明
1
2let string = `我也一个字符串哦!`;
console.log(string);内容中可以直接出现换行符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15//错误写法
//let string1 = '<ul>
// <li>一</li>
// <li>二</li>
// <li>三</li>
// <li>四</li>
// </ul>';
let string2 = `<ul>
<li>一</li>
<li>二</li>
<li>三</li>
<li>四</li>
</ul>`;
console.log(string2);变量拼接
1
2
3let test1 = `AAAAAA`;
let test2 = `${test1}BBBBBB`;
console.log(test2)
简化对象和函数写法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁;
1 | let name = "wx"; |
箭头函数
ES6允许使用箭头(=>)定义函数,箭头函数提供了一种更加简洁的函数书写方式,箭头函数多用于匿名函数的定义
写法&特性
声明
1
2
3
4
5
6
7
8
9
10//正常写法
var fn1 = function (a, b) {
return a + b;
};
//箭头函数写法
var fn2 = (a, b) => {
return a + b;
};
console.log(fn1(1, 2));
console.log(fn2(1, 2));this是静态的
this始终指向函数声明时所在作用域下的this值1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function getName1() {
console.log(this.name);
}
let getName2 = () => {
console.log(this.name);
};
window.name = "wx1";
let person = { name: "wx2" };
getName1();
getName2();
getName1.call(person);
getName2.call(person);不能作为构造实例化对象
1
2
3
4
5
6
7let person = (name, age) => {
this.name = name;
this.age = age;
};
//此处报错
let me = new person("wx", 20);
console.log(me);不能使用 arguments 变量
1
2
3
4
5//错误实例
var fn2 = () => {
console.log(arguments);
};
fn2(1, 2, 3);箭头函数的简写
1
2
3
4
5
6
7
8
9//形参有且只有一个的时候,省略括号()
let add5 = n => {
return n + 5;
};
//当函数体只有一条语句的时候,省略花括号{}
let pow = n => n * n;
console.log(add5(5));
console.log(pow(5));
场景
箭头函数适合与 this 无关的回调. 定时器, 数组的方法回调
箭头函数不适合与 this 有关的回调. 事件回调, 对象的方法
1 回调里的this要使用当前div的this时,而不是window,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<body>
<div id="test1" style="height: 200px; width: 200px; background: #66ccff"></div>
<div id="test2" style="height: 200px; width: 200px; background: #39c5bb"></div>
<script>
let test1 = document.getElementById("test1");
test1.addEventListener("click", function () {
setTimeout(function () {
this.style.background = "red";
}, 2000);
});
let test2 = document.getElementById("test2");
test2.addEventListener("click", function () {
setTimeout(() => {
this.style.background = "red";
}, 2000);
});
</script>
</body>2 回调的简写
1
2
3
4
5
6
7
8
9
10
11
12
13const arr = [1, 2, 3, 4, 5, 6, 7, 8];
const result1 = arr.filter(function (item) {
//返回偶数
if (item % 2 === 0) {
return true;
} else {
return false;
}
});
console.log(result1);
const result2 = arr.filter((item) => item % 2 === 0);
console.log(result2);
中函数参数的默认值
ES允许给函数的参数赋初始值
形参初始值 具有默认值的参数一般位置要靠后(约定俗成)
1
2
3
4
5function add(a, b, c = 10) {
return a + b + c;
}
console.log(add(1, 2, 3));
console.log(add(1, 2));与解构赋值结合
1
2
3
4
5function connect({ host = "127.0.0.1", username, password, port }) {
console.log(host + "," + username + "," + password + "," + port);
}
connect({ host: "baidu.com", username: "root", password: "root", port: 3306 });
connect({ username: "root", password: "root", port: 3306 });
rest参数
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments;
详见
1 | function data1() { |
- rest参数只包括那些没有给出名称的参数,arguments包含所有参数
- arguments 对象不是真正的数组,而rest 参数是数组实例,可以直接应用sort, map, forEach, pop等方法
- arguments 对象拥有一些自己额外的功能
- rest 参数之后不能再有其他参数(即,只能是最后一个参数),否则会报错
- 函数的 length 属性,不包括rest参数。
扩展运算符
...
扩展运算符能将数组转换为逗号分隔的参数序列;
扩展运算符(spread)也是三个点(…)。
它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。
写法
1 | const data = ["一", "二", "三", "四"]; |
应用
数组合并
1
2
3
4
5
6
7const data1 = ["一", "二", "三", "四"];
const data2 = ["1", "2", "3", "4"];
const data12_1 = data1.concat(data2);
const data12_2 = [...data1, ...data2];
console.log(data12_1);
console.log(data12_2);数组克隆
1
2
3
4const data1 = ["一", "二", "三", "四"];
const data2 = [...data1];
console.log(data1);
console.lg(data2);将伪数组转为真正数组
1
2
3
4const divs = document.querySelectorAll("div");
const divArr = [...divs];
console.log(divs);
console.log(divArr);
Symbol
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。
它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
参考
写法
1 | let s1 = Symbol(); |
应用
- 向对象中添加方法1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18let game = {
up: () => console.log("game.up"),
down: () => console.log("game.up"),
};
let methods = {
up: Symbol(),
down: Symbol(),
};
game[methods.up] = function () {
console.log("methods.up");
};
game[methods.down] = function () {
console.log("methods.down");
};
console.log(game); - 向对象中添加方法2
1
2
3
4
5
6
7
8
9
10
11let game = {
up: () => console.log("game.up"),
down: () => console.log("game.up"),
[Symbol()]: function () {
console.log("methods.up");
},
[Symbol()]: function () {
console.log("methods.down");
},
};
console.log(game);
Symbol内置值:
除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行;
内置Symbol的值 | 调用时机 | |
---|---|---|
1 | Symbol.hasInstance | 当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法 |
2 | Symbol.isConcatSpreadable | 对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于 Array.prototype.concat()时,是否可以展开。 |
3 | Symbol.species | 创建衍生对象时,会使用该属性 |
4 | Symbol.match | 当执行 str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值。 |
5 | Symbol.replace | 当该对象被 str.replace(myObject)方法调用时,会返回该方法的返回值。 |
6 | Symbol.search | 当该对象被 str. search (myObject)方法调用时,会返回该方法的返回值。 |
7 | Symbol.split | 当该对象被 str. split (myObject)方法调用时,会返回该方法的返回值。 |
8 | Symbol.iterator | 对象进行 for…of 循环时,会调用 Symbol.iterator 方法,返回该对象的默认遍历器 |
9 | Symbol.toPrimitive | 该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。 |
10 | Symbol.toStringTag | 在该对象上面调用 toString 方法时,返回该方法的返回值 |
11 | Symbol.unscopables 该 | 对象指定了使用 with 关键字时,哪些属性会被 with环境排除。 |
示例1
1
2
3
4
5
6
7
8
9class Person {
static [Symbol.hasInstance](param) {
console.log(param);
console.log("我被用来检测类型了");
return false;
}
}
let o = {};
console.log(o instanceof Person);示例2
1
2
3
4
5const arr = [1, 2, 3];
const arr2 = [4, 5, 6];
// 合并数组:false数组不可展开,true可展开
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));
迭代器
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作
写法
1 | const data1 = ["一", "二", "三", "四"]; |
原理
- 创建一个指针对象,指向当前数据结构的起始位置;
- 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员;
- 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员;
- 每调用 next 方法返回一个包含 value 和 done 属性的对象;
1 | const data1 = ["一", "二", "三", "四"]; |
迭代器自定义遍历对象
1 | const data = { |
生成器
生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同
写法
1 | function* gen() { |
生成器函数的参数传递
1 | function* gen(arg) { |
生成器函数实例
- 异步的回调地狱可以写成为下面格式
1
2
3
4
5
6
7
8
9
10
11
12setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
setTimeout(() => {
console.log(444);
}, 4000);
}, 3000);
}, 2000);
}, 1000);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34function one() {
setTimeout(() => {
console.log(111);
iterator.next();
}, 1000);
}
function two() {
setTimeout(() => {
console.log(222);
iterator.next();
}, 2000);
}
function there() {
setTimeout(() => {
console.log(333);
iterator.next();
}, 3000);
}
function four() {
setTimeout(() => {
console.log(444);
iterator.next();
}, 4000);
}
function* gen() {
yield one();
yield two();
yield there();
yield four();
}
let iterator = gen();
iterator.next(); - 业务流程上的异步流程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30// 模拟获取: 用户数据 订单数据 商品数据
function getUsers() {
setTimeout(() => {
let data = "用户数据";
// 第二次调用next,传入参数,作为第一个的返回值
iterator.next(data); // 这里将data传入
}, 1000);
}
function getOrders() {
setTimeout(() => {
let data = "订单数据";
iterator.next(data); // 这里将data传入
}, 1000);
}
function getGoods() {
setTimeout(() => {
let data = "商品数据";
iterator.next(data); // 这里将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 构造函数: Promise (excutor) {}
Promise.prototype.then 方法
Promise.prototype.catch 方法
1 | const psuc = new Promise(function (resolve, reject) { |
Promise.prototype.then
如果回调函数中返回的结果是非promise类型的数据,状态为成功,返回值为对象的成功值resolved
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16const p = new Promise((resolve, reject) =>
setTimeout(() => resolve("用户数据"), 1000)
);
const result = p.then(
(value) => {
console.log(value);
return "seccess";
},
(reason) => {
console.log(reason);
return "error";
}
);
console.log(result);如果是promise类型的数据,此Promise对象的状态决定上面Promise对象p的状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17const p = new Promise((resolve, reject) =>
setTimeout(() => resolve("用户数据"), 1000)
);
const result = p.then(
(value) => {
console.log(value);
return new Promise((resolve, reject) => {
reject("error");
});
},
(reason) => {
console.log(reason);
}
);
console.log(result);抛出错误
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const p = new Promise((resolve, reject) =>
setTimeout(() => resolve("用户数据"), 1000)
);
const result = p.then(
(value) => {
console.log(value);
throw new Error("失败啦!");
},
(reason) => {
console.log(reason);
}
);
console.log(result);链式调用,解决回调地狱问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23const p1 = new Promise((resolve, reject) =>
setTimeout(() => resolve("用户数据1"), 3000)
);
const p2 = new Promise((resolve, reject) =>
setTimeout(() => resolve("用户数据2"), 1000)
);
const result = p1
.then(
(value) => {
console.log(value);
return p2;
},
(reason) => {}
)
.then(
(value) => {
console.log(value);
return value;
},
(reason) => {}
);
console.log(result);
应用
Promise封装读取文件
一般写法1
2
3
4
5const fs = require("fs");
fs.readFile("../resources/test.txt", (err, data) => {
if (err) throw err;
console.log(data.toString());
});Promise封装后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const fs = require("fs");
const read = new Promise(function (resole, reject) {
fs.readFile("../resources/test.txt", (err, data) => {
if (err) {
reject(err);
} else {
resole(data.toString());
}
});
});
read.then(
(value) => console.log(value),
(reason) => console.log("失败:" + reason.message)
);回调地狱
1
2
3
4
5
6
7
8
9
10const fs = require("fs");
// 2、调用方法,读取文件
fs.readFile("resources/test.txt", (err, data1) => {
fs.readFile("resources/test1.txt", (err, data2) => {
fs.readFile("resources/test2.txt", (err, data3) => {
let result = data1 + data2 + data3;
console.log(result);
});
});
});使用Promise优化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25const fs = require("fs");
new Promise((resolve, reject) => {
fs.readFile("resources/test.txt", (err, data) => {
resolve(data);
});
})
.then((value) => {
return new Promise((resolve, reject) => {
fs.readFile("resources/test1.txt", (err, data) => {
resolve([value, data]);
});
});
})
.then((value) => {
return new Promise((resolve, reject) => {
fs.readFile("resources/test2.txt", (err, data) => {
value.push(data);
resolve(value);
});
});
})
.then((value) => {
console.log(value.join("\r\n"));
});Promise封装Ajax请求
一般写法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.apiopen.top/getJoke"); // 2、初始化
xhr.send(); // 3、发送
xhr.onreadystatechange = function () {
// 判断状态
if (xhr.readyState == 4) {
// 判断响应状态码 200-299
if (xhr.status >= 200 && xhr.status <= 299) {
// 成功
console.log(xhr.responseText);
} else {
// 失败
console.error(xhr.status);
}
}
};Promise封装后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const ajax = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.apiopen.top/getJoke"); // 2、初始化
xhr.send(); // 3、发送
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status >= 200 && xhr.status <= 299) {
console.log(xhr.responseText);
resolve(xhr.responseText);
} else {
reject(xhr.status);
}
}
};
});
ajax.then(
(value) => console.log(value),
(reason) => console.log(reason)
);
catch
1 | const p = new Promise((resolve, reject) => { |
Set
ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator
接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。
基本属性和方法
size | 返回集合的元素个数 |
add | 增加一个新元素,返回当前集合 |
delete | 删除元素,返回 boolean 值 |
has | 检测集合中是否包含某个元素,返回 boolean 值 |
clear | 清空集合,返回 undefined |
基本使用
1 | let s = new Set(); |
Set实践
数组去重
1 | let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]; |
求交集
1 | let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]; |
求差集
1 | let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]; |
求并集
1 | let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]; |
Map
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类
型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历
基本属性和方法
size | 返回 Map 的元素个数 |
set | 增加一个新元素,返回当前 Map |
get | 返回键名对象的键值 |
has | 检测 Map 中是否包含某个元素,返回 boolean 值 |
clear | 清空集合,返回 undefined |
基本使用
1 | // Map集合 |
class类
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。
基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
基本使用
先来看看ES5的写法
1 | // 手机 ES5写法 |
Es6写法
1 | class Phone { |
Class成员
ES5写法
1 | // class静态成员 |
ES6写法
1 | class Phone { |
构造函数继承
ES5构造函数继承
1 | function Phone(brand, price) { |
ES6 class类继承
1 | class Phone { |
重写
1 | class Phone { |
getter和setter设置
1 | class Phone { |
数值扩展
Number.EPSILON
Number.EPSILON 是 JavaScript 表示的最小精度,EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16。
1 | function equal(a, b) { |
进制
1 | let a = 0b1010; //二进制 |
Number.isFinite()
用来检查一个数值是否为有限的
1 | console.log("100\t\t\t", Number.isFinite(100)); |
Number.isNaN() :
用来检查一个值是否为 NaN
1 | console.log("100\t\t\t", Number.isNaN(100)); |
Number.parseInt() & Number.parseFloat()
1 | console.log("100\t\t", Number.parseInt("100")); |
Math.trunc
用于去除一个数的小数部分,返回整数部分
1 | console.log("99.999", Math.trunc(99.999)); |
Number.isInteger
用来判断一个数值是否为整数;
1 | console.log("99", Number.isInteger(99)); |
Math.sign
用来判断一个数是正数 负数还是零
1 | console.log("-99\t", Math.sign(-999)); |
对象扩展
Object.is
比较两个值是否严格相等,与『===』行为基本一致(+0 与 NaN)
1 | console.log(Object.is(100, 100)); |
Object.assign
对象的合并,将源对象的所有可枚举属性,复制到目标对象
1 | const config1 = { |
proto && setPrototypeOf
setPrototypeOf 可以直接设置对象的原型
1 | const obj1 = { |
模块化
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
- 优点
- 防止命名冲突
- 代码复用
- 高维护性
- 模块化规范产品
- CommonJS => NodeJS、Browserify
- AMD => requireJS
- CMD => seaJS
ES6 模块化语法
模块功能主要由两个命令构成:export 和 import
- export 命令用于规定模块的对外接口(导出模块)
- import 命令用于输入其他模块提供的功能(导入模块)
简单使用
test.js
1 | export let name = "test.js"; |
index.js
1 | import * as test from "./test.js"; |
ES6导出数据语法
逐个导出
与上面简单使用的例子一样
统一导出
test.js
1 | let name = "test.js"; |
index.js
1 | import * as test from "./test.js"; |
默认导出
test.js
1 | export default { |
index.js
1 | import * as test from "./test.js"; |
ES6引入数据语法
通用
上面ES6导出数据语法的所有例子都为通用写法
解构赋值形式
- 一般情况
test.jsindex.js1
2
3
4
5let name = "test.js";
function call() {
console.log("you call test.js function");
}
export { name, call };1
2
3import { name, call } from "./test.js";
console.log(name);
call(); - 别名
test1.jstest2.js1
2
3
4
5let name = "test1.js";
function call() {
console.log("you call test1.js function");
}
export { name, call };index.js1
2
3
4
5let name = "test2.js";
function call() {
console.log("you call test2.js function");
}
export { name, call };1
2
3
4
5
6import { name, call } from "./test1.js";
import { name as name1, call as call2 } from "./test2.js";
console.log(name);
call();
console.log(name1);
call2(); - 导入默认导出的模块
test.jsindex.js1
2
3
4
5
6export default {
name: "test.js",
call: function () {
console.log("you call test.js function");
},
};1
2
3import { default as test } from "./test.js";
console.log(test.name);
test.call();
简便形式
只能针对默认暴露
test.js
1 | export default { |
index.js
1 | import test from "./test1.js"; |
整合引入
test1.js
1 | export default { |
test2.js
1 | let name = "test2.js"; |
将js语法整合到一个文件app.js
1 | import test1 from "./test1.js"; |
在index.html引入
1 |
|
Babel对ES6模块化代码转换
安装工具
- 初始化项目
1
npm init -y
- babel-cli(命令行工具)
1
npm i babel-cli babel-preset-env browserify -D
- babel-preset-env(ES转换工具)
1
npx babel src/js -d dist/js --presets=babel-preset-env
- browserify(打包工具,项目中使用的是webpack)
1
npx browserify dist/js/app.js -o dist/bundle.js
操作示例
ES6模块化引入NPM包
例如导入jquery
- 安装 jquery
1
npm i jquery
- 在app.js使用jquery
1
2
3//修改背景颜色为粉色
import $ from 'jquery';// 相当于const $ = require("jquery");
$('body').css('background','pink');
ES7新特性
Array.prototype.includes
判断数组中是否包含某元素,includes 方法用来检测数组中是否包含某个元素,返回布尔类型值。
1 | let arr = [1, 2, 3, 4, 5]; |
指数操作符
在 ES7 中引入指数运算符「」,用来实现幂运算,功能与 Math.pow 结果相同;
幂运算的简化写法,例如:2的10次方:210;
1 | console.log(Math.pow(2,10)) |
ES8新特性
async & await
async 和 await 两种语法结合可以让异步代码看起来像同步代码一样
async 函数
- async 函数的返回值为 promise 对象
- promise 对象的结果由 async 函数执行的返回值决定
1 | async function fn() { |
await 表达式
- await 必须写在 async 函数中
- await 右侧的表达式一般为 promise 对象
- await 返回的是 promise 成功的值
- await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理
1 | // async函数 + await表达式:异步函数 |
async 和 await 读取文件
1 | // 导入模块 |
async 和 await 结合发送ajax请求
1 | let XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; |
对象方法扩展
Object.values
返回一个给定对象的所有可枚举属性值的数组;
1 | // 对象方法扩展 |
Object.entries
返回一个给定对象自身可遍历属性 [key,value]
的数组
1 | // 对象方法扩展 |
Object.getOwnPropertyDescriptors:
返回指定对象所有自身属性的描述对象
1 | let school = { name: "testname", age: 24, sex: "男" }; |
ES9新特性
Rest 参数
1 | function connect({ host, port, ...user }) { |
spread 扩展运算符
1 | const One = { q: "1111" }; |
正则扩展
命名捕获分组
ES9 允许命名捕获组使用符号『?』,这样获取捕获结果可读性更强
1 | let str = '<a href="http://www.baidu.com">百度</a>'; |
反向断言
ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选
1 | let str = "JS5201314你知道么555啦啦啦"; |
dotAll模式
1 | // 正则扩展:dotAll 模式 |
ES10 新特性
fromEntries
将二维数组或者map转换成对象
1 | // 之前学的Object.entries是将对象转换成二维数组 |
trimStart & trimEnd
1 | // trimStart 和 trimEnd |
flat
将高维数组转为低维数组
1 | const arr1 = [1, 2, 3, 4, [5, 6], 7, [8, 9], 0]; |
flatMap
1 | const arr1 = [1, 2, 3, 4]; |
Symbol.prototype.description
获取Symbol的字符串描述
1 | let s = Symbol("test"); |
ES11 新特性
类的私有属性
1 | // 类的私有属性 |
Promise.allSettled
获取多个promise执行的结果集
1 | // 获取多个promise执行的结果集 |
String.prototype.matchAll
用来得到正则批量匹配的结果
1 | // String.prototype.matchAll |
可选链操作符
1 | function main(config) { |
动态 import 导入
动态导入模块,什么时候使用时候导入
test1.js
1 | export function hello() { |
app.js
1 | // import * as m1 from "./hello.js"; // 传统静态导入 |
index.html
1 |
|
BigInt
更大的整数
1 | // BigInt |
globalThis
globalThis 对象 : 始终指向全局对象window
1 | console.log(globalThis); |
感谢查阅