ES6 Proxy为何物?

文章目录

系列文章目录

前言

一、Proxy语法

二、常用拦截操作

1.get

2.set

3.ownKeys

4.has

5.deleteProperty 

 6.apply

7.construct

总结


系列文章目录


ES5 VS ES6 之类的写法

ES6 Proxy为何物?

ES6 两种方式实现可迭代对象


前言

有过爬虫经历和科学上网经历的可能对proxy这个词并不陌生,Proxy是ES6中新增的一个非常强大的功能,可以理解为“代理”,它可以在访问对象的时候进行拦截修改


一、Proxy语法

let p = new Proxy(target,handler)

target:要进行代理的对象,可以还是代理疯狂套娃

handler:对象,里面的属性是进行代理操作时用到的函数

话不多说,上实例代码一目了然

二、常用拦截操作

1.get

作用:拦截对象属性的获取

let user1 = {
    name: 'Bob',
    _pwd: '123456'
}

// 现在我有一个需求,不想让别人读取到有关密码的信息
handler = {
    get(target,p) {
        if (p.startsWith('_')) {
            throw new Error('不可访问')
        } else {
            return target[p]
        }
    }
}
user1 = new Proxy(user1,handler)

2.set

作用:拦截设置对象属性,如xxx.xx = xxxx或xxx[xx] = xxxx,如果是数组的话还有push等。最后返回布尔值

let user1 = {
    name: 'Bob',
    age: 18,
    _pwd: '123456'
}

// 现在我有一个需求,年龄的设置只能是数字
handler = {
    set(target,p,value) {
        if (p === 'age') {
            if (typeof value !== 'number' || Number.isNaN(value)) {
                throw new TypeError('age必须是数字')
            } else if (age <= 0) {
                throw new TypeError('age要大于0')
            } else {
                target[p] = value
                return true
            }
        } else {
            target[p] = value
            return true
        }
    }
}
user1 = new Proxy(user1,handler)

3.ownKeys

作用:拦截获取对象属性的操作,如for...in,Object.getOwnPropertyNames,Object.getOwnPropertySymbols,Object.keys返回布尔值

let user1 = {
    name: 'Bob',
    age: 18,
    _pwd: '123456'
}

// 不想让别人知道有密码这个属性
handler = {
    ownKeys(target) {
        return Object.keys(target).filter(key => !key.startsWith('_'))
    }
}

user1 = new Proxy(user1,handler)
console.log(Reflect.ownKeys(user1)) // ['name','age']

4.has

作用:拦截in操作,返回布尔值 

let range = {
    min: 1,
    max: 10
}

// 看看x在不在range的范围里
range = new Proxy(range, {
    has(target,p) {
        return p >= range.min && p <= range.max
    }
})

console.log(1 in range) // true

5.deleteProperty 

作用:拦截delete xxx[xx]操作,返回布尔值

let user1 = {
    name: 'Bob',
    age: 18,
    _pwd: '123456'
}

// _开头的我不想能被删掉
user1 = new Proxy(user1,{
    deleteProperty(target,p) {
        if (p.startsWith('_')) {
            throw new Error('没有删除权限')
        } else {
            delete user1[p]
            return true
        }
    }
})

 6.apply

作用:拦截Proxy实例作为函数被调用的操作

参数:ctx 被调用时的上下文对象;argsList 参数数组

let sum = (...args) {
    let total = 0
    args.forEach(item => {
        total += item
    })
    return total
}

sum = new Proxy(sum,{
    apply(target,ctx,argsList) {
        return new target(...argsList) + 1 // 这样就篡改了sum的结果
    }
})

7.construct

作用:拦截Proxy实例作为构造函数被调用的操作,比如new

参数:argsList 参数列表;newTarget 网上说是最初被调用的构造函数,还不是很了解,欢迎大佬们赐教!!!

class Person {
    constructor(name) {
        this.name = name
    }
}

Person = new Proxy(Person,{
    construct(target,argsList,newTarget) {
        console.log('This is construct')
        return {name: 'whoami'}
    }
})

console.log(new Person('Bob'))
// This is construct
// {name: 'whoami'}

总结

欢迎各位大佬,或者是同样在学习的伙伴一起交流

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值