成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深入理解ES6筆記(十一)代理(Proxy)和反射(Reflection)API(12)

explorer_ddf / 1725人閱讀

摘要:是陷阱函數(shù)對(duì)應(yīng)的反射方法,同時(shí)也是操作的默認(rèn)行為。對(duì)象外形指的是對(duì)象已有的屬性與方法的集合,由于該屬性驗(yàn)證只須在讀取屬性時(shí)被觸發(fā),因此只要使用陷阱函數(shù)。無論該屬性是對(duì)象自身的屬性還是其原型的屬性。

主要知識(shí)點(diǎn):代理和反射的定義、常用的陷阱函數(shù)、可被撤銷的代理、將代理對(duì)象作為原型使用、將代理作為類的原型

《深入理解ES6》筆記 目錄

代理與反射

代理是什么?

通過調(diào)用 new Proxy() ,你可以創(chuàng)建一個(gè)代理用來替代另一個(gè)對(duì)象(被稱之為目目標(biāo)對(duì)象) ,這個(gè)代理對(duì)目標(biāo)對(duì)象進(jìn)行了虛擬,因此該代理與該目標(biāo)對(duì)象表面上可以被當(dāng)作同一個(gè)對(duì)象來對(duì)待。
代理允許你攔截目標(biāo)對(duì)象上的底層操作,而這本來是JS引擎的內(nèi)部能力,攔截行為適用了一個(gè)能響應(yīng)特定操作的函數(shù)(被稱之為陷阱);

反射是什么?

被Reflect對(duì)象所代表的反射接口,是給底層操作提供默認(rèn)行為的方法的集合,這些操作是能夠被代理重寫的。每個(gè)代理陷阱都有一個(gè)對(duì)應(yīng)的反射方法,每個(gè)方法都與對(duì)應(yīng)的陷阱函數(shù)同名,并且接收的參數(shù)也與之一致。

創(chuàng)建一個(gè)簡(jiǎn)單的代理

使用Proxy構(gòu)建可以創(chuàng)建一個(gè)簡(jiǎn)單的代理對(duì)象,需要傳遞兩個(gè)參數(shù):目標(biāo)對(duì)象以及一個(gè)處理器,后者是定義一個(gè)或多個(gè)陷阱函數(shù)的對(duì)象。如果不定義陷阱函數(shù),則依然使用目標(biāo)對(duì)象的默認(rèn)行為:

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"
使用 set 陷阱函數(shù)驗(yàn)證屬性值

假設(shè)你想要?jiǎng)?chuàng)建一個(gè)對(duì)象,并要求其屬性值只能是數(shù)值,這就意味著該對(duì)象的每個(gè)新增屬性都要被驗(yàn)證,并且在屬性值不為數(shù)值類型時(shí)應(yīng)當(dāng)拋出錯(cuò)誤。為此你需要定義 set 陷阱函數(shù)來重寫設(shè)置屬性值時(shí)的默認(rèn)行為,該陷阱函數(shù)能接受四個(gè)參數(shù):

trapTarget :將接收屬性的對(duì)象(即代理的目標(biāo)對(duì)象);

key :需要寫入的屬性的鍵(字符串類型或符號(hào)類型);

value :將被寫入屬性的值;

receiver :操作發(fā)生的對(duì)象(通常是代理對(duì)象)。

Reflect.set() 是 set 陷阱函數(shù)對(duì)應(yīng)的反射方法,同時(shí)也是 set 操作的默認(rèn)行為。
Reflect.set() 方法與 set 陷阱函數(shù)一樣,能接受這四個(gè)參數(shù),讓該方法能在陷阱函數(shù)內(nèi)部被方便使用:

let target = {
    name: "target"
};
let proxy = new Proxy(target, {
    set(trapTarget, key, value, receiver) {
        // 忽略已有屬性,避免影響它們
        if (!trapTarget.hasOwnProperty(key)) {
            if (isNaN(value)) {
                throw new TypeError("Property must be a number.");
            }
        }
        // 添加屬性
        return Reflect.set(trapTarget, key, value, receiver);
    }
});
// 添加一個(gè)新屬性
proxy.count = 1;
console.log(proxy.count); // 1
console.log(target.count); // 1
// 你可以為 name 賦一個(gè)非數(shù)值類型的值,因?yàn)樵搶傩砸呀?jīng)存在
proxy.name = "proxy";
console.log(proxy.name); // "proxy"
console.log(target.name); // "proxy"
// 拋出錯(cuò)誤
proxy.anotherName = "proxy";
使用 get 陷阱函數(shù)進(jìn)行對(duì)象外形驗(yàn)證

JS 語言有趣但有時(shí)卻令人困惑的特性之一,就是讀取對(duì)象不存在的屬性時(shí)并不會(huì)拋出錯(cuò)誤,而會(huì)把 undefined 當(dāng)作該屬性的值,例如:

let target = {};
console.log(target.name); // undefined

在多數(shù)語言中,試圖讀取 target.name 屬性都會(huì)拋出錯(cuò)誤,因?yàn)樵搶傩圆⒉淮嬖冢坏?JS 語言卻會(huì)使用 undefined 。
對(duì)象外形( Object Shape )指的是對(duì)象已有的屬性與方法的集合,由于該屬性驗(yàn)證只須在讀取屬性時(shí)被觸發(fā),因此只要使用 get 陷阱函數(shù)。該陷阱函數(shù)會(huì)在讀取屬性時(shí)被調(diào)用,即使該屬性在對(duì)象中并不存在,它能接受三個(gè)參數(shù):

trapTarget :將會(huì)被讀取屬性的對(duì)象(即代理的目標(biāo)對(duì)象);

key :需要讀取的屬性的鍵(字符串類型或符號(hào)類型);

receiver :操作發(fā)生的對(duì)象(通常是代理對(duì)象)。

相應(yīng)的Reflect.get()方法同樣擁有這三個(gè)參數(shù)。進(jìn)行對(duì)象外形驗(yàn)證的示例代碼:

//import {color,sum,magicNumber} from "./export.js"
import * as example from "./export.js"
console.log(example.color)
console.log(example.magicNumber)

console.log(example.


    sum(76, 2))



let proxy = new Proxy({}, {
    get(trapTarget, key, receiver) {
        if (!(key in receiver)) {
            throw new TypeError("Property " + key + " doesn"t exist.");
        }
        return Reflect.get(trapTarget, key, receiver);
    }
});
// 添加屬性的功能正常
proxy.name = "proxy";
console.log(proxy.name); // "proxy"
// 讀取不存在屬性會(huì)拋出錯(cuò)誤
console.log(proxy.nme); // 拋出錯(cuò)誤
使用 has 陷阱函數(shù)隱藏屬性

in運(yùn)算符用于判斷指定對(duì)象中是否存在某個(gè)屬性,如果對(duì)象的屬性名與指定的字符串或符號(hào)值相匹配,那么in運(yùn)算符就會(huì)返回true。無論該屬性是對(duì)象自身的屬性還是其原型的屬性。
has陷阱函數(shù)會(huì)在使用in運(yùn)算符的情況下被調(diào)用,控制in運(yùn)算符返回不同的結(jié)果,has陷阱函數(shù)會(huì)傳入兩個(gè)參數(shù):

trapTarget:代理的目標(biāo)對(duì)象;
key:屬性鍵;

Reflect.has()方法接收相同的參數(shù),并向in運(yùn)算符返回默認(rèn)的響應(yīng)結(jié)果,用于返回默認(rèn)響應(yīng)結(jié)果。


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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97024.html

相關(guān)文章

  • 深入理解ES6筆記——代理Proxy反射ReflectionAPI12

    摘要:方法與代理處理程序的方法相同。使用給目標(biāo)函數(shù)傳入指定的參數(shù)。當(dāng)然,不用反射也可以讀取的值。的例子我們可以理解成是攔截了方法,然后傳入?yún)?shù),將返回值賦值給,這樣我們就能在需要讀取這個(gè)返回值的時(shí)候調(diào)用。這種代理模式和的代理有異曲同工之妙。 反射 Reflect 當(dāng)你見到一個(gè)新的API,不明白的時(shí)候,就在瀏覽器打印出來看看它的樣子。 showImg(https://segmentfault....

    ZHAO_ 評(píng)論0 收藏0
  • 深入理解ES6筆記——代理Proxy反射ReflectionAPI12

    摘要:方法與代理處理程序的方法相同。使用給目標(biāo)函數(shù)傳入指定的參數(shù)。當(dāng)然,不用反射也可以讀取的值。的例子我們可以理解成是攔截了方法,然后傳入?yún)?shù),將返回值賦值給,這樣我們就能在需要讀取這個(gè)返回值的時(shí)候調(diào)用。這種代理模式和的代理有異曲同工之妙。 反射 Reflect 當(dāng)你見到一個(gè)新的API,不明白的時(shí)候,就在瀏覽器打印出來看看它的樣子。 showImg(https://segmentfault....

    shiina 評(píng)論0 收藏0
  • 深入理解ES6筆記——導(dǎo)讀

    摘要:最近買了深入理解的書籍來看,為什么學(xué)習(xí)這么久還要買這本書呢主要是看到核心團(tuán)隊(duì)成員及的創(chuàng)造者為本書做了序,作為一個(gè)粉絲,還是挺看好這本書能給我?guī)硪粋€(gè)新的升華,而且本書的作者也非常厲害。 使用ES6開發(fā)已經(jīng)有1年多了,以前看的是阮一峰老師的ES6教程,也看過MDN文檔的ES6語法介紹。 最近買了《深入理解ES6》的書籍來看,為什么學(xué)習(xí)ES6這么久還要買這本書呢?主要是看到Daniel A...

    Godtoy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<