首页 > 其他分享 >【ES6】Proxy对象

【ES6】Proxy对象

时间:2023-01-16 17:32:17浏览次数:35  
标签:ES6 set target 对象 Proxy var


【ES6】Proxy对象

  • ​​一、Proxy的基本用法​​
  • ​​二、Proxy示例的方法​​
  • ​​1)get()​​
  • ​​2)set()​​
  • ​​3)apply()​​
  • ​​查看更多ES6教学文章:​​
  • ​​参考文献​​

引言:ES6规范里面新增了Proxy对象,在高级范畴的js编程或者底层脚本的编写有这极强的作用。


一、Proxy的基本用法

        Proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程"( meta programming),即对编程语言进行编程。
        Proxy可以理解成在目标对象前架设一“拦截”层,外界对该对象的访问都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理"”某些操作,可以译为“代理器”。
        在介绍Proxy对象的基本用法之前,我们先来讲述一下JS中对象的机制。例如,我先简单的创建一个对象:​​​var obj = {};​​​,现在​​obj​​​对象是没有属性的。假如我再写一条语句​​obj.id=1;​​​,此时,虽然obj对象没有id这条属性,但是​​obj.id=1​​​操作是调用了JS对象机制内部的set方法。
        下面,给出Proxy对象定义的基本格式:​​​var proxy = new Proxy(target , handler);​

Proxy对象的所有用法都是上面这种形式,不同的只是handler参数的写法。其中,new Proxy()表示生成个Proxy实例,target参数表示所要拦截的目标对象的名称,hander参数是一个函数方法,用来定制拦截行为。

        代码块1-1运用Proxy对象写了一个拦截对象对自己的属性进行赋值与取值的代理器。

/***@@    代码块1-1    拦截器举例一    @@***/
var obj = new Proxy({},{
get: function (target, key, receiver) {
console. log(`getting ${key}!`);
return Reflect.get(target, key, receiver);
},
set: function (target, key, value, receiver) {
console. log(`setting ${key}!`);
return Reflect.set(target, key, value, receiver);
});

obj.count=1;
// setting count!
++obj.count;
//getting count!
//setting count!
//2
代码块1-1解释:
首先,定义obj对象为Proxy类。
Proxy第一个参数应该是一个对象名,表示要拦截的目标对象,本例为空,则指向源对象obj。
Proxy第二个参数是自定义的拦截方法。
本例是对JS对象机制的get与set进行重定义,其中target参数是目标对象名,key是属性名。

当obj.count=1;代码运行时,首先会调用obj对象的set函数机制,然后被Proxy拦截,输出setting count!。
当obj.count++;运行时,先get到count的值,再去set。

        代码块1-1对一个空对象做了一层拦截,重定义了属性的读取(get)和设置(set)行为。Proxy 实际上重载(overlad)了点运算符,即用自己的定义覆盖了语言的盾始定义。
        下面是另一个拦截读取属性行为的例子。见代码块1-2。

/***@@    代码块1-2    拦截读取属性    @@***/
var proxy = new Proxy({}, {
get: function(target, property) {
return 35;
}
});
proxy.time // 35
proxy.nane // 35
proxy.title // 35

        上面的代码中,作为构造函数Proxy接受两个参数:第一个参数是所要代理的目标对象(上例中是一个空对象),即如果没有Proxy介人,操作原来要访问的就是这个对象;第二个参数是配置对象,对于每一个被代理的操作,需要提供一 个对应的处理函数,该函数将拦截对应的操作。比如,上面的代码中, 配置对象有一个get方法,用来拦截对目标对象属性的访问请求。get方法的两个参数分别是目标对象和所要访问的属性。可以看到,由于拦截函数总是返回35,所以访问任何属性都将得到35。
        注意,要使Proxy起作用,必须针对Proxy实例(上例中是proxy对象)进行操作,而不是针对目标对象(上例中是空对象)进行操作。
        如果handler没有设置任何拦截,那就等同于直接通向原对象。见代码块1-3。

/***@@    代码块1-3       @@***/
var target = {};
var handler = {};
var proxy = new Proxy(target, handler);
proxy.a = 'b';
target.a // "b"

        上面的代码中,handler 是一个空对象,没有任何拦藏效果,访问hndler就等同于访问target。
        一个技巧是将 Proxy对象设置到object.proxy属性,从而可以在object对象上调用。
​​​var object= { proxy: new Proxy(target, handler) }​

二、Proxy示例的方法

1)get()

        get方法用于拦截某个属性的读取操作。前面已经有一个例子, 下面是另一个拦截读取操作的例子。见代码块2-1-1。

/***@@    代码块2-1-1       @@***/
var person = {
name: "张三"
};

var proxy = new Proxy(person, {
get: function(target, property) {
if (property in target) {
return target[property];
} else {
throw new ReferenceError("Property \"" + property + "\" does not exist.");
}
}
});
proxy.name // "张三”
proxy.age //抛出一个错误

2)set()

        set方法用于拦截某个属性的赋值操作。
        假定Person对象有个age属性,该属性应该是个不大于200的整数,那么可以使用Porxy对象保证age的属性值符合要求。见代码块2-2-1。

/***@@    代码块2-2-1       @@***/
let validator = {
set: function(obj, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TyeError('The age is not an integer');
}
if (value > 200) {
throw new RangeError('The age seems invalid');
}
}
//其他属性一律保存
obj[prop] = value;
}
};
let person = new Proxy({}, validator);

person.age = 100;

person.age // 100
person.age = 'young' //报错
person.age = 300 //报错

        上面的代码中,由于设置了存值函数set,任何不符合要求的age属性赋值都会抛出一个错误。利用set方法,还可以数据绑定,即每当对象发生变化时,会自动更新DOM。
        有时,我们会在对象上设置内部属性,属性名的第一个字符使用 下画线开头,表示这些属性不应该被外部使用。结合get和set方法,就可以做到防止这些内部属性被外部读写。

/***@@    代码块2-2-1   屏蔽下划线开头的属性    @@***/
var handler = {
get (target, key) {
invartant(key, 'get');
return target[key];
},
set (target, key, value) {
invartant(key, 'set');
return true;
}
}
functton invartant (key, action) {
if (key[0] === '_') {
throw new Error(`Invalid attempt to ${action} private "${key}" property`);
}
}
var target = {};
var proxy = new Proxy(target, handler);

proxy._prop
//Error: Invalid attempt to get private " prop" property
proxy._prop = 'c'
// Error: Invalid attempt to set private " prop" property

        上面的代码中,只要读写的属性名的第一个字符是下画线,一律抛出错误,从而达到禁止读/写内部属性的目的。

3)apply()

        apply方法拦截函数的调用、call和apply操作。形式如下:
​​​var handler = {
apply (target, ctx, args) {
return Reflect. apply(…arguments);}
}​
​         apply方法可以接受3个参数,分别是目标对象、目标对象的上下文对象( this )和目标对象的参数数组。下面是一个例子。

var target= function () { return 'I am the target'; };
var handler =
apply: function () {
return 'I am the proxy';
};
var p = new Proxy(target, handler);
p() === 'I am the proxy';
// true

        上面的代码中,变量p是Proxy的实例,当作为函数调用时(p()),就会被apply方法拦截,返回一个字符串。

查看更多ES6教学文章:

​​1. 【ES6】let与const 详解​​2. 【ES6】变量的解构赋值
3. 【ES6】字符串的拓展
4. 【ES6】正则表达式的拓展
5. 【ES6】数值的拓展
6. 【ES6】数组的拓展
7. 【ES6】函数的拓展
8. 【ES6】对象的拓展
9. 【ES6】JS第7种数据类型:Symbol
10. 【ES6】Proxy对象
11. 【ES6】JS的Set和Map数据结构
12. 【ES6】Generator函数详解
13. 【ES6】Promise对象详解
14. 【ES6】异步操作和async函数
15. 【ES6】JS类的用法class
16. 【ES6】Module模块详解
17. 【ES6】ES6编程规范 编程风格

参考文献

阮一峰 《ES6标准入门(第2版)》


标签:ES6,set,target,对象,Proxy,var
From: https://blog.51cto.com/u_15942590/6010589

相关文章

  • 【ES6】JS第7种数据类型:Symbol
    【ES6】JS第7种数据类型:Symbol​​一、Symbol的由来​​​​二、Symbol的涵义​​​​三、Symbol的判等​​​​四、Symbol的运算与转化​​​​查看更多ES6教学文章:​​​......
  • 【ES6】对象的拓展
    【ES6】对象的拓展​​一、对象的两种表示法【掌握】​​​​1)简洁表示法​​​​2)属性名表达式法​​​​二、Object.is()【了解】​​​​三、Object.assign()【了解】​......
  • Java面向对象程序设计基础知识
    Java面向对象程序设计Java基础语法类(class):类是一个模块,描述一类对象的行为和状态对象:类的一个实例,有状态和行为,例如:一条狗是一个对象,它的状态有:颜色、名字、品种;行......
  • Microsoft 365 开发篇:New Microsoft Graph Developer Proxy preview v0.3
    Blog链接:https://blog.51cto.com/13969817使用MicrosoftGraphDeveloperProxy的最新预览版本构建弹性和高性能的应用程序。在这个新版本中,我将介绍对MicrosoftGraph和其......
  • vue将地区以对象、数组的格式传给后端
    项目涉及到了一个地区筛选,同时省市区三级不进行关联,后端要求以对象包数组的格式传参,完整代码1、先拿到接口返回的地区数据对数据进行处理,拿到想要的格式this.province......
  • Day6: 初识面向对象 / 方法回顾与加深 / 对象的创建分析 / 面向对面的三大特性 / 抽象
    1.初识面向对象1.面向过程&面向对象面向过程思想步骤清洗简单,第一步做什么,第二步做什么......面向过程适合处理一些较为简单的问题面向对象思想物以类聚,分......
  • Thymeleaf入门(二):基本对象
    目录表达式基本对象 基本对象#ctx:上下文对象。是org.thymeleaf.context.IContext或者org.thymeleaf.context.IWebContext的实现#locale:直接访问与java.util.Local......
  • Java对象转JSON动态设置字段
    需求User类:@DatapublicclassUser{ privateStringname; privateIntegerage;}序列化成JSON时,处理动态增加一个sex字段{ "name":"张三", "age":20, "sex......
  • 面向对象编程(OOP)
    面向对象编程(OOP)属性+方法=类面向过程步骤清晰简单,第一步做什么,第二步做什么...适用于处理简单的问题面向对象物以类聚和分类的思想模式思考解决问题需要......
  • JS数组对象里面key名替换、新增、删除
    新增letarr=[{id:1,name:'杨过'},{id:2,name:'过儿'}]arr.forEach(item=>{item["status"]=false})//对象letobj={}obj['state']=1......