proxy
Proxy 也就是代理,可以帮助我们完成很多事情,例如对数据的处理,对构造函数的处理,对数据的验证,说白了,就是在我们访问对象前添加了一层拦截,可以过滤很多操作,而这些过滤,由你来定义。
let p = new Proxy(target, handler);
参数
target
:需要使用Proxy
包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。handler
: 一个对象,其属性是当执行一个操作时定义代理的行为的函数(可以理解为某种触发器)。具体的handler
相关函数请查阅官网
let xiaohong = {
name: 'xiaohong',
age: 34
}
let xh = new Proxy(xiaohong, {
// target 为对象
// key 为对象的键值
get(target, key){
console.log(`${target[key]} is ${key}`)
return target[key]; // get 的时候需要有返回值
},
// target 为对象
// key 为对象的键值
// value 为需要设置的值
set(target, key, value) {
// console.log(`${target[key]} is ${key} + ${value}`)
target[key] = value;
// return Reflect.set(target, key, value);
return true; // set 只有在返回值为true时,才表示设置成功
}
})
xh.name = 'xiaohong123'
console.log(xh.age)
console.log(xh.name)
reflect
Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。Reflect对象的设计目的有这样几个。
(1) 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。
(2) 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。
(3) 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。
(4)Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。
Reflect对象一共有 13 个静态方法。
- Reflect.apply(target, thisArg, args)
- Reflect.construct(target, args)
- Reflect.get(target, name, receiver)
- Reflect.set(target, name, value, receiver)
- Reflect.defineProperty(target, name, desc)
- Reflect.deleteProperty(target, name)
- Reflect.has(target, name)
- Reflect.ownKeys(target)
- Reflect.isExtensible(target)
- Reflect.preventExtensions(target)
- Reflect.getOwnPropertyDescriptor(target, name)
- Reflect.getPrototypeOf(target)
- Reflect.setPrototypeOf(target, prototype)
上面这些方法的作用,大部分与Object对象的同名方法的作用都是相同的,而且它与Proxy对象的方法是一一对应的。
promise
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
Promise对象有以下两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
注意,为了行文方便,本章后面的resolved统一只指fulfilled状态,不包含rejected状态。
有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。
Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
如果某些事件不断地反复发生,一般来说,使用 Stream 模式是比部署Promise更好的选择。
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
set / map
Set 是ES6提供的新的数据结构,它类似于数组,但是成员都是唯一的,没有重复值。Set中的成员可以是数组,数字,字符串,甚至是对象,不需要像数组一样,必须所有的字段类型相同。
WeakSet的结构与Set类似,也不是重复值的集合,和Set的区别主要有三点:
- WeakSet 中的成员只能是对象,不能是其他类型
- WeakSet中的对象都是弱引用,垃圾回收机制不考虑WeakSet对该对象的引用,当不使用时,垃圾回收机制会直接回收该对象
- WeakSet不可遍历
Set实例的属性:
- Set.propotype.constructor
- Set.propotype.size
Set实例的方法:
- Set.propotype.add(value);
- Set.propotype.delete(value);
- Set.propotype.has(value);
- Set.propotye.clear();
Set实例遍历的方法:
- Set.prototype.keys();
- Set.prototype.values();
- Set.prototype.entries();
- Set.prototype.forEach();
WeakSet的方法:
- WeakSet.prototype.add(value);
- WeakSet.prototype.delete(value);
- WeakSet.prototype.has(value);
JavaScript对象本质上是键值对的集合(Object), 本质上是键值对的集合。但是传统上只能用字符串当键,这对它的使用带来很大的限制。因此,ES6提供了Map结构,类似于数组,也是键值对的集合,但是键不限于字符串,各种类型的值都可以当作键。
let map = new Map();
map.set('name', 'beebo');
Map实例的属性:
- map.size
- Map.prototype.set(key, vaule);
- Map.prototype.get(key);
- Map.prototype.has(key);
- Map.prototype.delete(key);
- Map.prototype.clear();
Map实例的遍历方法:
- Map.prototype.keys();
- Map.prototype.values();
- Map.prototype.entries();
- Map.prototype.forEach();
Map与其他数据结构的转换
- Map转数组 — 扩展运算符 […map]
- 数组转Map — 将数组传入Map的构造函数中
- Map转对象
- 对象转Map
- Map转JSON
- JSON转Map