ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

代理捕获器与反射方法

2021-10-06 17:03:30  阅读:129  来源: 互联网

标签:反射 const target 捕获 Object 代理 Reflect proxy property


代理捕获器与反射方法

资料来源JavaScript高级程序设计

代理可以捕获13种不同的基本操作。这些基本操作有各自不同的反射API方法、参数、关联ECMAScript操作和不变式。

文章目录

get()

get()捕获器会在获取属性值的操作种被调用。对应的反射API的方法为Reflect.get()

// get()

const test1={
    name:'yihen'
}
const proxy=new Proxy(test1,{
    get(target,property,receiver){
        console.log('已经调用了get()')
        return Reflect.get(...arguments);
    }
})
//已经调用了get() 
console.log(proxy.name);// yihen
  1. 返回值

返回值无限制

  1. 拦截的操作
  • proxy.property
  • proxy[property]
  • Object.create(proxy)[property]
  • Reflect.get(proxy,property,receiver)
  1. 捕获器处理程序参数
  • target : 目标对象
  • property: 引用的目标对象上的字符串键属性
  • receiver:代理对象或继承代理对象的对象
  1. 捕获器不变式
  • 如果target.property不可写且不可配置,则处理程序返回的值必须与target.property匹配

  • 如果target.property不可配置且[[Get]]特性为undefined,处理程序的返回值也必须是undefined

set()

set()捕获器会在设置属性值的操作中被调用。对应的反射API方法为Reflect.set()

const test2={}
const proxy2=new Proxy(test2,{
    set(target,property,value,receiver){
        console.log("已经调用了set()")
        const res=Reflect.set(...arguments);
        console.log(res);// true
        return res
    }
})

proxy2.name='yihen';// 已经调用了set()
console.log(test2.name); //yihen
  1. 返回值
    返回true表示成功;返回false表示失败,严格模式下会抛出TypeError

  2. 拦截操作

  • proxy.property=value;
  • proxy[property]=value;
  • Object.create(proxy)[value];
  • Reflect.set(taget,property,value,receiver)
  1. 捕获器处理程序参数
  • target: 目标对象
  • property: 引用的目标对象上的字符串键属性
  • value: 要赋给属性的值
  • receiver: 接收最初赋值的对象
  1. 捕获器不变式
  • 如果target.property不可写且不可配置,则不能修改目标的属性值

  • 如果target.property不可配置且[[Set]]特性为undefined,则不能修改目标属性的值,在严格模式下,处理程序中返回false会抛出TypeError

has()

has()捕获器会在in操作符中被调用,对应的反射API方法为Reflect.has();

/* 
has()
*/

const test3={}
const proxy3=new Proxy(test3,{
    has(target,property){
        console.log("你调用了has()")
        return Reflect.has(...arguments)
    }
})

console.log("name" in proxy3);// false
proxy3.name='yihen'
console.log("name" in proxy3);// true
  1. 返回值
    has()必须返回bool值,表示属性是否存在,返回非bool值会被转换为bool值

  2. 拦截操作

  • property in proxy
  • property in Object.create(proxy)
  • with(proxy){(property);}
  • Reflect.has(proxy,property)
  1. 捕获器处理程序参数
  • target: 目标对象
  • property: 引用的目标对象上的字符串键属性
  1. 捕获器不变式
  • 如果target.property存在且不可配置,则处理程序必须返回true

  • 如果target.property存在且目标对象不可扩展,则处理程序必须返回true

defineProperty

defineProperty()捕获器会在Object.defineProperty()中被调用。对应的反射API方法为Reflect.defineProperty().

/* 
    defineProperty()
*/

const test4={}
const proxy4=new Proxy(test4,{
    defineProperty(target,property,descriptor){
        console.log('你调用了defineProperty');
        return Reflect.defineProperty(...arguments)
    }
});

Object.defineProperty(proxy4,'name',{
    value:'yihen'
});//你调用了defineProperty
  1. 返回值

defineProperty() 必须返回bool值,表示属性是否成功定义。返回非bool值会被转换为bool值

  1. 拦截操作
  • Object.defineProperty(proxy,property,descriptor)
  • Reflect.defineProperty(proxy,property,descriptor)
  1. 捕获器处理程序参数
  • target: 目标对象
  • property: 引用的目标对象上的字符串键属性
  • descriptor: 包含可选的 enumerable、configurable、writable、value、get和set定义的对象
  1. 捕获器不变式
  • 如果目标对象不可扩展,则无法定义属性
  • 如果目标对象有一个可配置的属性,则不能添加同名的不可配置属性
  • 如果目标对象有一个不可配置的属性,则不能添加同名的可配置属性

getOwnPropertyDescriptor()

getOwnPropertyDescriptor()捕获器会在 Object.getOwnPropertyDescriptor()中被调用。对应的反射API方法为Reflect.getOwnPropertyDescriptor()

/* 
    getOwnPropertyDescriptor()
*/

const test5={name:'yihen'}
const proxy5=new Proxy(test5,{
    getOwnPropertyDescriptor(target,property){
        console.log('你调用了getOwnPropertyDescriptor')
        return Reflect.getOwnPropertyDescriptor(...arguments)
    }
})

const res= Object.getOwnPropertyDescriptor(proxy5,'name') // '你调用了getOwnPropertyDescriptor'
console.log(res)
/* 
{
  value: 'yihen',
  writable: true,
  enumerable: true,
  configurable: true
}
*/
  1. 返回值
    getOwnPropertyDescriptor()必须返回对象,或者在属性不存在的时候返回undefined

  2. 拦截的操作

  • Object.getOwnpropertyDescriptor(proxy,property)
  • Reflect.getOwnPropertyDescriptor(proxy,property)
  1. 捕获器处理程序参数
  • target: 目标对象
  • property: 引用的目标对象上的字符串键属性
  1. 捕获器的不变式
  • 如果自有的target.property存在且不可配置,则处理程序必须返回一个表示该属性存在的对象

  • 如果自有的target.property存在且可配置,则处理程序必须返回一个表示该属性存在且可配置的对象

  • 如果target.property不存在且target不可扩展,则处理程序必须返回undefined表示该属性不存在

  • 如果target.property不存在,则处理程序不能返回表示该属性可配置的对象

deleteProperty()

deleteProperty()捕获器会在delete操作符中被调用。对应的反射API方法为Reflect.deleteProperty()。

/* 
 deleteProperty()
*/


const test6={name:'yihen'}
const proxy6=new Proxy(test6,{
    deleteProperty(target,property){
        console.log('你调用了deleteProperty()')
        return Reflect.deleteProperty(...arguments)
    }
})
console.log(proxy6.name);// yihen
delete proxy6.name;
console.log(proxy6.name);// undefined
  1. 返回值

deleteProperty()返回值必须是bool值,表示删除属性是否成功。返回非bool值会被转换为bool值

  1. 拦截操作
  • delete proxy.property
  • delete proxy[property]
  • Reflect.deleteProperty(proxy,property)
  1. 捕获器处理程序参数
  • target: 目标对象
  • property: 引用的目标对象上的字符串键属性
  1. 捕获器不变式

如果自有的target.property存在不可配置,则处理函数不能删除这个属性

ownKeys()

onwKeys()捕获器会在Object.keys()及类似的方法中被调用。对应的反射API方法为Reflect.ownKeys()

/* 
    ownKeys()
*/

const test7={name:'yihen',age:18}
Object.defineProperty(test7,'id',{
    value:12345678
})
const proxy7=new Proxy(test7,{
    ownKeys(target){
        console.log('你调用了ownKeys()')
        const res=Reflect.ownKeys(...arguments)
        console.log(res);// [ 'name', 'age','id ]
        return res
    }
})


const res2=Object.keys(proxy7)
console.log(res2);// [ 'name', 'age' ]
  1. 返回值

ownKeys()必须返回包含字符串或符号的可枚举对象

  1. 拦截的操作
  • Object.getOwnPropertyNames(proxy);
  • Object.getOwnPropertySymbols(proxy);
  • Object.keys(proxy);
  • Reflect.ownKeys(proxy)
  1. 捕获器处理程序参数

target: 目标对象

  1. 捕获器不变式
  • 返回的可枚举对象必须包含target的所有不可配置的自有属性
  • 如果target不可扩展,则返回可枚举对象必须准确的包含自有属性键

getPrototypeOf()

getPrototypeOf()捕获器会在Object.getPrototypeOf()中被调用。对应的反射API方法为Reflect.getPrototypeOf()。

/* 
 getPrototypeOf()
*/

const test8={}
const proxy8=new Proxy(test8,{
    getPrototypeOf(target){
        console.log("你调用了了getPrototypeOf()")
        const res=Reflect.getPrototypeOf(...arguments);
        console.log(res);//[Object: null prototype] {}
        return res
    }
})

console.log(Object.getPrototypeOf(proxy8));//[Object: null prototype] {}
  1. 返回值

getPrototypeOf()必须返回对象或null

  1. 拦截的操作
  • Object.getPrototypeOf(proxy);
  • proxy.__proro__
  • Object.prototypeOf.isPrototypeOf(proxy)
  • proxy instanceof Object
  • Reflect.getPrototypeOf(proxy)
  1. 捕获处理程序参数
  • target: 目标对象
  1. 捕获不变式

如果target不可拓展,则Object.getPrototype(proxy)唯一有效的返回值就是Object.getPrototypeOf(target)的返回值

setPrototypeOf()

setPrototypeOf()捕获器会在Object.setPrototypeOf()中被调用,对应的反射API方法为Reflect.setPrototypeOf()

/* 
    setPrototypeOf()
*/


const test9={}
const proxy9=new Proxy(test9,{
    setPrototypeOf(target,property){
        console.log('你调用了setPrototypeOf()')
        const res=Reflect.setPrototypeOf(...arguments);
        console.log(res); // true
        return res
    }
})

Object.setPrototypeOf(proxy9,Object);
  1. 返回值

setPrototypeOf()必须返回bool值,表示原型赋值是否成功,返回非bool值会被转换为bool值

  1. 拦截的操作
  • Object.setPrototypeOf(proxy)
  • Reflect.setPrototypeOf(proxy)
  1. 捕获器处理程序参数
  • target: 目标对象
  • prototype: target的替代原型,如果是顶级原型则为null
  1. 捕获器不定式

如果target不可扩展,则唯一有效的prototype参数就是Object.getPrototypeOf(target)

isExtensible()

isExtensible()捕获器会在Object.isExtensible()中被调用。对应的反射API方法为Reflect.isExtensible()。

const test1={}
const proxy1=new Proxy(test1,{
    isExtensible(target){
        console.log("正在调用isExtensible()");
        const res=Reflect.isExtensible(...arguments);
        console.log(res);// true
        return res
    }
})

console.log(Object.isExtensible(proxy1));//true
  1. 返回值
    isExtensible()必须返回bool值,表示target是否可扩展。返回非bool值会被转换为bool值。

  2. 拦截的操作

  • Object.isExtensible(proxy)
  • Reflect.isExtensible(proxy)
  1. 捕获处理程序参数
  • target: 目标对象
  1. 捕获器不变式
  • 如果target可扩展,必须返回true
  • 如果target不可扩展,必须返回false

preventExtensions()

preventExtensions()捕获器会在Object.preventExtensions()中被调用。对应的反射API方法为Reflect.preventExtensions()

/* 
    preventExtensions()
*/

const test2={}
const proxy2=new Proxy(test2,{
    preventExtensions(target){
        console.log('你调用了preventExtensions()')
        const res=Reflect.preventExtensions(...arguments)
        console.log(res);// true
        return res
    }
})

console.log(Object.preventExtensions(proxy2));// {}
  1. 返回值

preventExtensions()必须返回bool值,表示target是否应该不可扩展,返回非bool值会被转换为bool值

  1. 拦截的操作
  • Object.preventExtensions(proxy)
  • Reflect.preventExtensions(proxy)
  1. 捕获器处理程序操作

target;目标对象

  1. 捕获其不变式

如果Object.isExtensible(proxy)是false,则处理程序必须返回true

apply

apply()捕获器会在调用函数时中被调用。对应的反射API方法为Reflect.apply()

/* 
    apply()
*/

const test3=()=>{}
const proxy3=new Proxy(test3,{
    apply(target,thisArg,...argumentsList){
        console.log('你调用了apply()')
        const res=Reflect.apply(...arguments)
        console.log(res);// undefined
        return res
    }
})

proxy3()
  1. 返回值

返回值无限制

  1. 拦截的操作
  • proxy(…arguments)
  • Function.prototype.apply(thisArg,argumentsList)
  • Function.prototype.call(thisArg,…argumentsList)
  • Reflect.apply(target,thisArg,argumentsList)
  1. 捕获器处理程序参数
  • target: 目标对象
  • thisArg: 调用函数时的this参数
  • argumentsList: 调用函数时的参数列表
  1. 捕获器不变式
  • target必须时一个函数对象

construct()

construct()捕获器会在new操作符中被调用。对应的反射API方法为Reflect.construct()

/* 
    construct()
*/

const test4=function(){}
const proxy4=new Proxy(test4,{
    construct(target,argumentsList,newTarget){
        console.log('你调用了construct()');
        const res=Reflect.construct(...arguments)
        console.log(res);//test4 {}
        return res
    }
})

new proxy4;
  1. 返回值

construct()必须返回一个对象

  1. 拦截操作
  • new proxy(…argumentsList)
  • Reflect.construct(target,argumentsList,newTarget)
  1. 捕获器处理程序参数
  • target: 目标构造函数
  • argumentsList: 传给目标构造函数的参数列表
  • newTarget: 最初被调用的构造函数
  1. 捕获器不变式

target必须可以用作构造函数

标签:反射,const,target,捕获,Object,代理,Reflect,proxy,property
来源: https://blog.csdn.net/yihen0214/article/details/120626541

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有