ES6-11学习笔记--代理Proxy

Proxy代理

常用拦截方法

 

ES5拦截:
let obj = {}
let newVal = ''
Object.defineProperty(obj, 'name', {
    get() {
        console.log('get');
        return newVal
    },
    set(val) {
        console.log('set');
        newVal = val
    }
})
obj.name = '张三'
console.log(obj.name);

  

proxy基本定义:
let pObj = {}
let p = new Proxy(pObj, {})
p.name = '李四'
console.log(pObj.name); // pObj的属性值已经通过p代理写入值

  

proxy常用的拦截钩子:
get
let arr = [1, 2, 3]
arr = new Proxy(arr, {
    get(target, prop) {
        console.log(`target:${target}  prop:${prop}`);
        return prop in target ? target[prop] : 'error'
    }
})
console.log(arr[1]);

let dict = {
    'name': '王五',
    'age': 18
}
dict = new Proxy(dict, {
    get(target, prop) {
        console.log(`target:${target}  prop:${prop}`);
        return prop in target ? target[prop] : prop;
    }
})
console.log(dict['name']); // 王五
console.log(dict['class']); // class

  

set
let arr2 = []
arr2 = new Proxy(arr2, {
    set(target, prop, val) {
        if (typeof val === 'number') {
            target[prop] = val
            return true
        } else {
            return false
        }
    }
})
arr2.push(5)
arr2.push(6)
console.log(arr2[0], arr2[1]);

  

has
let range = {
    start: 1,
    end: 5
}

range = new Proxy(range, {
    has(target, prop) {
        return prop >= target.start && prop <= target.end
    }
})
console.log(2 in range); // true
console.log(9 in range); // false

  

ownKeys,循环遍历的时候进行拦截
deleteProperty,删除拦截
现在我们把_开头的属性为似有属性,不进行遍历出来
我们禁止_开头的似有属性删除
let user = {
    name: '张三',
    age: 18,
    _password: '***'
}
user = new Proxy(user, {
    ownKeys(target) {
        return Object.keys(target).filter(key => !key.startsWith('_'))
    },
    deleteProperty(target, prop) {
        if (prop.startsWith('_')) {
            throw new Error('不可删除')
        } else {
            delete target[prop]
            return true
        }
    }
})
for (let key in user) {
    console.log(key);
}

try {
    delete user._password;
} catch (e) {
    console.log(e.message);
}

  

apply,拦截函数调用、call、apply的操作
let sum = (...args) => {
    let num = 0;
    args.forEach(item => {
        num += item
    })
    return num
}
sum = new Proxy(sum, {
    apply(target, ctx, args) {
        return target(...args) * 2
    }
})
console.log(sum(1, 2));
console.log(sum.call(null, 1, 2));
console.log(sum.apply(null, [1, 2]));

  

construct,拦截new
let People = class {
    constructor(name) {
        this.name = name
    }
}
People = new Proxy(People, {
    construct(target, args, newTarget) {
        console.log('construct');
        return new target(...args)
    }
})
console.log(new People('张三'));

  

posted @ 2021-05-31 15:48  火星_PGY  阅读(55)  评论(0)    收藏  举报