一、认识Proxy
基本形式
new Proxy({},{});
Proxy 可以理解为城墙,外界对该对象进行访问,都必须先通过“城墙”,它可以对外界的访问进行过滤和改写。
Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。
get属性
get属性是在你得到某对象属性值时预处理的方法,有三个参数
target:得到的目标值,对象及其属性值
key:对象的属性
var proxy = new Proxy({
add: function (val) {
return val + 10;
},
age: 18,
name: '勇敢牛牛,不怕困难'
}, {
get:function(target,key){
console.log('Welcome, This is Get');
console.log("target",target);
console.log("key",key);
console.log("target[key]"+target[key]);//属性值
return target[key];
}
});
console.log(proxy);
console.log(proxy.age);
console.log(proxy.name);
set属性
set属性是值你要改变Proxy属性值时,进行的预先处理。它接收四个参数。
value:要改变的值
var proxy = new Proxy({
add: function (val) {
return val + 10;
},
name: '勇敢牛牛,不怕困难'
}, {
get:function(target,key){
console.log('Welcome, This is Get');
return target[key];
},
set:function(target,key,value){
console.log(`setting ${value}`);
return target[key] = value;
}
});
console.log(proxy.name);
proxy.name='牛牛';
console.log(proxy.name);
Proxy拦截
var proxy = new Proxy({
add: function (val) {
return val + 10;
},
name: '勇敢牛牛,不怕困难'
}, {
get: function(target, key) {
if (key in target) {
return target[key];
} else {
throw new ReferenceError("Prop name \"" + key + "\" does not exist.");
}
}
});
console.log( proxy.name);//勇敢牛牛,不怕困难
//没有该属性,访问目标对象不存在的属性,报错 Prop name "age" does not exist.
//如果没有这个拦截函数,访问不存在的属性,会返回undefined。
console.log( proxy.age)
其他方法
apply()、has()、construct()、deleteProperty()、defineProperty()、getOwnPropertyDescriptor() 等,见 阮一峰 es6——proxy详解
二、promise对象
Promise,简单说就是一个容器,它的英文是“承诺”,表示其他手段无法改变,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。一旦状态改变,就不会再变。
基本使用
const promise = new Promise(function(resolve, reject) {
if (/* 异步操作成功 */){
//将Promise对象的状态从“未完成”变为“成功”
//在异步操作成功时调用,并将异步操作的结果,作为参数传递出去
resolve(value);
} else {
//将Promise对象的状态从“未完成”变为“失败”
//在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去
reject(error);
}
});
then方法
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
}
timeout(20).then((value) => {
console.log(value);
});
timeout()返回一个Promise实例,表示一段时间以后才会发生的结果。
过了指定的时间(ms参数)以后,Promise实例的状态变为resolved,
就会触发then方法绑定的回调函数,将在当前脚本所有同步任务执行完才会执行。
其他方法
Promise.prototype.then()、Promise.prototype.catch() 、Promise.prototype.finally()等
三、async 函数—— Generator 函数的语法糖
async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果
async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
基本用法
// 函数声明
async function f() {}
// 函数表达式
const f = async function () {};
// 对象的方法
let obj = { async foo() {} };
obj.f().then(...)
// Class 的方法,不是太理解。。。
class Storage {
constructor() {
this.cachePromise = caches.open('avatars');
}
async getAvatar(name) {
const cache = await this.cachePromise;
return cache.match(`/avatars/${name}.jpg`);
}
}
const storage = new Storage();
storage.getAvatar('jake').then(…);
// 箭头函数
const f = async () => {};
按顺序完成异步操作
async function logInOrder(urls) {
// 并发读取远程URL
const textPromises = urls.map(async url => {
const response = await fetch(url);
return response.text();
});
// 按次序输出
for (const textPromise of textPromises) {
console.log(await textPromise);
}
}
使用fetch方法,同时远程读取一组 URL。
每个fetch操作都返回一个 Promise 对象,放入textPromises数组。
map方法的参数是async,但它是并发执行的,因为只有async函数内部是继发执行,外部不受影响。
后面的for..of循环内部使用了await,因此实现了按顺序输出。
四、认识Module模块(export、import)
export :负责进行模块化,也是模块的输出。
import : 模块的引入
as关键字重命名
使用as关键字,重命名了函数v1和v2的对外接口。重命名后,v2可以用不同的名字输出两次
function v1() { ... }
function v2() { ... }
export {
v1 as streamV1,
v2 as streamV2,
v2 as streamLatestVersion
};
import
import {a} from './xxx.js'
import { a, b} from './xxx.js';
export default 命令——为模块指定默认输出
// 第一组
export default function crc32() { // 输出
}
import crc32 from 'crc32'; // 输入
export default命令用于指定模块的默认输出。
一个模块只能有一个默认输出,因此export default命令只能使用一次。
import命令后面才不用加大括号,因为只可能唯一对应export default命令。
// 第二组
export function crc32() { // 输出
};
import {crc32} from 'crc32'; // 输入