Home  >  Article  >  Web Front-end  >  An in-depth analysis of Proxy in ES6

An in-depth analysis of Proxy in ES6

青灯夜游
青灯夜游forward
2021-07-05 11:23:251688browse

An in-depth analysis of Proxy in ES6

Create a simple Proxy

let target = {}
let proxy = new Proxy(target, {})

proxy.name = 'proxy'

console.log(proxy.name) // proxy
console.log(target.name) // proxy

target.name = 'target'

console.log(proxy.name) // target
console.log(target.name) // target

This instance will create name on the target when assigning "proxy" to the proxy.name attribute. The proxy simply operates Forwarded to the target, he will not store this attribute. Equivalent to proxy.name and target.name refer to the value of target.name.

Use set trap to verify properties

The set trap receives four parameters:

1.trapTarget: an object used to receive properties (the target of the agent)

2.key: The attribute key to be written (string or symbol)

3.value: The attribute value being written

4.receiver: The object where the operation occurs (usually Proxy)

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 = 1
console.log(proxy.count) //1
console.log(target.count) //1

proxy.name = "proxy"

console.log(proxy.name) //proxy
console.log(target.name) //proxy

proxy.other = "other" // 这里会报错因为不数字

This instance will trigger the set function every time the value of proxy is changed outside.

Use get trap to verify the object structure

get receives 3 parameters

1.trapTarget: an object used to receive attributes (the target of the agent)

2.key: the attribute key to be written (string or symbol)

3.receiver: the object where the operation occurs (usually the proxy)

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) //proxy

console.log(proxy.age) // 属性不存在会抛出错误

When we access the object properties created by proxy The get method will be triggered

Use has trap, so there are existing attributes

has receives 2 parameters:

1.trapTarget: used to receive attributes (the target of the agent) Object

2.key: The property key to be written (string or 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) // false
console.log("name" in proxy) // true
console.log("toString" in proxy) // true

Use deleteProperty trap to prevent deletion of properties

deleteProperty receives 2 parameters:

1.trapTarget: The object used to receive attributes (the target of the agent)

2.key: The attribute key to be written (string or 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) // true

let result1 = delete proxy.value

console.log(result1) // false
console.log("value" in proxy) // true

console.log("name" in proxy) // true

let result2 = delete proxy.name
console.log(result2) // true
console.log("name" in proxy) // false

When If you want to delete the proxy's attribute externally, the deleteProperty function will be triggered

Prototype proxy trap (setProptotypeOf, getPrototypeOf)

setProptotypeOf receives 2 parameters

1.trapTarget: used to receive attributes (The target of the proxy)

2.proto: The object used as the prototype

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) //true
console.log(proxyProto === Object.prototype) // false
console.log(proxyProto) // null

Object.setPrototypeOf(target, {}) // 成功

Object.setPrototypeOf(proxy, {}) // 抛出错误

If implemented normally

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) //true
console.log(proxyProto === Object.prototype) // true

Object.setPrototypeOf(target, {}) // 成功

Object.setPrototypeOf(proxy, {}) // 成功

Property descriptor trap

defineProperty Receives three parameters:

1.trapTarget: the object used to receive attributes (the target of the agent)

2.key: the attribute key to be written (string or symbol)

3.descriptor: The description object of the property

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) //proxy

let nameSymbol = Symbol("name")

Object.defineProperty(proxy, nameSymbol, {
    value: "proxy"
})

The internal defineProperty | getOwnPropertyDescriptor method will be triggered when defineProperty | getOwnPropertyDescriptor is called externally.

ownKeys trap

ownKeys trap will intercept the four external methods Object.keys(), Object.getOwnPropertyName(), Object.getOwnPropertySymbols() and 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) // 1
console.log(names) // name

console.log(keys.length) //1
console.log(keys[0]) // name

console.log(symbols.length) //1
console.log(symbols[0]) // symbol(name)

For more programming-related knowledge, please visit: Introduction to Programming! !

The above is the detailed content of An in-depth analysis of Proxy in ES6. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete