本文总结ECMAScript6相关实用特性
目录
let和const
箭头函数
class
对象字段
模板字符串
解构赋值
函数参数扩展
迭代器for...of
模块加载
map和weakmap
set和weakset
对象代理
Symbol数据类型
类型方法的扩展
Promise规范
async和await
Fetch
-
let 声明变量
const 声明常量
两者没有作用域提升 -
箭头函数不存在this调用模式的问题,函数在哪儿定义的this就是这个上下文
var fn = () => { console.log(this); } -
基本使用
class Demo {
constructor(a, b) { // 构造函数
this.a = a; // 实例属性
this.b = b;
}
get myA () { // getter
return this.a;
}
fn() { // 自定义函数
console.log(11);
}
static staticFn() { // 静态函数
console.log(22);
}
}
const demo = new Demo(1, 2);
console.log(demo.b);
console.log(demo.myA);
demo.fn();
Demo.staticFn();
类继承
子类没有构造函数
class Demo1 extends Demo {
fn() {
console.log(this.a);
}
}
const demo1 = new Demo1(1);
demo1.fn();
子类有构造函数
class Demo1 extends Demo {
constructor(a, b) {
super(a, b)
}
fn() {
console.log(this.a);
super.fn(); // 父类中的方法
}
}
const demo1 = new Demo1(1);
demo1.fn(); -
var handler = 'aa'
var obj = {
__proto__: {}, // 设置原型对象
handler, // 对象字段简写
toString() { // 重写toString方法,使用super调用原型中的方法
return "d " + super.toString();
},
[ 'prop_' + (() => 42)() ]: 42 // 字段名,使用表达式计算
}; -
var a = 11, b = 22;
var str = ` ${a} + ${b} = ${a + b} `; -
数组解构 var [a, , b] = [1,2,3]; // a -> 1 b -> 3
对象解构
var {a: a1, b: b1, c: {d: c1}} = {
a: 1, b: 2, c: { d: 3 }
}; // a1 -> 1 b1 -> 2 c1 -> 3
简写
var {a, b, c: {d}} = {
a: 1, b: 2, c: { d: 3 }
}; // a -> 1 b -> 2 c -> 3
函数解构
function fn({a}){
console.log(a); // 1
}
fn({a: 1}); -
默认值
function fn(a, b=10){ // b如果没传默认10
console.log(a + b);
}
fn(1);
参数rest
function fn(a, ...b){
console.log(a + b.length); // b接受剩余参数,生成一个数组
}
fn(1, 2, 3, 4, 5);
参数spread
function fn(a, b, c){
console.log(a + b + c);
}
fn(...[1,2,3]); -
能够使用迭代器for...of进行迭代的结构必定是iterable结构
最基本的iterable结构
function* fn() {
yield 1;
yield 2;
yield 3;
}
for(let item of fn()) {
console.log(item);
break; // 关闭迭代器
}
内置iterable结构:数组,字符串,map,set...
使用generators
写法一
function* fn() {
let [prev, curr] = [0, 1];
while(true) {
[prev, curr] = [curr, prev + curr];
yield curr;
}
}
for(let item of fn()) {
console.log(item);
if(item >= 1000) {
break;
}
}
写法二
var obj = {
[Symbol.iterator]: function* fn() {
let [prev, curr] = [0, 1];
while(true) {
[prev, curr] = [curr, prev + curr];
yield curr;
}
}
}
for(let item of obj) {
console.log(item);
if(item >= 1000) {
break;
}
}
原始写法
let obj = {
[Symbol.iterator]() {
let pre = 0, cur = 1;
return {
next() {
[pre, cur] = [cur, pre + cur];
return {
done: false,
value: cur
}
}
}
}
}
for (var item of obj) {
if (item > 1000) break;
console.log(item);
} -
导出
test.js
export function fn () {}
export let a = 1;
test1.js
export * from 'test.js' // 导出test.js中所有成员
export let b = 2;
test2.js
export default {}
导入
import { fn, a } from "test.js"
import * as obj from "test.js"
import obj from "test2.js" -
map
[[ 1, 'one' ],[ 2, 'two' ]] 这种结构就是map,相当于是对象的另一种表现形式
基本使用
var map = new Map();
map.set("name", "ye");
map.set("age", "11");
console.log(map.get("name"));
console.log(map.size);
遍历map
遍历键值对
for(var [key, value] of map) {
console.log(key + "|" + value);
}
等价于
for(var [key, value] of map.entries()) {
console.log(key + "|" + value);
}
遍历键
for(var key of map.keys()){
console.log(key);
}
遍历值
for(var value of map.values()){
console.log(value);
}
weakmap
weakmap和map类似,只不过键必须是引用类型,如果没有外部强引用此键,存储的键会被垃圾回收机制回收
基本使用
var key = {}
var wMap = new WeakMap();
wMap.set(key, "ye");
console.log(wMap.get(key));
wMap.delete(key);
console.log(wMap.has(key)); -
set
和数组类似,不过成员是不重复的,如果添加重复的值无效
基本使用
const set = new Set([1,2,3,4,5]);
set.add(6);
set.add(6); // 无效
console.log(set.size);
set.delete(6);
console.log(set.has(6));
set.clear(); // 清空set
遍历set
const set = new Set([1,2,3,4,5]);
for(let item of set) {
console.log(item);
}
set.forEach((a,b,c) => {
// a,b都表示元素,c表示set本身
console.log(a, b, c);
}) set转化成array
let arr = Array.from(set);
let arr = [...set]; WeakSet 和set类似,不过成员是引用
const wSet = new WeakSet();
var obj = {}
wSet.add(obj);
wSet.delete(obj);
console.log(wSet.has(obj)); -
对象代理的作用就像土豪的管家一样
基本使用
var obj = {
a: 11
}
var guanjia = new Proxy(obj, {
// 代理处理函数
get: function(target, name) {
console.log(target, name); // target是原对象,name是属性名
return name
}
})
console.log(guanjia.a);
in操作符使用
var guanjia = new Proxy(obj, {
get: function(target, name) {
return name in target? target[name]: "没有此属性"
}
})
console.log('b' in guanjia); false // 属性是否存在
console.log(guanjia.'b'); "没有此属性"
给函数写代理
var fn = function() {
console.log("函数");
}
var guanjia = new Proxy(fn, {
apply: function(target, ...args) {
// 调用fn之前触发
target();
console.log(args[1]);
}
})
guanjia("a", "b", "c"); -
Symbol用来获取一个独一无二的值
const symbol = Symbol("myFirstSymbol"), symbol1 = Symbol("myFirstSymbol");
console.log(typeof symbol); // symbol
console.log(symbol.toString()); // Symbol(myFirstSymbol)
console.log(symbol === symbol1) // false const symbol2 = Symbol.for("myFirstSymbol"), symbol3 = Symbol.for("myFirstSymbol");
console.log(symbo2 === symbol3) // true 注意:symbol作为对象的属性,无法使用for...in遍历,另外JSON.stringify对此属性也无法访问 -
Number.isInteger(1.1) 判断是否是整数
"abcd".includes("cd"); 字符串是否包含指定字符
"abc".repeat(3); 字符串重复
Array.from(new Set()); 转数组
Array.of(1); 创建数组
[0, 0, 0, 0].fill(7, 1); 数组填充,第一参数是要填充的元素,第二个参数是开始填充的索引
[1, 2, 3, 3].find(x => x == 3); 找出第一个满足添加的元素
[1, 2, 3, 3].findIndex(x => x == 3); 找出第一个满足添加的元素的索引 -
function fn (duration = 0) {
return new Promise((resolve, reject) => {
setTimeout(function() {
resolve("执行成功" + duration);
}, duration)
})
}
fn(1000).then(data => {
console.log(data);
return fn(1000);
}).then(() => {
throw new Error("故意抛出的错误");
}).catch(err => {
return Promise.all([fn(1000), fn(2000)]);
}).then(data => {
console.log(data);
}) -
async和await就是用同步的方式来写异步
(async ()=>{
await new Promise((resolve, reject) => {
setTimeout(function() {
console.log("执行成功1");
resolve();
}, 2000)
});
console.log("执行成功2");
})()
输出结果:
执行成功1
执行成功2 -
fetch("http://localhost:8000/test", {
method: 'GET'
}).then(res => res.json()).then(data => {
console.log(data);
}).catch(data => {
console.log(data);
})