The first time I came across the word proxy, I was setting up the browser proxy. Today, I noticed that this word also appeared in the new ES6 syntax, so I decided to study how this magic thing is used. After learning, in the xiaobian simple understanding, it is similar to the security guard at the gate of the community, and only when the conditions are met can the release be allowed. In data, there is a rule for getting a value or setting a value. You can also follow my wechat public number, Snail Quanzhan.

Es5 handles proxy syntax

let obj = {}
Object.defineProperty(obj,'name', {// The parameters are the object itself, the object value, the get and set methods
    get(){
        console.log("666")
        return "GET IT"
    },
    set(){
        console.log("SET")}})console.log(obj.name)// 666 GET IT
Copy the code

Es6 basic syntax

let obj = {}
let p = new Proxy(obj,{}) // The parameters are the object to be proxied and the proxied rule
p.name= 'lilei'
console.log(obj.name) // lilei
for(let key in obj){
    console.log(key) // name
}
Copy the code

1. Proxy GET

let arr = [7.8.9]
arr = new Proxy(arr,{
    get(target,prop){ // Target indicates the current array prop is the current index
        return prop in target ? target[prop] : 'error'}})console.log(arr[1]) / / 8
console.log(arr[10]) // error
let dict = {
    "hello":"Hello"."world":"The world"
}

dict = new Proxy(dict,{
    get(target,prop){
        return prop in target ? target[prop]:prop
    }
})

console.log(dict["hello"]) / / how are you
console.log(dict["school"]) // school
Copy the code

2, proxy set: must have a return value, the return value is Boolean

let arr = []
arr = new Proxy(arr,{
    set(target,prop,val){
        if(typeof val === 'number'){
            target[prop] = val
            return true
        }else{
            return false
        }
    }
})
arr.push(5)
arr.push(6)
console.log(arr[0],arr[1],arr.length) // 5 6 2 does not break the original method
Copy the code

3, agent 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
Copy the code

4. Proxy ownKeys

// Hide attributes within the object that begin with an underscore
let userinfo = {
    username:"lilei".age:34._password:"* * *" // Simulate the private property
}

userinfo = new Proxy(userinfo,{
    ownKeys(target){
        return Object.keys(target).filter(key= >! key.startsWith("_"))}})for(let key in userinfo){
    console.log(key) // name age
}

Object.keys(userinfo) // name age
Copy the code

5, agent deleteProperty: the effect of delete

let user = {
    name:"lilei".age:34._password:"* * *"
}
user = new Proxy(user,{
    deleteProperty(target,prop){ // Intercept delete operation, need to return a Boolean value
        if(prop.startsWith("_")) {throw new Error("Undeletable")}else{
            delete target[prop]
            return true}}})try{
    delete user._password
}catch(e){
    console.log(e.message) // Cannot be deleted
}
Copy the code

6. Comprehensive examples

let user = {
    name:"lilei".age:34._password:"* * *"
}

user = new Proxy(user,{
    get(target,prop){
        if(prop.startsWith("_")) {throw new Error("Inaccessible")}else{
            return target[prop]
        }
    },
    set(target,prop,val){ // set must return a value
        if(prop.startsWith("_")) {throw new Error("Inaccessible")}else{
            target[prop] = val
            return true}},deleteProperty(target,prop){ // Intercept delete operation, need to return a Boolean value
        if(prop.startsWith("_")) {throw new Error("Delete")}else{
            delete target[prop]
            return true}},ownKeys(target){
        return Object.keys(target).filter(key= >! key.startsWith("_"))}})console.log(user.name) // lilei
console.log(user._password) // Error: inaccessible
user.age = 18
console.log(user.age) / / 18
// user._password = "&&&" // Error
try{
    user._password = && "&"
}catch(e){  
    console.log(e.message) // Not accessible
}

try{
    delete user._password
}catch(e){
    console.log(e.message) // Cannot be deleted
        }
for(let key in user){
    console.log(key) // ["name","age"]
}
Copy the code

7, agent apply

let sum = (. args) = > {
    let num = 0
    args.forEach(item= > {
        num += item
    })
    return num
}
sum = new Proxy(sum,{
    apply(target,ctx,args){ // Target, context, parameters of the proxy
        returntarget(... args) *2}})console.log(sum(1.2)) / / 6
console.log(sum.call(null.1.2.3)) // 12 Call function arguments
console.log(sum.apply(null[1.2.3])) // 12 Calls an array of the current function arguments
Copy the code

Agent Construct: Acts on new

let User = class{
    constructor(name){
        this.name = name
    }
}
User = new Proxy(User,{
    construct(target,args,newTarget){ // The object must be returned
        console.log("starting...")
        return newtarget(... args) } })console.log(new User("lilei")) // starting... User{name:"lilei"}
Copy the code