proxy 对象代理

本文介绍了JavaScript中的Proxy对象,用于实现代理模式,主要用于拦截和扩展对象操作,包括get、set、apply、deleteProperty和has等方法。通过Proxy,可以实现属性访问控制、数据验证、函数调用统计等功能,例如限制age属性为100以下的整数,并提供了模拟React中定义虚拟DOM的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

proxy 对象代理 代理模式的实现

代理模式的实现,一般用于,代理拦截,预警,上报,统计,扩展功能

  1. Proxy函数接收两个对象 (target, handler) 被代理对象,,对代理对象的操作
1.get 获取某个属性时触发
let person = {
    name: 'CY',
    age: 108
}
let obj  = new Proxy(person, {
    get(target, property){      //代理对象,访问属性
        console.log(target,property)  
        return `你访问了${property}属性`
    }
})
console.log(obj.name)
//访问一个对象的属性,当属性不存在的时候,就返回^_^,
let json = { name:'CY'};

let obj = new Proxy(json,{
    get(target,property){
        if(property in  target){
            return target[property]
        }else{
            console.warn(`${property}属性不存在`);
            return `^_^`
        }
    }
})

console.log(obj.name)   //CY
console.log(obj.age)    //^_^
2.set 当设置某个属性时触发
let person = {
    name: 'Wangjing',
    age: 108
}
let obj  = new Proxy(person, {
    set(target, property, val){
        console.warn('你生下来后名字就只能是' + target[property])
        return `改名为${val}失败`
    }
})
console.log(obj.name = '张三')

限制age属性为100以下的整数

let obj = new Proxy({},{
    set(target,property,value){
        if(property == 'age'){
            if(!Number.isInteger(value)){
                throw new TypeError(' is not integer')
            }
            if(value>100){
                throw new RangeError('you are too old')
            }
        }
        return target[property]=value;
    }
})
obj.age = 123;
3.apply 用于代理函数执行时
function fn(...n){
    console.log(n)
    return "i am fn";
}
let newfn = new Proxy(fn,{
    apply(fn){
        let res = fn.apply(this, arguments[2])
        // 可以获取函数返回值
        console.log( res )
        return 'i am in proxy'
    }
})
console.log(newfn(2,3))

使用reflect可以写得更简便

function fn(a,b){
    return a+b
}
let newfn = new Proxy(fn,{
    apply(target,context,args){
        return Reflect.apply(...arguments) 
    }
})
console.log(newfn(2,3))
3.deleteProperty 用于删除属性时
let json ={
    a:1,
    b:2
}
let newJson = new Proxy(json,{
    deleteProperty(target,property){
        console.log(`you are deleting ${property}`)
        // delete target[property]
        return Reflect.deleteProperty(target, property)
    }
})

delete newJson.a;//调用deleteProperty
console.log(json)
3.has 用于查询属性时
let json ={
    a:1,
    b:2
}
let newJson = new Proxy(json,{
    has(target,property){
        console.log('using method has()')
        // 返回一个欺骗大众的值
        return true
    }
})
console.log(3 in newJson); // true

console.log(json)

例子, 模仿一下react里定义虚拟dom的语句

let React = new Proxy({}, {
    get(target, property){
        if(property === 'createElement'){
            return function (tag, attr = {}, ...children) {
                let el = document.createElement(tag)
                for(let key of Object.keys(attr)){
                    el.setAttribute(key, attr[key])
                }
                for(let child of children){
                    if(typeof child === 'string'){
                        child = document.createTextNode(child)
                    }
                    el.appendChild(child)
                }
                return el
            }
        }
    }
})
let dom = React.createElement('div',{id: 'text'},React.createElement('p', {class: 'name'}, 'dogone'))
console.log(dom)
document.body.appendChild(dom)

顺便说一句Reflect.apply的参数,Reflect.apply(反射的函数,this指向,值-数组

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值