首页前端开发JavaScript深入浅析ES6中的Proxy(代理)

深入浅析ES6中的Proxy(代理)

时间2024-01-30 00:09:02发布访客分类JavaScript浏览285
导读:收集整理的这篇文章主要介绍了深入浅析ES6中的Proxy(代理),觉得挺不错的,现在分享给大家,也给大家做个参考。创建一个简单的Proxylet target = {}let PRoxy = new Proxy(target, {} pro...
收集整理的这篇文章主要介绍了深入浅析ES6中的Proxy(代理),觉得挺不错的,现在分享给大家,也给大家做个参考。

创建一个简单的Proxy

let target = {
}
let PRoxy = new Proxy(target, {
}
    )proxy.name = 'proxy'console.LOG(proxy.name) // proxyconsole.log(target.name) // proxytarget.name = 'target'console.log(proxy.name) // targetconsole.log(target.name) // target

这个实例将"proxy"赋值给proxy.name属性时会在目标上创建name,代理只是简单的将操作转发给目标,他不会储存这个属性。相当于proxy.name和target.name引用的都是target.name的值。

使用set陷阱验证属性

set陷阱接收四个参数:

1.trapTarget:用于接收属性(代理的目标)的对象

2.key:要写入的属性键(字符串或者symbol)

3.value:被写入的属性值

4.receiver:操作发生的对象(通常是代理)

let target = {
    name: "target"}
let proxy = new Proxy(target, {
    set(trapTarget, key, value, receiver) {
        if (!trapTarget.hasOwnProPErty(key)) {
            if (isNaN(value)) {
                throw new TypeError("属性必须时数字")            }
        }
        return Reflect.set(trapTarget, key, value, receiver)    }
}
    )proxy.count = 1console.log(proxy.count) //1console.log(target.count) //1proxy.name = "proxy"console.log(proxy.name) //proxyconsole.log(target.name) //proxyproxy.other = "other" // 这里会报错因为不数字

这个实例每次在外面改变proxy的值时就会出发set函数。

用get陷阱验证对象结构

get接收3个参数

1.trapTarget:用于接收属性(代理的目标)的对象

2.key:要写入的属性键(字符串或者symbol)

3.receiver:操作发生的对象(通常是代理)

let proxy = new Proxy({
}
, {
    get(trapTarget, key, receiver) {
        if (!(key in receiver)) {
            throw new TypeError("属性" + key + "不存在")        }
        return Reflect.get(trapTarget, key, receiver)    }
}
    )proxy.name = "proxy"console.log(proxy.name) //proxyconsole.log(proxy.age) // 属性不存在会抛出错误

当我们访问proxy创建的对象属性时就会触发get方法

使用has陷阱因此已有属性

has接收2个参数:

1.trapTarget:用于接收属性(代理的目标)的对象

2.key:要写入的属性键(字符串或者symbol)

let target = {
    name: "target",    value: 42}
let proxy = new Proxy(target, {
    has(trapTarget, key) {
        if (key === 'value') {
            return false        }
 else {
            return Reflect.has(trapTarget, key)        }
    }
}
    )console.log("value" in proxy) // falseconsole.log("name" in proxy) // trueconsole.log("toString" in proxy) // true

用deleteProperty陷阱防止删除属性

deleteProperty接收2个参数:

1.trapTarget:用于接收属性(代理的目标)的对象

2.key:要写入的属性键(字符串或者symbol)

let target = {
    name: "target",    value: 42}
let proxy = new Proxy(traget, {
    deleteProperty(trapTarget, key) {
        if (key === "value") {
            return false        }
 else {
            return Reflect.deleteProperty(trapTarget, key)        }
    }
}
    )console.log("value" in proxy) // truelet result1 = delete proxy.valueconsole.log(result1) // falseconsole.log("value" in proxy) // trueconsole.log("name" in proxy) // truelet result2 = delete proxy.nameconsole.log(result2) // trueconsole.log("name" in proxy) // false

当外部要删除proxy的属性就会触发deleteProperty函数

原型代理陷阱(setProptotypeOf,getPrototypeOf)

setProptotypeOf接收2个参数

1.trapTarget:用于接收属性(代理的目标)的对象

2.proto:作为原型使用的对象

let target = {
}
let proxy = new Proxy(target, {
    // 访问时调用    getPrototypeOf(trapTarget) {
        return null    }
,    // 改变时调用    setPrototypeOf(trapTarget, proto) {
        return false    }
}
)let targetProto = Object.getPrototypeOf(target)let proxyProto = Object.getPrototypeOf(proxy)console.log(targetProto === Object.prototype) //trueconsole.log(proxyProto === Object.prototype) // falseconsole.log(proxyProto) // nullObject.setPrototypeOf(target, {
}
) // 成功Object.setPrototypeOf(proxy, {
}
    ) // 抛出错误

如果正常实现

let target = {
}
let proxy = new Proxy(target, {
    // 访问时调用    getPrototypeOf(trapTarget) {
        return Reflect.getPrototypeOf(trapTarget)    }
,    // 改变时调用    setPrototypeOf(trapTarget, proto) {
        return Reflect.setPrototypeOf(trapTarget, proto)    }
}
)let targetProto = Object.getPrototypeOf(target)let proxyProto = Object.getPrototypeOf(proxy)console.log(targetProto === Object.prototype) //trueconsole.log(proxyProto === Object.prototype) // trueObject.setPrototypeOf(target, {
}
) // 成功Object.setPrototypeOf(proxy, {
}
    ) // 成功

属性描述符陷阱

defineProperty接收三个参数:

1.trapTarget:用于接收属性(代理的目标)的对象

2.key:要写入的属性键(字符串或者symbol)

3.descriptor:属性的描述对象

let proxy = new Proxy({
}
, {
    defineProperty(trapTarget, key, descriptor) {
 // descriptor 只能接收enumerable, configurable, value, wrITeable, get, set         if (typeof key === "symbol") {
            return false        }
        return Reflect.defineProperty(trapTarget, key, descriptor)    }
,    getOwnPropertyDescriptor(trapTarget, key) {
        return Reflect.getOwnPropertyDescriptor(trapTarget, key)    }
}
)Object.defineProperty(proxy, "name", {
    value: "proxy"}
)console.log(proxy.name) //proxylet namesymbol = Symbol("name")Object.defineProperty(proxy, nameSymbol, {
    value: "proxy"}
    )

在外部调用defineProperty | getOwnPropertyDescriptor时会触发内部definenProperty | getOwnPropertyDescriptor方法。

ownKeys陷阱

ownKeys陷阱会拦截外部的Object.keys(),Object.getOwnPropertyName(),Object.getOwnPropertySymbols()和Object.assign()四个方法

let proxy = new Proxy({
}
, {
    ownKeys(trapTarget) {
            return Reflect.ownKeys(trapTarget).filter(key =>
 {
            return typeof key !== "string" || key[0] !== '_'        }
)    }
}
    )let nameSymbol = Symbol("name")proxy.name = "proxy"proxy._name = "private"proxy[nameSymbol] = "symbol"let names = Object.getOwnPropertyNames(proxy),    keys = Object.keys(proxy),    symbols = Object.getOwnPropertySymbols(proxy)console.log(names.length) // 1console.log(names) // nameconsole.log(keys.length) //1console.log(keys[0]) // nameconsole.log(symbols.length) //1console.log(symbols[0]) // symbol(name)

更多编程相关知识,请访问:编程入门!!

以上就是深入浅析ES6中的Proxy(代理)的详细内容,更多请关注其它相关文章!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

ES6

若转载请注明出处: 深入浅析ES6中的Proxy(代理)
本文地址: https://pptw.com/jishu/591781.html
深入浅析Node.js异步编程中的callback(回调) javascript中宿主对象和原生对象的区别是什么

游客 回复需填写必要信息