Hi FE !
Ai
git
前端面试题
前端小tip
  • vite
  • webpack
npm
  • vue2
  • vue3
react
GitHub
Ai
git
前端面试题
前端小tip
  • vite
  • webpack
npm
  • vue2
  • vue3
react
GitHub
  • Proxy是如何监听数组的

Proxy是如何监听数组的

  let arr = [1,2,3]
  let proxy = new Proxy(arr, {	
 	get: function (target, key, receiver) {
         console.log('get的key为 ===>' + key);
         return Reflect.get(target, key, receiver);
     },
     set(target, key, value, receiver){
         console.log('set的key为 ===>' + key, value);
         return Reflect.set(target, key, value, receiver);
     }
 })
 proxy[0]          // set的key为 ===>0
 proxy[3] = 12     // set的key为 ===>3  12

key值是索引,如果使用数组的方法呢?

  let arr = [1,2,3]
  let proxy = new Proxy(arr, {	
 	get: function (target, key, receiver) {
         console.log('get的key为 ===>' + key);
         return Reflect.get(target, key, receiver);
     },
     set(target, key, value, receiver){
         console.log('set的key为 ===>' + key, value);
         return Reflect.set(target, key, value, receiver);
     }
 })

proxy.push('2')
// get的key为 ===>push
// get的key为 ===>length
// set的key为 ===>3 2
// set的key为 ===>length 4

可以看到,get方法走了两次,set方法走了两次。因为push方法其实做了两步,第一次更新的是数组中的第4项,第二次更新的是数组的length 如何避免多次执行呢 用的hasOwProperty, set肯定会出发多次,但是通知只出去一次, 比如数组修改length的时候,hasOwProperty是true, 那就不触发

function hasOwn(target,key){
  return target.hasOwnProperty(key);
}

  let arr = [1,2,3]
  let proxy = new Proxy(arr, {	
 	get: function (target, key, receiver) {
         console.log('get的key为 ===>' + key);
         return Reflect.get(target, key, receiver);
     },
    set(target, key, value, receiver) {
        // 更改、新增属性
        let oldValue = target[key]; // 获取上次的值
        let hadKey = hasOwn(target,key); // 看这个属性是否存在
        let result = Reflect.set(target, key, value, receiver);
        if(!hadKey){ // 新增属性
            console.log('更新 添加')
        }else if(oldValue !== value){ // 修改存在的属性
            console.log('更新 修改')
        }
        // 当调用push 方法第一次修改时数组长度已经发生变化
        // 如果这次的值和上次的值一样则不触发更新
        return result;

    }
 })

proxy.push('2')

这样 set 就执行了一次啦

  let arr = [1,2,3]
  let proxy = new Proxy(arr, {	
 	get: function (target, key, receiver) {
         console.log('get的key为 ===>' + key);
         return Reflect.get(target, key, receiver);
     },
     set(target, key, value, receiver){
         console.log('set的key为 ===>' + key, value);
         return Reflect.set(target, key, value, receiver);
     }
 })

console.log(proxy, 'proxy的length=' + proxy.length)
console.log(arr, 'arr的length=' + arr.length)

// get的key为 ===>length
// Proxy(Array) {0: 1, 1: 2, 2: 3, 3: '2'} 'proxy的length=4'
// (4) [1, 2, 3, '2'] 'arr的length=4'

从console的结果所以可以看出,这里的proxy就是个类数组。那么可以猜想,如果proxy第一个参数传的是数组时,proxy就会转化成类数组,也可以调用数组的方法,length、push等,找不到的方法就去原型链上找。

所以,如果调用push等方法,key就是push,数组长度改变,key值就是length。

Edit this page
最近更新: 2025/6/27 02:24
Contributors: qdleader
qdleader
本站总访问量 129823次 | 本站访客数 12人