最近公司在组织前端团队学习JavaScript高级程序设计(第四版)。这两天把第九章看完了,如下是精简版的学习笔记:前端
proxy是代理的意思, 能够经过 构造函数 Proxy,给目标对象targetObj建立一个代理对象。api
const proxyObj = new Proxy(targetObj, handlerObj)
能够给对象obj建立一个代理。数组
当对代理对象进行一些对象操做时,会先执行代理中handlerObj对象定义的方法。app
好比:ide
get( ) // 取对象属性 set( ) // 往对象中添加属性
对代理对象执行操做,会走handler里的方法函数
对源对象执行操做,不会走handler里的方法学习
const target = {foo: "bar"} const handler = { get(target, prop, receiver){ // get()是一个捕获器,其参数分别表明:目标对象、目标属性、代理对象。每一个捕获器入参不一样。 return "handle override" } } const proxyObj = new Proxy(target,handler) console.log(proxyObj.foo) // "handle override",执行handler console.log(target.foo) // "bar",没有执行handler
是一个全局的Reflect对象,全部捕获的方法都有对应的Reflect api方法。它与捕获器拦截的方法同名、行为相同。this
Reflect api 不限于捕获处理程序handler设计
大多数Reflect api在Object上有对应的方法。代理
有了Reflect后,能够方便写捕获器。
看例子:
const target = {foo: "bar"} const handler = { get(target, prop, receiver){ return Reflect.get(...arguments) } } const proxyObj = new Proxy(target,handler)
Reflect api会提供一些状态标记。
Reflect.set() ,Reflect.defineProperty()会返回布尔值。
Reflect api可利用一等函数替换操做符。Reflect.has( )
const obj = {name: "cc"} const target = Object.create(obj) target.age = 12 if(Reflect.has(target, "name")) { // 亲测和对象的in操做符效果相同,均可以获取对象原型链上的属性 console.log("wow, I have!") }
以上,写捕获器的时候能够用,利用它的返回值,在对象上也能够用
代理能够捕获13中不一样的基础api。
get() 获取属性时
set() 设置属性值
has() 对象执行in操做时
defineProperty( )
getOwnPropertyDescriptor()
deleteProperty()
ownKeys()
getPrototypeOf()
setPropotypeOf()
isExtensible()
preentExtensions()
apply()
construct()
经过捕获get、set 和has 等操做,能够知道对象属性何时被访问、被查询。
set()里面写捕获器,验证对象的赋值操做是否合法
例子:
setObjDataEmpty = (paramObj) => { const proxy = new Proxy(paramObj, { set(target, prop) { const oldVal = target[prop] if(typeof oldVal === "string") { // 字符串,直接赋值 return Reflect.set(...arguments) }else if(Array.isArray(oldVal)){ return Reflect.set(target, prop, []) // 数组,置空 }else{ return false // 都不是,赋值失败 } } }) Object.keys(proxy).forEach(key => { proxy[key] = "" }) return proxy }
consructor = () => { class SetId { constructor(id) { this.id = id } } const pSetId = new Proxy(SetId, { construct(target, argumentList) { if(argumentList[0] === undefined) { throw("oh, you must put id!") }else{ return Reflect.construct(...arguments) } } }) const id1 = new pSetId("1") console.log(id1) // {id: '1'} const id2 = new pSetId() // Uncaught oh, you must put id! console.log(id2) }
const userList = []; class User { constructor(name) { this.name = name; } } const proxy = new Proxy(User, { construct() { const newUser = Reflect.construct(...arguments); userList.push(newUser); return newUser; } }); new proxy('John'); new proxy('Jacob'); new proxy('Jingleheimerschmidt'); console.log(userList);