学习ES6语法proxy之set方法

时间:2025-05-15 22:24:54

介绍
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入门,如果哪里写的不完整欢迎指正,还是萌新还望包容!