Skip to content

JS 元编程 #68

@coconilu

Description

@coconilu

概述

从ES 6开始,我们可以使用 Proxy 和 Reflect 对象来进行元级别编程。

术语

  1. target,用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
  2. handler,包含陷阱(traps)的占位符对象。
  3. traps,提供属性访问的方法。

Proxy

Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。

作用:

  1. 触发陷阱
  2. 转发代理,如果陷阱不设置回调,将会直接作用在target上
  3. 验证
  4. 扩展构造函数
  5. 操作DOM节点
  6. 值修正及附加属性
  7. 通过属性查找数组中的特定对象

Proxy 的使用:

new Proxy(target, handler)

handler 的API:

函数和构造函数相关:
handler.apply(target, thisArg, argumentsList),拦截函数的调用
handler.construct(target, argumentsList, newTarget),拦截new 操作符

对象属性相关:
handler.defineProperty(target, property, descriptor),截对对象的 Object.defineProperty() 操作
handler.getOwnPropertyDescriptor(target, prop),截对对象的 Object.getOwnPropertyDescriptor() 操作
handler.deleteProperty(target, property),拦截对对象属性的 delete 操作
handler.get(target, property, receiver),拦截对对象的读取属性值操作
handler.set(target, property, value, receiver),拦截对对象的设置属性值操作

对象原型相关:
handler.setPrototypeOf(target, prototype),拦截对对象的设置原型操作
handler.getPrototypeOf(target),拦截对对象的获取原型操作

遍历对象相关:
handler.ownKeys(target),拦截对对象遍历键操作,包括Object.getOwnPropertyNames()、Object.getOwnPropertySymbols()、Object.keys()
handler.has(target, prop),拦截对对象的in操作

对象其它相关:
handler.isExtensible(target),拦截对对象的Object.isExtensible()操作
handler.preventExtensions(target),拦截对对象的Object.preventExtensions()操作

Reflect

Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。Reflect不是一个函数对象,因此它是不可构造的。

API:

函数和构造函数相关:
Reflect.apply(target, thisArg, argumentsList)
Reflect.construct(target, argumentsList, newTarget)

对象属性相关:
Reflect.defineProperty(target, property, descriptor)
Reflect.getOwnPropertyDescriptor(target, prop)
Reflect.deleteProperty(target, property)
Reflect.get(target, property, receiver)
Reflect.set(target, property, value, receiver)

对象原型相关:
Reflect.getPrototypeOf(target)
Reflect.setPrototypeOf(target, prototype)

遍历对象相关:
Reflect.has(target, prop)
Reflect.ownKeys(target)

对象其它相关:
Reflect.isExtensible(target)
Reflect.preventExtensions(target)

参考

元编程
Object
Proxy
Reflect

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions