介绍
set方法用来拦截某个属性的赋值操作,可以接受四个参数,
目标对象,属性名,属性值和Proxy实例本身,最后一个参数可选
- demo1 假定Person对象有个age属性,该属性应该是一个不大于200的整数,那么可以使用Proxy保证age的值符合要求
{
let validator = {
set:function (obj,prop,value){
if(prop === 'age'){
//判断是不是整数
if(!(value)){
throw new TypeError('the age is not an integer');
}
if(value>200){
throw new RangeError('The age seems invalid');
}
}
//对于满足条件的age属性以及其他属性,直接保存
obj[prop] = value;
}
};
let person = new Proxy({},validator);
= 100;
();
}
- demo2 有时我们会在对象上面设置内部属性,属性名的第一个字符使用下划线开头,表示这些属性不应该被外部使用。结合get和set方法,就可以做到防止这些内部属性被外部读写。
{
const handler = {
get (target,key){
invariant(key,'get');
return target[key];
},
set (target,key,value){
invariant(key,'set');
target[key] = value;
return true;
}
};
function invariant (key,action) {
if(key[0] === '_'){
throw new Error(`Invalid attempt to ${action} private "${key}"property`)
}
}
const target = {};
const proxy = new Proxy(target,handler);
}
//("proxy._prop",proxy._prop);
//Invalid attempt to get private "_prop" property at invariant
//proxy._prop = "c";
//Invalid attempt to get private "_prop" property at invariant
- demo3 下面是set方法第四个参数的例子
{
const handler = {
set:function(obj,prop,value,receiver) {
obj[prop] = receiver;
}
};
const proxy = new Proxy({},handler);
= 'bar';
( === proxy);//true
}
//上面的代码中,set方法的第四个参数receiver,指的是原始的操作行为所在的那个对象,一般情况下是proxy实例本身。
- demo4 请看下面的例子
{
const handler = {
set :function (obj,prop,value,receiver) {
obj[prop] = receiver
}
};
const proxy = new Proxy({},handler);
const myObj = {};
(myObj,proxy);
//() 方法设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或 null。
= 'bar';
( === myObj);//true
}
//上面的代码中设置属性的值时,myObj并没有foo属性,因此引擎会到myObj的原型链上去找foo属性。
//然而,myObj的原型对象proxy是Proxy实例,设置它的foo属性会触发set方法。这时,
//第四个参数receiver就指向原始赋值行为所在的对象myObj
//注意:如果目标对象自身的某个属性,不可写且不可配置,那么set方法将不起作用。
- demo5
{
const obj = {};
(obj,'foo',{
value:'bar',
writable:false,
});
const handler = {
set :function (obj,prop,value,receiver) {
obj[prop] = 'baz';
}
};
const proxy = new Proxy(obj,handler);
= 'baz';
("",);// bar
}
//上面代码中,属性不可写,Proxy 对这个属性的set代理将不会生效 writable属性控制是否可写。
- demo6 注意,严格模式下,set代理如果没有返回true,就会报错
{
'use strict';
const handler ={
set:function (obj,prop,value,receiver) {
obj[prop] = value;
//无论有没有下面这一行,都会报错
//return true;
}
}
const proxy = new Proxy({},handler);
='bar';
("",=='bar');
}
//上面这个实例有没有renturn似乎并没有什么关系,此实例摘自阮一峰ECMAScript6 入门Proxy set方法最后一个实例
例子来源于阮一峰的es6入门,如果哪里写的不完整欢迎指正,还是萌新还望包容!