溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JavaScript對象管家Proxy怎么使用

發(fā)布時間:2023-03-10 10:22:02 來源:億速云 閱讀:110 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“JavaScript對象管家Proxy怎么使用”,在日常操作中,相信很多人在JavaScript對象管家Proxy怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”JavaScript對象管家Proxy怎么使用”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

JavaScript 在 ES6 中,引入了一個新的對象類型 Proxy,它可以用來代理另一個對象,并可以在代理過程中攔截、覆蓋和定制對象的操作。Proxy 對象封裝另一個對象并充當(dāng)中間人,其提供了一個捕捉器函數(shù),可以在代理對象上攔截所有的操作,包括訪問屬性、賦值屬性、函數(shù)調(diào)用等等。通過攔截這些操作,可以對代理對象進行定制和控制。

JavaScript對象管家Proxy怎么使用

在開始介紹 Proxy 對象前先了解 3 個術(shù)語:

  • target 目標(biāo)對象:要代理的對象或函數(shù)。

  • handler 處理程序:對代理的對象或函數(shù)執(zhí)行某些操作的函數(shù)。

  • traps 捕捉器:這些是一些用于處理目標(biāo)的函數(shù)。單擊此處閱讀有關(guān)陷阱的更多信息。

語法

Proxy 對象的基本語法如下:

new Proxy(target, handler);

其中,target 是被代理的目標(biāo)對象,handler 是一個對象,它包含了一些捕捉器函數(shù),用來攔截代理對象的操作。

下面是一些常見的攔截操作和對應(yīng)的捕捉器函數(shù):

對象方法

  • getPrototypeOf()Object.getPrototypeOf 方法的捕捉器。

  • setPrototypeOf()Object.setPrototypeOf 方法的捕捉器。

  • isExtensible()Object.isExtensible 方法的捕捉器。

  • preventExtensions()Object.preventExtensions 方法的捕捉器。

  • getOwnPropertyDescriptor()Object.getOwnPropertyDescriptor 方法的捕捉器。

  • handler.defineProperty()Object.defineProperty 方法的捕捉器。

屬性獲取器/設(shè)置器

  • get(target, propKey, receiver):攔截對象的讀取屬性操作,返回屬性值。

  • set(target, propKey, value, receiver):攔截對象的設(shè)置屬性操作,返回一個布爾值表示是否設(shè)置成功。

  • has(target, propKey):攔截對象的 in 操作符,返回一個布爾值表示對象是否包含該屬性。

  • deleteProperty(target, propKey):攔截對象的 delete 操作符,返回一個布爾值表示是否刪除成功。

  • ownKeys()Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法的捕捉器

函數(shù)方法

如果目標(biāo)對象是一個函數(shù),可以使用下面 2 個捕捉器。

  • apply(target, thisArg, args):攔截函數(shù)的調(diào)用操作,返回調(diào)用結(jié)果。

  • construct(target, args, newTarget):攔截 new 操作符,返回一個對象。

Proxy 在目標(biāo)對象周圍創(chuàng)建一個不可檢測的屏障,將所有操作重定向到處理程序?qū)ο蟆H绻l(fā)送一個空的 handler ,代理只是原始對象的一個空包裝器。

const author = {
    name: "Quintion",
    age: 36,
};
const proxyAuthor = new Proxy(author, {});
console.log(author.name); // Quintion
console.log(proxyAuthor.name); // Quintion

為了賦予代理意義,需要向處理程序添加一些操作方法。

捕捉器

每當(dāng)與一個對象交互時,都在調(diào)用一個內(nèi)部方法。代理允許使用捕捉器攔截給定內(nèi)部方法的執(zhí)行。

因此,當(dāng)運行 author.name 時,告訴 JavaScript 引擎調(diào)用內(nèi)部 [[GET]] 方法來檢索 name 屬性。當(dāng)運行 proxyAuthor.name 時,get 捕捉器會調(diào)用處理程序中定義的 get() 函數(shù)來執(zhí)行,然后再將調(diào)用發(fā)送到原始對象。

JavaScript對象管家Proxy怎么使用

get

get() 方法有兩個必需的參數(shù):

  • target — 傳遞給代理的對象。

  • property — 訪問的屬性的名稱。

要自定義代理,在處理程序?qū)ο笊隙x函數(shù)。下面定義了 get 方法來記錄訪問:

const handler = {
    get(target, property) {
        console.log(`捕捉器 GET:${property}`);
        return target[property];
    },
};

為了讓調(diào)用通過,捕捉器 get 返回 target[property]。使用方式如下:

const author = {
    name: "Quintion",
    age: 36,
};
const handler = {
    get(target, property) {
        console.log(`捕捉器 GET[${property}]`);
        return target[property];
    },
};
const proxyAuthor = new Proxy(author, handler);
console.log(proxyAuthor.name);

執(zhí)行后,將打印以下內(nèi)容:

捕捉器 GET[name]
Quintion

set

set 捕捉器用于給目標(biāo)對象進行賦值操作,返回值是一個布爾值。set 捕捉器需要的參數(shù)如下:

  • target — 傳遞給代理的對象。

  • property — 將被設(shè)置的屬性名或 Symbol。

  • value — 新的屬性值

  • receiver — 最初被調(diào)用的對象。

下面通過 set 捕捉器驗證年齡值的輸入:

const handler = {
    set(target, property, value) {
        if (property === "age" && typeof value !== "number") {
            throw new TypeError("年齡必須是一個數(shù)字");
        }
        target[property] = value;
        return true;
    },
};

下面嘗試將錯誤的類型值賦值給 age ,則會拋出錯誤:

const proxyAuthor = new Proxy(author, handler);
proxyAuthor.age = "young";
// 執(zhí)行后拋出異常:throw new TypeError("年齡必須是一個數(shù)字");

set() 方法應(yīng)該返回一個布爾值 true 用來表示賦值成功。 在嚴(yán)格模式下運行,并且返回一個假值或什么都不返回,則會拋出錯誤。

除了攔截對屬性的讀取和修改,Proxy 總共可以攔截 13 種操作。

應(yīng)用場景

通過 Proxy 對象的特征,可以將其使用在下面這些場合:

驗證和過濾

代理Proxy 用于攔截和驗證對對象屬性的訪問。如,可以創(chuàng)建一個代理來檢查用戶輸入的數(shù)據(jù)是否符合預(yù)期的格式,并拒絕不正確的數(shù)據(jù)。就如下面 age 屬性賦值判斷

緩存

代理Proxy 用于緩存對象的操作結(jié)果,以避免重復(fù)計算。如,可以創(chuàng)建一個代理來攔截對象的某些方法,并將結(jié)果存儲在緩存中,以便將來使用。

下面是一個基于 Proxy 的緩存庫的示例:

class Cache {
    constructor() {
        this.cache = new Map();
        this.proxy = new Proxy(this, {
            get(target, property) {
                if (property === "get") {
                    return (key) => {
                        return target.cache.get(key);
                    };
                }
                if (property === "set") {
                    return (key, value) => {
                        target.cache.set(key, value);
                    };
                }
                if (property === "has") {
                    return (key) => {
                        return target.cache.has(key);
                    };
                }
                if (property === "delete") {
                    return (key) => {
                        return target.cache.delete(key);
                    };
                }
            },
        });
    }
}

在上面的代碼中,定義了一個 Cache 類,該類中包含一個內(nèi)部的 Map 對象用于存儲緩存數(shù)據(jù),并且定義了一個 proxy 對象作為該類的代理。

proxy 對象的 get 方法中,根據(jù)傳入的屬性名返回相應(yīng)的方法。如果屬性名為 get,則返回一個可以獲取緩存值的方法;如果屬性名為 set,則返回一個可以設(shè)置緩存值的方法;如果屬性名為 has,則返回一個可以判斷是否存在緩存值的方法;如果屬性名為 delete,則返回一個可以刪除緩存值的方法。

下面是一個使用該緩存庫的示例:

const cacheHelper = new Cache();
cacheHelper.set("foo", "bar");
console.log(cacheHelper.get("foo")); // "bar"
console.log(cacheHelper.has("foo")); // true
cacheHelper.delete("foo");
console.log(cacheHelper.get("foo")); // undefined
console.log(cacheHelper.has("foo")); // false

在上面的代碼中,創(chuàng)建了一個 Cache 對象,并調(diào)用其 set 方法設(shè)置緩存值,然后調(diào)用其 get 方法獲取緩存值,并調(diào)用其 has 方法判斷緩存值是否存在,最后調(diào)用其 delete 方法刪除緩存值。

監(jiān)聽屬性變化

代理Proxy用于監(jiān)視對象屬性的變化,并在屬性發(fā)生變化時觸發(fā)其他操作。如,創(chuàng)建一個代理來監(jiān)視對象屬性的變化,并在屬性發(fā)生變化時更新頁面上的元素。

防止誤操作

代理Proxy用于防止誤操作,如,創(chuàng)建一個代理來攔截對象的某些方法,并在方法調(diào)用時檢查一些條件,以確保方法只在正確的上下文中調(diào)用。

虛擬化

代理Proxy可以用于創(chuàng)建虛擬化對象。如,創(chuàng)建一個代理對象,用于代替某個對象的真實實現(xiàn),并且在實際對象執(zhí)行之前,對其進行修改或攔截。

到此,關(guān)于“JavaScript對象管家Proxy怎么使用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI