资讯专栏INFORMATION COLUMN

es6基础0x020:代理

hatlonely / 811人阅读

摘要:概述代理嘛,就是请代理人代替自己做某件事,但是和自己不一样的是代理人可以有自己的行为,甚至可以做出和预期相违背的行为。

0x000 概述

代理嘛,就是请代理人代替自己做某件事,但是和自己不一样的是代理人可以有自己的行为,甚至可以做出和预期相违背的行为。

0x001 栗子

声明一个普通对象origin,他有一个属性name

let origin={
    name: "origin"
}

声明一个代理对象

let proxy=new Proxy(origin, {
    get: (target, key)=>target[key]+" from proxy",
    set: (target, key, value)=>target[key]="set by proxy "+value
})

此时输出originproxy,可以发现,proxy拥有和origin一样的name属性

console.log(origin) // {name: "origin"}
console.log(proxy) // Proxy {name: "origin"}

origin添加age属性,再输出,可以发现,originproxy都拥有了age属性

origin.age=1 
console.log(origin) // {name: "origin", age: "1"}
console.log(proxy) // Proxy {name: "origin", age "1"}

那就是代理吗,当然不是,我们尝试为proxy添加属性

proxy.x=1
console.log(origin) // {name: "origin", age: "1", x:"set by proxy 1"}
console.log(proxy) // Proxy {name: "origin", age "1"}

可以发现,虽然originproxy都拥有了x属性,但是并不是我们赋值的1,而是多了set by proxy 几个字符串,很明显,这里是执行了初始化proxy时传入的第二个对象的set方法
那如果我们get

console.log(proxy.x) // set by proxy 1
console.log(proxy.x) // set by proxy 1 from proxy

现在很清楚了,proxy就是origin的代理,所有在proxy上的操作都会同步到origin上,而对origin的操作却不会同步到proxy上,而且proxy还有自己的行为。

可以这么想,proxy就是origin的秘书,所有的事务处理都要提交给秘书,秘书有自己的办事准则,可以直接提交给老板,也可以拒绝提交,或者添加一些其他的行为再提交。那这个秘书到底能代理老板做哪些事呢?

0x002 陷阱

语法

let p = new Proxy(target, handler);

初始化一个代理需要有两个参数

target:代理目标

handle:陷阱,是一个对象,我们的操作就像一只逃跑的动物,如果猎人在所有可以逃跑的路上全部放满了陷阱,那我们总是会落入一起一个的。本质就是一个对象,键描述我们的操作,值是函数,描述我们的行为,一共有13种陷阱。

0x003 set:设置属性

语法:

set(target, key, value)

target: 代理对象

`key: 设置的属性

value: 设置的属性值

栗子:

let origin={}
let proxy=new Proxy(origin,{
    set:(target, key, value)=>{
        if(value>5)target[key]=value+10000
    }
})
proxy.x=1
proxy.y=10
console.log(proxy) // Proxy {y: 10010}
console.log(origin) // {y: 10010}

说明:
上面我们放置了一个set陷阱,当我们做set操作的时候,就会被捕捉到,我们判断value是否大于5,如果不大于5我们就不会做任何东西,但是如果大于5,就会给做赋值操作,并且还将他加上了10000。上面的栗子就相当于一个拦截器了。

0x004 get:访问属性

语法:

get(target, key)

target: 代理对象

`key: 访问的属性

栗子:

let origin={
    x:1,
    y:2
}
let proxy=new Proxy(origin,{
    get:(target, key)=>{
        if(key==="x")return "no"
        return target[key]
    }
})
console.log(proxy.x) // "no"
console.log(proxy.y) // 2

0x005 deleteProperty:删除属性

语法:

deleteProperty(target, key)

target: 代理对象

`key: 要删除的属性

栗子:

let origin={
    x:1,
    y:2
}
let proxy=new Proxy(origin,{
    deleteProperty:(target, key)=>{
        if(key==="x")return
        delete target[key]
    }
})
delete proxy.x
delete proxy.y
console.log(proxy) // {x:1}

0x006 has:判断是否包含某属性

语法:

has(target, key)

target: 代理对象

`key: 要判断的属性

栗子:

let origin={
    x:1,
    y:2
}
let proxy=new Proxy(origin,{
    has:(target, key)=>{
        if(key==="x")return false
        return true
    }
})
console.log("x" in proxy) // false
console.log("y" in proxy) // true

0x007 ownKeys:获取自身属性值

语法:

ownKeys(target)

target: 代理对象

栗子:

let origin={
    x:1,
    y:2
}
let proxy=new Proxy(origin,{
    ownKeys:(target)=>{
        return ["y"]
    }
})
console.log(Object.getOwnPropertyNames(proxy)) // ["y"]

0x008 getPrototypeOf:获取prototype

语法:

getPrototypeOf(target)

target: 代理对象

栗子

let origin={
    x:1,
    y:2
}
let proxy=new Proxy(origin,{
    getPrototypeOf:(target)=>{
        return null
    }
})
console.log(Object.getPrototypeOf(p)) // null

0x009 setPrototypeOf:设置prototype

语法:

setPrototypeOf(target, prototype)

target: 代理对象

prototype: 要设置的prototype

栗子

let origin={
    x:1,
    y:2
}
let proxy=new Proxy(origin,{
    setPrototypeOf:(target, prototype)=>{
        throw "no"
    }
})
Object.setPrototypeOf(proxy, {}) //  Uncaught no

0x010 defineProperty :设置属性描述

语法:

defineProperty(target, prop, descriptor)

target: 代理对象

prop: 要设置描述的属性

descriptor: 描述

栗子

let origin={}
let proxy=new Proxy(origin,{
    defineProperty:(target, prop, descriptor)=>{
        throw "no"
    }
})
Object.defineProperty(proxy, "x", {configurable: true}) //  Uncaught no

0x011 getOwnPropertyDescriptor :获取自身属性描述

语法:

getOwnPropertyDescriptor(target, prop)

target: 代理对象

prop: 获取描述的属性

栗子

let origin={}
let proxy=new Proxy(origin,{
    getOwnPropertyDescriptor:(target, prop)=>{
        throw "no"
    }
})
Object.getOwnPropertyDescriptor(proxy, "x") //  Uncaught no

0x012 isExtensible:判断是否可扩展

语法:

isExtensible(target)

target: 代理对象

栗子

let origin={}
let proxy=new Proxy(origin,{
    isExtensible:(target)=>{
       return false
    }
})
console.log(Object.isExtensible(proxy)); // false

0x013 preventExtensions :阻止扩展

语法:

preventExtensions(target)

target: 代理对象

栗子:

let origin={}
let proxy=new Proxy(origin,{
    preventExtensions:(target)=>{
        return false;
    }
})
console.log(Object.preventExtensions(proxy)); // Uncaught TypeError: "preventExtensions" on proxy: trap returned falsish

0x014 construct:构造

语法:

construct(target, argumentsList, newTarget) 

target: 代理对象

argumentsList: 参数列表

newTarget: 新对象

栗子:

let Origin=function(){}
let OriginProxy=new Proxy(Origin,{
  construct: function(target, argumentsList, newTarget) {
      throw "error"  
  }
})
new OriginProxy() // Uncaught error

0x015 apply:调用

语法:

apply(target, thisArg, argumentsList)

target: 代理对象

thisArg: 上下文

argumentsList: 参数列表

栗子:

let origin=function(){}
let proxy=new Proxy(origin,{
  apply: function(target, thisArg, argumentsList) {
    throw "error"
  }
})
origin() // Uncaught error

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108643.html

相关文章

  • 《深入理解ES6》笔记——代理(Proxy)和反射(Reflection)API(12)

    摘要:方法与代理处理程序的方法相同。使用给目标函数传入指定的参数。当然,不用反射也可以读取的值。的例子我们可以理解成是拦截了方法,然后传入参数,将返回值赋值给,这样我们就能在需要读取这个返回值的时候调用。这种代理模式和的代理有异曲同工之妙。 反射 Reflect 当你见到一个新的API,不明白的时候,就在浏览器打印出来看看它的样子。 showImg(https://segmentfault....

    ZHAO_ 评论0 收藏0
  • 《深入理解ES6》笔记——代理(Proxy)和反射(Reflection)API(12)

    摘要:方法与代理处理程序的方法相同。使用给目标函数传入指定的参数。当然,不用反射也可以读取的值。的例子我们可以理解成是拦截了方法,然后传入参数,将返回值赋值给,这样我们就能在需要读取这个返回值的时候调用。这种代理模式和的代理有异曲同工之妙。 反射 Reflect 当你见到一个新的API,不明白的时候,就在浏览器打印出来看看它的样子。 showImg(https://segmentfault....

    shiina 评论0 收藏0
  • 深入理解 Generator 函数

    摘要:同时,迭代器有一个方法来向函数中暂停处抛出一个错误,该错误依然可以通过函数内部的模块进行捕获处理。 本文翻译自:Diving Deeper With ES6 Generators 由于个人能力有限,翻译中难免有纰漏和错误,望不吝指正issue ES6 Generators:完整系列 The Basics Of ES6 Generators Diving Deeper With E...

    jzzlee 评论0 收藏0
  • ES6中的代理(Proxy)和反射(Reflection)

    摘要:代理和反射的定义调用可常见代替其它目标对象的代理,它虚拟化了目标,所以二者看起来功能一致。代理可拦截引擎内部目标的底层对象操作,这些底层操作被拦截后会触发响应特定操作的陷阱函数。 代理和反射的定义 调用 new Proxy() 可常见代替其它目标 (target) 对象的代理,它虚拟化了目标,所以二者看起来功能一致。 代理可拦截JS引擎内部目标的底层对象操作,这些底层操作被拦截后会触发...

    Markxu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<