Proxy

Proxy

vue3.x用Proxy来代替Object.defineProperty。

它能做什么

Proxy是ES6中提出的一个构造器。通过new Proxy(原对象,{代理列表})的方式去创建对象,创建的这个对象我们称之为代理对象。

即:

代理对象 = new Proxy(原对象,{代理列表})

之所以要额外产生这么一个代理对象,好处在于可以保持原对象不变,在代理对象中添加新的功能,或者是改造某些功能。

使用格式和基本示例

格式

var obj={};
var proxyObj = new Proxy(obj, {
  操作1: 函数1,
  操作2: 函数2...
})

示例

var star = {name: '罗志祥', age: 40,aihao:'运动'}

        //Proxy :代理对象
        // 通过原对象,产生一个代理对象obj1,代理原对象的 get方法
        // 经纪人
        var zhaohui = new Proxy(star, {
            // 对于obj1,只要执行访问对象的属性,就会执行get函数
            //     target: 代理原对象,
            //     prop:    当前要访问的属性名 
            get:function(target,prop) {
                if(prop === 'aihao') {
                    return '唱歌'
                }
                else if(prop === 'name') {
                    return '小猪'
                }else {
                    return target[prop]
                }
            },
            //   给代理对象设置属性时,会执行set
            //     target: 代理原对象,
            //     prop:    当前要访问的属性名 
            //     newVal:  要设置的新属性值
            set:function(target,prop,newVal) {
                console.log(target,prop,newVal)
                if(prop === 'age') {
                    if(newVal > 30) {
                        console.log('gun......')
                    }
                    else {
                        target[prop] = newVal
                    }
                }
            }
        })

解释如下:

  • proxy对象是在obj对象的基础之上创建的一个新对象。
  • get函数中的两个参数:target,prop 。 target就是原对象obj,prop是当前的属性名; 你可以在get方法中做任意的自定义的处理。当你去获取proxyObj上的任意属性时,get函数就会执行。
  • set函数中的三个参数:target,prop,newVal 。target就是原对象obj,prop是当前的属性名,newVal是要设置给它的初值。当你去设置proxyObj上的任意属性时,set函数就会执行。

代理的应用

访问不存在的属性名时给出更加优雅的提示

背景:在我们写js代码的过程中,最容易遇到的是错误是:访问一个对象不存在的属性。而这个时候js代码是不报错的,它只会返回一个undefined.

需求:访问对象的属性时,如果这个属性不存在,则报出一个错误提示。

// 17.proxy应用-访问一个不存在的属性时给提示.html
        // 背景:在我们写js代码的过程中,最容易遇到的是错误是:访问一个对象不存在的属性。而这个时候js代码是不报错的,它只会返回一个undefined.

        // 需求:访问对象的属性时,如果这个属性不存在,则报出一个错误提示。

        var obj = {a:1,b:2}
        // console.log(obj.abc123)

        var obj1 = new Proxy(obj, {
            get:function(target,propName) {
                // 如果当前要访问的属性propName在target中:
                //  - 存在,返回值
                //  - 不存在,给出提示,再返回undefine

                // 格式: 属性名 in 对象   
                // 功能: 是检查这个属性名在对象中有没有
                // 返回值:boolean
                if(propName in target) {
                    return target[propName]
                } else {
                    console.error(propName, '属性不存在')
                    return undefined
                }

            }
        })
        
        console.log(obj1.a)
        console.log(obj1.abc123)

允许数组下标是负值

背景:在js中,数组的有效下标是从0开始的。

var arr = [1,2,3];

console.info(arr[0]) // 1
console.info(arr[-1]) // undefined
console.info(arr[100]) // undefined

值得注意的是,下标越界或者是负值的情况下,得到的结果是undefined,而不是报错

需求:

如果我们希望数组可以取负值下表,且规则如下:-n表示倒数第n个元素。例如:arr[-1]表示数组arr中的倒数第一个元素。

使用Proxy解决如下:

<script>
   
// 需求:

// 如果我们希望数组可以取负值下表,且规则如下:-n表示倒数第n个元素。
// 例如:arr[-1]表示数组arr中的倒数第一个元素。

        var arr = [1,2,3,4]
        // arr[3] = 4;
        // 目标:
        // arr[-1] = arr[3] = 4
        // arr[-2] = arr[2] = 3
        //  .....
        // arr[-n] = arr[arr.length - n]

        var arr1 = new Proxy(arr,{
            get: function(target,prop) {
                console.log(target,prop)
                // 判断是数字
                if(false === isNaN(prop)) {
                    var idx = Number(prop)
                    // 是不是负数
                    if(idx < 0) {
                        idx = target.length + idx
                    }
                    return target[idx]
                } else {
                    return target[prop]
                }
            }
        })

        console.log(arr1[-1])
    </script>

附:代理列表

在new Proxy的第二个参数中,可以设置的代理属性如下:

var proxyObj = new Proxy(obj, {
  get: function(tagert,key,receiver){},
  set: function(tagert,key,value){},
  has: function(tagert,key){},
  deleteProperty: function(tagert,key){},
  ownKeys: function(tagert){},
  getOwnPropertyDescriptor: function(tagert,key){},
  defineProperty: function(tagert,key,desc){},
  preventExtensions: function(tagert){},
  getPrototypeOf: function(tagert){},
  isExtensible: function(tagert){},
  setPrototypeof: function(tagert,proto){},
  apply: function(tagert,obj,args){},
  construct: function(tagert,args){},
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值