《javascript高级程序设计》学习笔记 | 9.2.代理捕获器与反射方法
发布于 3 年前 作者 simon9124 1376 次浏览 来自 分享

关注前端小讴,阅读更多原创技术文章

代理捕获器与反射方法

  • 代理可以捕获13 种不同的基本操作,代理对象上执行的任一种操作只会有一种捕获处理程序被调用,不存在重复捕获现象
  • 只要在代理上操作,所有捕获器都会拦截对应的反射 API 操作

相关代码→

get()

  • 获取属性值的操作中被调用,对应的反射 API 方法为Reflect.get(target, property, receiver)
    • 返回值
      • 无限制
    • 拦截的操作
      • proxy.property
      • proxy[property]
      • Object.create(proxy)[property]
      • Reflect.get(proxy,property,receiver)
    • 捕获器处理程序参数
      • target:目标对象
      • property:目标对象的键属性(字符串键或符号键)
      • receiver:代理对象或继承代理对象的对象
    • 捕获器不变式
      • 如果target.property不可写且不可配,处理程序返回值必须target.property匹配
      • 如果target.property不可配置且[[Get]]特性为undefined,处理程序返回值必须undefined
const myTarget = {
  foo: 'bar',
}
const proxy = new Proxy(myTarget, {
  get(target, property, receiver) {
    console.log(target) // { foo: 'bar' },目标对象
    console.log(property) // 'foo',目标对象键属性
    console.log(receiver) // { foo: 'bar' },代理对象
    return Reflect.get(...arguments)
  },
})
console.log(proxy.foo) // 'bar',拦截的操作

// 捕获器不变式
Object.defineProperty(myTarget, 'foo', {
  configurable: false, // 不可配置
})
const proxy2 = new Proxy(myTarget, {
  get() {
    return 'baz' // 试图重写
  },
})
console.log(proxy2.foo) // TypeError

set()

  • 设置属性值的操作中被调用,对应的反射 API 方法为Reflect.set(target, property, value, receiver)
    • 返回值
      • 布尔值,true 成功 / false 失败(严格模式下抛出 TypeError)
    • 拦截的操作
      • proxy.property = value
      • proxy[property] = value
      • Object.create(proxy)[property] = value
      • Reflect.get(proxy,property,receiver) = value
    • 捕获器处理程序参数
      • target:目标对象
      • property:目标对象的键属性(字符串键或符号键)
      • value:要赋给属性的值
      • receiver:接收最初赋值的对象
    • 捕获器不变式
      • 如果target.property不可写且不可配,则不能修改目标属性的值
      • 如果target.property不可配置且[[Set]]特性为undefined,则不能修改目标属性的值
      • 严格模式下,处理程序返回false会抛出 TypeError
const myTarget2 = {}
const proxy3 = new Proxy(myTarget2, {
  set(target, property, value, receiver) {
    console.log(target) // {},目标对象
    console.log(property) // 'foo',目标对象键属性
    console.log(value) // 'baz',要赋给属性的值
    console.log(receiver) // {},接收最初赋值的对象
    console.log(Reflect.set(...arguments)) // true,操作成功
    return Reflect.set(...arguments)
  },
})
proxy3.foo = 'baz' // 拦截的操作
console.log(proxy3.foo) // 'baz'
console.log(myTarget2.foo) // 'baz',赋值转移到目标对象上

// 捕获器不变式
Object.defineProperty(myTarget2, 'foo', {
  configurable: false, // 不可配置
  writable: false, // 不可重写
})
const proxy4 = new Proxy(myTarget2, {
  set() {
    console.log(Reflect.set(...arguments)) // false,操作失败
    return undefined
  },
})
proxy4.foo = 'bar'
console.log(proxy4.foo) // 'baz'
console.log(myTarget2.foo) // 'baz'

has()

  • in 操作符中被调用,对应的反射 API 方法为Reflect.has(target, property)
    • 返回值
      • 布尔值,表示属性是否存在,非布尔值会被转型为布尔值
    • 拦截的操作
      • property in proxy
      • property in Object.create(proxy)
      • with(proxy) {(property)}
      • Reflect.has(proxy,property)
    • 捕获器处理程序参数
      • target:目标对象
      • property:目标对象的键属性(字符串键或符号键)
    • 捕获器不变式
      • 如果target.property存在且不可配置,则处理程序必须返回true
      • 如果target.property存在且目标对象不可扩展,则处理程序必须返回true
const myTarget3 = { foo: 'bar' }
const proxy5 = new Proxy(myTarget3, {
  has(target, property) {
    console.log(target) // { foo: 'bar' },目标对象
    console.log(property) // 'foo',目标对象键属性
    console.log(Reflect.set(...arguments)) // true,属性存在
    return Reflect.set(...arguments)
  },
})
'foo' in proxy5 // 拦截的操作

// 捕获器不变式
Object.defineProperty(myTarget3, 'foo', {
  configurable: false, // 不可配置
})
const proxy6 = new Proxy(myTarget3, {
  has() {
    return false // 试图返回false
  },
})
'foo' in proxy6 // TypeError

defineProperty()

  • Object.defineProperty()中被调用,对应的反射 API 方法为Reflect.defineProperty(target, property, descriptor)
    • 返回值
      • 布尔值,表示属性是否成功定义,非布尔值会被转型为布尔值
    • 拦截的操作
      • Object.defineProperty(proxy, property, descriptor)
      • Reflect.defineProperty(proxy, property, descriptor)
    • 捕获器处理程序参数
      • target:目标对象
      • property:目标对象的键属性(字符串键或符号键)
      • descriptor:描述符对象(描述符对象的属性:configurableenumerablewritablevaluegetset的一个或多个)
    • 捕获器不变式
      • 如果目标对象不可扩展,则无法定义属性
      • 如果目标对象有一个可配置的属性,则不能添加同名的不可配置属性
      • 如果目标对象有一个不可配置的属性,则不能添加同名的可配置属性
const myTarget4 = {}
const proxy7 = new Proxy(myTarget4, {
  defineProperty(target, property, descriptor) {
    console.log(target) // {},目标对象
    console.log(property) // 'foo',目标对象键属性
    console.log(descriptor) // { value: 'bar' },描述符对象
    console.log(Reflect.defineProperty(...arguments)) // true,属性定义成功
    return Reflect.defineProperty(...arguments)
  },
})
Object.defineProperty(proxy7, 'foo', { value: 'bar' }) // 拦截的操作
console.log(proxy7.foo) // 'bar'
console.log(myTarget4.foo) // 'bar'

// 捕获器不变式
Object.defineProperty(myTarget4, 'fox', {
  value: 'baz',
  configurable: false, // 不可配置
})
const proxy8 = new Proxy(myTarget4, {
  defineProperty() {
    return true
  },
})
Object.defineProperty(proxy8, 'fox', {
  value: 'qux',
  configurable: true,
  writable: true,
}) // TypeError

getOwnPropertyDescriptor()

  • Object.getOwnPropertyDescriptor()中被调用,对应的反射 API 方法为Reflect.getOwnPropertyDescriptor(target, property)
    • 返回值
      • 属性的描述符对象,属性不存在时返回undefined
    • 拦截的操作
      • Object.getOwnPropertyDescriptor(proxy, property)
      • Reflect.getOwnPropertyDescriptor(proxy, property)
    • 捕获器处理程序参数
      • target:目标对象
      • property:目标对象的键属性(字符串键或符号键)
    • 捕获器不变式
      • 如果自有的target.property存在且不可配置,则处理程序必须返回一个表示该属性存在的对象
      • 如果自有的target.property存在且可配置,则处理程序必须返回该属性可可配置的对象
      • 如果自有的target.property存在且目标对象不可扩展,则处理程序必须返回一个表示该属性存在的对象
      • 如果target.property不存在且目标对象不可扩展,则处理程序必须返回undefined表示改属性不存在
      • 如果target.property不存在,则处理程序不能返回表示该属性存在的对象
const myTarget5 = { foo: 'bar' }
const proxy9 = new Proxy(myTarget5, {
  getOwnPropertyDescriptor(target, property) {
    console.log(target) // { foo: 'bar' },目标对象
    console.log(property) // 'foo',目标对象键属性
    console.log(Reflect.getOwnPropertyDescriptor(...arguments)) // { value: 'bar', writable: true, enumerable: true, configurable: true },属性的描述符对象
    return Reflect.getOwnPropertyDescriptor(...arguments)
  },
})
Object.getOwnPropertyDescriptor(proxy9, 'foo') // 拦截的操作

// 捕获器不变式
Object.defineProperty(myTarget5, 'fox', {
  value: 'baz', // 目标对象的属性存在
  configurable: false, // 不可配置
})
const proxy10 = new Proxy(myTarget5, {
  getOwnPropertyDescriptor() {
    // return undefined // TypeError,必须返回一个表示该属性存在的对象
    return {
      value: 'baz',
      writable: false,
      enumerable: false,
      configurable: false,
    }
  },
})
Object.getOwnPropertyDescriptor(proxy10, 'fox')

deleteProperty()

  • delete 操作符中被调用,对应的反射 API 方法为Reflect.deleteProperty(target, property)
    • 返回值
      • 布尔值,表示删除属性是否成功,非布尔值会被转型为布尔值
    • 拦截的操作
      • delete proxy.property
      • delete proxy[property]
      • Reflect.delete(proxy,property)
    • 捕获器处理程序参数
      • target:目标对象
      • property:目标对象的键属性(字符串键或符号键)
    • 捕获器不变式
      • 如果target.property存在且不可配置,则处理程序不能删除这个属性
const myTarget6 = { foo: 'bar' }
const proxy11 = new Proxy(myTarget6, {
  deleteProperty(target, property) {
    console.log(target) // { foo: 'bar' },目标对象
    console.log(property) // 'foo',目标对象键属性
    console.log(Reflect.deleteProperty(...arguments)) // true,删除属性成功
    return Reflect.deleteProperty(...arguments)
  },
})
delete proxy11.foo // 拦截的操作
console.log(proxy11.foo) // undefined
console.log(myTarget6.foo) // undefined

// 捕获器不变式
Object.defineProperty(myTarget6, 'fox', {
  value: 'baz', // 目标对象的属性存在
  configurable: false, // 不可配置
})
const proxy12 = new Proxy(myTarget6, {
  deleteProperty() {
    console.log(Reflect.deleteProperty(...arguments)) // false,删除属性失败
    return Reflect.deleteProperty(...arguments)
  },
})
delete proxy12.fox
console.log(proxy12.fox) // 'baz'
console.log(myTarget6.fox) // 'baz'

ownKeys()

  • Object.keys()及类似方法中被调用,对应的反射 API 方法为Reflect.ownKeys(target)
    • 返回值
      • 必须返回包含字符串或符号的可枚举对象
    • 拦截的操作
      • Object.getOwnPropertyNames(proxy)
      • Object.getOwnPropertySymbols(proxy)
      • Object.keys(proxy)
      • Reflect.ownKeys(proxy)
    • 捕获器处理程序参数
      • target:目标对象
    • 捕获器不变式
      • 返回的可枚举对象必须包含target所有不可配置的自有属性
      • 如果target不可扩展,则返回可枚举对象必须准确包含自有属性键
Object.defineProperty(myTarget7, 'fox', {
  value: 'baz',
  configurable: false, // 不可配置
})
const proxy14 = new Proxy(myTarget7, {
  ownKeys() {
    // return [] // TypeError: 'ownKeys' on proxy: trap result did not include 'fox',必须包含目标对象所有不可配置的自有属性
    return ['fox', 'qux'] // 必须包含fox键
  },
})
Object.keys(proxy14)

getPrototypeOf()

  • Object.getPrototypeOf()中被调用,对应的反射 API 方法为Reflect.getPrototypeOf(target)
    • 返回值
      • 必须返回对象或 null
    • 拦截的操作
      • Object.getPrototypeOf(proxy)
      • Reflect.getPrototypeOf(proxy)
      • proxy.__proto__
      • Object.prototype.isPrototyprOf(proxy)
      • proxy instanceof Object
    • 捕获器处理程序参数
      • target:目标对象
    • 捕获器不变式
      • 如果target不可扩展,则Object.getPrototypeOf(proxy)唯一有效的返回值就是Object.getPrototypeOf(target)的返回值
const myTarget8 = new Array(1, 2, 3)
const proxy15 = new Proxy(myTarget8, {
  getPrototypeOf(target) {
    console.log(target) // [ 1, 2, 3 ],目标对象
    console.log(Reflect.getPrototypeOf(...arguments)) // Array的原型对象,可在浏览器中查看
    return Reflect.getPrototypeOf(...arguments)
  },
})
Object.getPrototypeOf(proxy15) // 拦截的操作

// 捕获器不变式
Object.preventExtensions(myTarget8) // 不可扩展
const proxy16 = new Proxy(myTarget8, {
  getPrototypeOf(target) {
    // return [] // TypeError,唯一有效的返回值是Object.getPrototypeOf(target)的返回值
    return Object.getPrototypeOf(target) // 有效
  },
})
Object.getPrototypeOf(proxy16)

setPrototypeOf()

  • Object.setPrototypeOf()中被调用,对应的反射 API 方法为Reflect.setPrototypeOf(target, prototype)
    • 返回值
      • 布尔值,表示原型赋值是否成功,非布尔值会被转型为布尔值
    • 拦截的操作
      • Object.setPrototypeOf(proxy)
      • Reflect.setPrototypeOf(proxy)
    • 捕获器处理程序参数
      • target:目标对象
      • prototypetarget的替代原型,顶级原型则为null
    • 捕获器不变式
      • 如果target.property不可扩展,则唯一有效prototype参数就是Object.getPrototypeOf(target)的返回值
const myTarget9 = {}
const targetPrototype = { foo: 'bar' }
const proxy17 = new Proxy(myTarget9, {
  setPrototypeOf(target, prototype) {
    console.log(target) //{},目标对象
    console.log(targetPrototype) // { foo: 'bar' },target的替代原型
    console.log(Reflect.setPrototypeOf(...arguments)) // true,原型赋值成功
    return Reflect.setPrototypeOf(...arguments)
  },
})
Object.setPrototypeOf(proxy17, targetPrototype)
console.log(proxy17) // {}
console.log(proxy17.__proto__ === targetPrototype) // true
console.log(proxy17.foo) // 'bar'
console.log(myTarget9.foo) // 'bar'

// 捕获器不变式
Object.preventExtensions(myTarget9) // 不可扩展
const proxy18 = new Proxy(myTarget9, {
  setPrototypeOf() {
    return Reflect.setPrototypeOf(...arguments)
  },
})
// Object.setPrototypeOf(proxy18, targetPrototype) // TypeError,唯一有效的prototype参数是Object.getPrototypeOf(target)的返回值
Object.setPrototypeOf(proxy18, Object.getPrototypeOf(myTarget9)) // 有效
console.log(proxy18.__proto__ === Object.getPrototypeOf(myTarget9)) // true

isExtensible()

  • Object.isExtensible()中被调用,对应的反射 API 方法为Reflect.isExtensible(target)
    • 返回值
      • 布尔值,表示target是否可被扩展,非布尔值会被转型为布尔值
    • 拦截的操作
      • Object.isExtensible(proxy)
      • Reflect.isExtensible(proxy)
    • 捕获器处理程序参数
      • target:目标对象
    • 捕获器不变式
      • 如果target可扩展,则处理程序必须返回true
      • 如果target不可扩展,则处理程序必须返回false
const myTarget10 = {}
const proxy19 = new Proxy(myTarget10, {
  isExtensible(target) {
    console.log(target) // {},目标对象
    console.log(Reflect.isExtensible(...arguments)) // true,target可扩展
    return Reflect.isExtensible(...arguments)
  },
})
Object.isExtensible(proxy19) // 拦截的操作

// 捕获器不变式
Object.preventExtensions(myTarget10) // 不可扩展
const proxy20 = new Proxy(myTarget10, {
  isExtensible() {
    // return true // TypeError,不可扩展必须返回false
    console.log(Reflect.isExtensible(...arguments)) // false,target不可扩展
    return false
  },
})
Object.isExtensible(proxy20)

preventExtensions()

  • Object.preventExtensions()中被调用,对应的反射 API 方法为Reflect.preventExtensions(target)
    • 返回值
      • 布尔值,表示target是否已经不可扩展,非布尔值会被转型为布尔值
    • 拦截的操作
      • Object.preventExtensions(proxy)
      • Reflect.preventExtensions(proxy)
    • 捕获器处理程序参数
      • target:目标对象
    • 捕获器不变式
      • 如果Object.isExtensions(target)false,则处理程序必须返回true
const myTarget11 = {}
const proxy21 = new Proxy(myTarget11, {
  preventExtensions(target) {
    console.log(target) // {},目标对象
    console.log(Reflect.preventExtensions(...arguments)) // true,target已经不可扩展
    return Reflect.preventExtensions(...arguments)
  },
})
Object.preventExtensions(proxy21) // 拦截的操作

// 捕获器不变式
Object.preventExtensions(myTarget11) // 不可扩展
console.log(Object.isExtensible(myTarget11)) // false,目标对象已经不可扩展
const proxy22 = new Proxy(myTarget11, {
  preventExtensions() {
    // return false // TypeError,处理程序此时必须返回true
    return true
  },
})
Object.preventExtensions(proxy22)

apply()

  • 调用函数时被调用,对应的反射 API 方法为Reflect.apply(target, thisArg, argumentsList)
    • 返回值
      • 返回值无限制
    • 拦截的操作
      • proxy(...argumentsList)
      • Function.prototype.apply(thisArg, argumentsList)
      • Function.prototype.call(thisArg, ...argumentsList)
      • Reflect.apply(proxy, thisArg, argumentsList)
    • 捕获器处理程序参数
      • target:目标对象
      • thisArg:调用函数时的 this 参数
      • argumentsList:调用函数时的参数列表
    • 捕获器不变式
      • target必须是一个函数对象
const myTarget12 = () => {}
const targetApply = { foo: 'bar' }
const proxy23 = new Proxy(myTarget12, {
  apply(target, thisArg, argumentsList) {
    console.log(target) // [Function: myTarget12],目标对象
    console.log(thisArg) // { foo: 'bar' },调用函数时的 this 参数
    console.log(argumentsList) // [ 1, 2, 3 ],调用函数时的参数列表
    return Reflect.apply(...arguments)
  },
})
Reflect.apply(proxy23, targetApply, [1, 2, 3]) // 拦截的操作

// 捕获器不变式
const proxy24 = new Proxy(targetApply, {
  apply() {
    return Reflect.apply(...arguments)
  },
})
// proxy24() // TypeError: proxy24 is not a function,target必须是函数对象

construct()

  • new 操作符时被调用,对应的反射 API 方法为Reflect.construct(target, argumentsList, newTarget)
    • 返回值
      • 必须返回一个对象
    • 拦截的操作
      • new proxy(...argumentsList)
      • Reflect.construct(proxy, argumentsList, newTarget)
    • 捕获器处理程序参数
      • target:目标构造函数
      • argumentsList:传给目标构造函数的参数列表
      • newTarget:最初被调用的构造函数
    • 捕获器不变式
      • target必须可以用作构造函数
const MyTarget13 = function () {}
const proxy25 = new Proxy(MyTarget13, {
  construct(target, argumentsList, newTarget) {
    console.log(target) // [Function: MyTarget13],目标构造函数
    console.log(argumentsList) // [ 123 ],传给目标构造函数的参数列表
    console.log(newTarget) // [Function: MyTarget13],最初被调用的构造函数
    return Reflect.construct(...arguments)
  },
})
new proxy25(123) // 拦截的操作

const MyTarget14 = () => {} // 箭头函数,不能用作构造函数
const proxy26 = new Proxy(MyTarget14, {
  construct() {
    return Reflect.construct(...arguments)
  },
})
new proxy26() // TypeError: proxy26 is not a constructor,target必须可以用作构造函数

总结 & 问点

捕获器 被调用 反射 API 返回值 拦截操作 参数 不变式
get() 获取属性值 Reflect.get() 无限制 proxy.property<br>proxy[property]<br>Object.create(proxy)[property]<br>Reflect.get(proxy,property,receiver) target:目标对象<br>property:目标对象的键属性(字符串键或符号键)<br>receiver:代理对象或继承代理对象的对象 如果target.property不可写且不可配,处理程序返回值必须target.property匹配<br>如果target.property不可配置且[[Get]]特性为undefined,处理程序返回值必须undefined
set() 设置属性值 Reflect.set() 布尔值,配置是否成功 proxy.property = value<br>proxy[property] = value<br>Object.create(proxy)[property] = value<br>Reflect.get(proxy,property,receiver) = value target:目标对象<br>property:目标对象的键属性(字符串键或符号键)<br>value:要赋给属性的值<br>receiver:代理对象或继承代理对象的对象 如果target.property不可写且不可配,则不能修改目标属性的值<br>如果target.property不可配置且[[Set]]特性为undefined,则不能修改目标属性的值<br>严格模式下,处理程序返回false会抛出 TypeError
has() in 操作符 Reflect.has() 布尔值,属性是否存在 property in proxy<br>property in Object.create(proxy)<br>with(proxy) {(property)}<br>Reflect.has(proxy,property) target:目标对象<br>property:目标对象的键属性(字符串键或符号键) 如果target.property存在且不可配置,则处理程序必须返回true<br>如果target.property存在且目标对象不可扩展,则处理程序必须返回true
defineProperty() Object.defineProperty() Reflect.defineProperty() 布尔值,属性是否成功定义 Object.defineProperty(proxy, property, descriptor)<br>Reflect.defineProperty(proxy, property, descriptor) target:目标对象<br>property:目标对象的键属性(字符串键或符号键) 如果目标对象不可扩展,则无法定义属性<br>如果目标对象有一个可配置的属性,则不能添加同名的不可配置属性<br>如果目标对象有一个不可配置的属性,则不能添加同名的可配置属性
getOwnPropertyDescriptor() Object.getOwnPropertyDescriptor() Reflect.getOwnPropertyDescriptor() 属性的描述符对象,属性不存在时返回undefined Object.getOwnPropertyDescriptor(proxy, property)<br>Reflect.getOwnPropertyDescriptor(proxy, property) target:目标对象<br>property:目标对象的键属性(字符串键或符号键) 如果自有的target.property存在且不可配置,则处理程序必须返回一个表示该属性存在的对象<br>如果自有的target.property存在且可配置,则处理程序必须返回该属性可可配置的对象<br>如果自有的target.property存在且目标对象不可扩展,则处理程序必须返回一个表示该属性存在的对象<br>如果target.property不存在且目标对象不可扩展,则处理程序必须返回undefined表示改属性不存在<br>如果target.property不存在,则处理程序不能返回表示该属性存在的对象
deleteProperty() delete 操作符 Reflect.deleteProperty() 布尔值,删除属性是否成功 delete proxy.property<br>delete proxy[property]<br>Reflect.delete(proxy,property) target:目标对象<br>property:目标对象的键属性(字符串键或符号键) 如果target.property存在且不可配置,则处理程序不能删除这个属性
ownKeys() Object.keys()及类似方法 Reflect.ownKeys() 包含字符串或符号的可枚举对象 Object.getOwnPropertyNames(proxy)<br>Object.getOwnPropertySymbols(proxy)<br>Object.keys(proxy)<br>Reflect.ownKeys(proxy) target:目标对象 返回的可枚举对象必须包含target所有不可配置的自有属性<br>如果target不可扩展,则返回可枚举对象必须准确包含自有属性键
getPrototypeOf() Object.getPrototypeOf() Reflect.getPrototypeOf() 对象或 null Object.getPrototypeOf(proxy)<br>Reflect.getPrototypeOf(proxy)<br>proxy.__proto__<br>Object.prototype.isPrototyprOf(proxy)<br>proxy instanceof Object target:目标对象 如果target不可扩展,则Object.getPrototypeOf(proxy)唯一有效的返回值就是Object.getPrototypeOf(target)的返回值
setPrototypeOf() Object.setPrototypeOf() Reflect.setPrototypeOf() 布尔值,原型赋值是否成功 Object.setPrototypeOf(proxy)<br>Reflect.setPrototypeOf(proxy) target:目标对象<br>prototypetarget的替代原型,顶级原型则为null 如果target.property不可扩展,则唯一有效prototype参数就是Object.getPrototypeOf(target)的返回值
isExtensible() Object.isExtensible() Reflect.isExtensible() 布尔值,target是否可被扩展 Object.isExtensible(proxy)<br>Reflect.isExtensible(proxy) target:目标对象 如果target可扩展,则处理程序必须返回true<br>如果target不可扩展,则处理程序必须返回false
preventExtensions() Object.preventExtensions() Reflect.preventExtensions() 布尔值,target是否不可扩展 Object.preventExtensions(proxy)<br>Reflect.preventExtensions(proxy) target:目标对象 如果Object.isExtensions(target)false,则处理程序必须返回true
apply() 调用函数 Reflect.apply() 无限制 proxy(...argumentsList)<br>Function.prototype.apply(thisArg, argumentsList)<br>Function.prototype.call(thisArg, ...argumentsList)<br>Reflect.apply(proxy, thisArg, argumentsList) target:目标对象<br>thisArg:调用函数时的 this 参数<br>argumentsList:调用函数时的参数列表 target必须是一个函数对象
construct() new 操作符 Reflect.construct() 一个对象 new proxy(...argumentsList)<br>Reflect.construct(proxy, argumentsList, newTarget) target:目标构造函数<br>argumentsList:传给目标构造函数的参数列表<br>newTarget:最初被调用的构造函数 target必须可以用作构造函数
回到顶部