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

資訊專欄INFORMATION COLUMN

【譯】Proxy及其優(yōu)勢

Freeman / 1922人閱讀

摘要:此方法充當(dāng)攔截器,在返回值之前,會首先對屬性值進(jìn)行檢查,如果不存在,則拋出異常。輸出與第一種情況相同,但此時(shí)函數(shù)專注于邏輯,只處理消息。在這種情況下,我們需要使用方法,并在其中進(jìn)行驗(yàn)證。在此示例中,我們不允許空和發(fā)布請求而不提供數(shù)據(jù)。

翻譯:劉小夕

原文鏈接:https://devinduct.com/blogpos...

什么是 Proxy

通常,當(dāng)談到JavaScript語言時(shí),我們討論的是ES6標(biāo)準(zhǔn)提供的新特性,本文也不例外。 我們將討論JavaScript代理以及它們的作用,但在我們深入研究之前,我們先來看一下Proxy的定義是什么。

MDN上的定義是:代理對象是用于定義基本操作的自定義行為(例如,屬性查找,賦值,枚舉,函數(shù)調(diào)用等)。

換句話說,我們可以說代理對象是我們的目標(biāo)對象的包裝器,我們可以在其中操縱其屬性并阻止對它的直接訪問。 你可能會發(fā)現(xiàn)將它們應(yīng)用到實(shí)際代碼中很困難,我鼓勵(lì)你仔細(xì)閱讀這個(gè)概念,它可能會改變你的觀點(diǎn)。

術(shù)語
handler

包含陷阱(traps)的占位符對象。

traps

提供屬性訪問的方法。這類似于操作系統(tǒng)中捕獲器的概念。

target

代理虛擬化的對象。(由代理對象包裝和操作的實(shí)際對象)

在本文中,我將為 getset 陷阱 提供簡單的用例,考慮到最后,我們將看到如何使用它們并包含更復(fù)雜的功能,如API。

語法和用例
let p = new Proxy(target, handler);

將目標(biāo)和處理程序傳遞給Proxy構(gòu)造函數(shù),這樣就創(chuàng)建了一個(gè)proxy對象?,F(xiàn)在,讓我們看看如何利用它。為了更清楚地看出Proxy的好處,首先,我們需要編寫一些沒有它的代碼。

想象一下,我們有一個(gè)帶有幾個(gè)屬性的用戶對象,如果屬性存在,我們想要打印用戶信息,如果不存在,則拋出異常。在不使用代理對象時(shí),判斷屬性值是否存在的代碼也放在了打印用戶信息的函數(shù),即 printUser 中(這并不是我們所希望的),如下demo所示:

let user = {
    name: "John",
    surname: "Doe"
};

let printUser = (property) => {
    let value = user[property];
    if (!value) {
        throw new Error(`The property [${property}] does not exist`);
    } else {
        console.log(`The user ${property} is ${value}`);
    }
}

printUser("name"); // 輸出: "The user name is John"
printUser("email"); // 拋出錯(cuò)誤: The property [email] does not exist
get

通過查看上面的代碼,你會發(fā)現(xiàn):將條件和異常移到其他地方,而printUser中僅關(guān)注顯示用戶信息的實(shí)際邏輯會更好。這是我們可以使用代理對象的地方,讓我們更新一下這個(gè)例子。

let user = {
    name: "John",
    surname: "Doe"
};

let proxy = new Proxy(user, {
    get(target, property) {
        let value = target[property];
        if (!value) {
            throw new Error(`The property [${property}] does not exist`);
        }
        return value;
    }
});

let printUser = (property) => {
    console.log(`The user ${property} is ${proxy[property]}`);
};

printUser("name"); // 輸出: "The user name is John"
printUser("email"); // 拋出錯(cuò)誤: The property [email] does not exist

在上面的示例中,我們包裝了 user 對象,并設(shè)置了一個(gè) get 方法。 此方法充當(dāng)攔截器,在返回值之前,會首先對屬性值進(jìn)行檢查,如果不存在,則拋出異常。

輸出與第一種情況相同,但此時(shí) printUser 函數(shù)專注于邏輯,只處理消息。

set

代理可能有用的另一個(gè)例子是屬性值驗(yàn)證。在這種情況下,我們需要使用 set 方法,并在其中進(jìn)行驗(yàn)證。例如,當(dāng)我們需要確保目標(biāo)類型時(shí),這是一個(gè)非常有用的鉤子。我們來看一下實(shí)際使用:

let user = new Proxy({}, {
    set(target, property, value) {
        if (property === "name" && Object.prototype.toString.call(value) !== "[object String]") { // 確保是 string 類型
            throw new Error(`The value for [${property}] must be a string`);
        };
        target[property] = value;
    }
});

user.name = 1; // 拋出錯(cuò)誤: The value for [name] must be a string

這些是相當(dāng)簡單的用例,以下場景,proxy均可以派上用場:

格式化

價(jià)值和類型修正

數(shù)據(jù)綁定

調(diào)試

...

現(xiàn)在是時(shí)候創(chuàng)建一個(gè)更復(fù)雜的用例了。

具有代理的API - 更復(fù)雜的示例

通過使用簡單用例中的知識,我們可以創(chuàng)建一個(gè)API包裝器,以便在我們的應(yīng)用程序中使用。 當(dāng)前只支持 getpost 請求,但它可以很容易地?cái)U(kuò)展。代碼如下所示。

const api = new Proxy({}, {
    get(target, key, context) {
        return target[key] || ["get", "post"].reduce((acc, key) => {
            acc[key] = (config, data) => {

                if (!config && !config.url || config.url === "") throw new Error("Url cannot be empty.");
                let isPost = key === "post";

                if (isPost && !data) throw new Error("Please provide data in JSON format when using POST request.");

                config.headers = isPost ? Object.assign(config.headers || {}, { "content-type": "application/json;chartset=utf8" }) :
                    config.headers;

                return new Promise((resolve, reject) => {
                    let xhr = new XMLHttpRequest();
                    xhr.open(key, config.url);
                    if (config.headers) {
                        Object.keys(config.headers).forEach((header) => {
                            xhr.setRequestHeader(header, config.headers[header]);
                        });
                    }
                    xhr.onload = () => (xhr.status === 200 ? resolve : reject)(xhr);
                    xhr.onerror = () => reject(xhr);
                    xhr.send(isPost ? JSON.stringify(data) : null);
                });
            };
            return acc;
        }, target)[key];
    },
    set() {
        throw new Error("API methods are readonly");
    },
    deleteProperty() {
        throw new Error("API methods cannot be deleted!");
    }
});

讓我們解釋一下簡單實(shí)現(xiàn),setdeleteProperty。 我們添加了一個(gè)保護(hù)級別,并確保每當(dāng)有人意外或無意地嘗試為任何API屬性設(shè)置新值時(shí),都會拋出異常。

每次嘗試刪除屬性時(shí)都會調(diào)用 deleteProperty 方法??梢源_保沒有人可以從我們的代理(即此處的 api)中刪除任何屬性,因?yàn)橥ǔN覀兌疾幌雭G失API方法。

get 在這里很有趣,它做了幾件事。target 是一個(gè)空對象,get 方法將在第一次有人使用 api 時(shí)創(chuàng)建所有方法(如當(dāng)前的 getpost請求),在 reduce 回調(diào)中,我們根據(jù)提供的配置執(zhí)行API規(guī)范所需的驗(yàn)證和檢查。在此示例中,我們不允許空URL和發(fā)布請求而不提供數(shù)據(jù)。這些檢查可以擴(kuò)展和修改,但重要的是我們只能在這一個(gè)地方集中處理。

reduce 僅在第一次API調(diào)用時(shí)完成,之后都會跳過整個(gè) reduce 進(jìn)程,get 只會執(zhí)行默認(rèn)行為并返回屬性值,即API處理程序。每個(gè)處理程序返回一個(gè)Promise對象,負(fù)責(zé)創(chuàng)建請求并調(diào)用服務(wù)。

使用:
api.get({
    url: "my-url"
}).then((xhr) => {
    alert("Success");
}, (xhr) => {
    alert("Fail");
});
delete api.get; //throw new Error("API methods cannot be deleted!"); 
結(jié)論

當(dāng)您需要對數(shù)據(jù)進(jìn)行更多控制時(shí),代理可以派上用場。你可以根據(jù)受控規(guī)則擴(kuò)展或拒絕對原始數(shù)據(jù)的訪問,從而監(jiān)視對象并確保正確行為。

如果您喜歡這篇文章,請關(guān)注我的公眾號??梢栽谙旅娴脑u論部分中表達(dá)您的想法。

謝謝各位小伙伴愿意花費(fèi)寶貴的時(shí)間閱讀本文,如果本文給了您一點(diǎn)幫助或者是啟發(fā),請不要吝嗇你的贊和Star,您的肯定是我前進(jìn)的最大動力。https://github.com/YvetteLau/...

關(guān)注小姐姐的公眾號,加入交流群。

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

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

相關(guān)文章

  • [] 用 Node.js 搭建 API Gateway

    摘要:協(xié)議轉(zhuǎn)換微服務(wù)架構(gòu)允許使用不同的協(xié)議以便于獲得使用不同技術(shù)的優(yōu)勢。過于龐大的在實(shí)現(xiàn)時(shí),應(yīng)當(dāng)避免將非通用邏輯如領(lǐng)域特定數(shù)據(jù)轉(zhuǎn)換放入其中。服務(wù)應(yīng)始終對其數(shù)據(jù)域擁有完全的所有權(quán)。構(gòu)建一個(gè)過于龐大的,從服務(wù)團(tuán)隊(duì)爭奪控制權(quán),這違反了微服務(wù)的理念。 我們團(tuán)隊(duì)的后端服務(wù)中,一開始只有一個(gè)大服務(wù),所有的東西都往里面寫,可以想象下,當(dāng)這個(gè)服務(wù)變得不斷的龐大,將會變得多么難以維護(hù)。后來逐漸把一些數(shù)據(jù)服務(wù)抽...

    鄒強(qiáng) 評論0 收藏0
  • [] 實(shí)例解析 ES6 Proxy 使用場景

    摘要:在下文中,首先我會介紹的使用方式,然后列舉具體實(shí)例解釋的使用場景。如果簡單地區(qū)分和的使用場景,可以概括為的核心作用是控制外界對被代理者內(nèi)部的訪問,的核心作用是增強(qiáng)被裝飾者的功能。 文章永久鏈接地址:http://pinggod.com/2016/%E5%AE%9E%E4%BE%8B%E8%A7%A3%E6%9E%90-ES6-Proxy-%E4%BD%BF%E7%94%A8%E5%9C...

    Rainie 評論0 收藏0
  • 正則表達(dá)式

    摘要:最全正則表達(dá)式總結(jié)驗(yàn)證號手機(jī)號中文郵編身份證地址等是正則表達(dá)式的縮寫,作用是對字符串執(zhí)行模式匹配。學(xué)習(xí)目標(biāo)了解正則表達(dá)式語法在中使用正則表達(dá)式在中使 JS高級技巧 本篇是看的《JS高級程序設(shè)計(jì)》第23章《高級技巧》做的讀書分享。本篇按照書里的思路根據(jù)自己的理解和經(jīng)驗(yàn),進(jìn)行擴(kuò)展延伸,同時(shí)指出書里的一些問題。將會討論安全的類型檢測、惰性載入函數(shù)、凍結(jié)對象、定時(shí)器等話題。1. 安全的類型檢測...

    yibinnn 評論0 收藏0
  • []使用 Proxy 更好的封裝 Storage API

    摘要:譯使用更好的封裝更多前端技術(shù)和知識點(diǎn),搜索訂閱號菌訂閱看到篇文章覺得不錯(cuò),原文。講的是使用來封裝,做一層提供存取數(shù)據(jù)的代理層。這里簡單翻譯一下這篇文章的主要內(nèi)容。請關(guān)注我的訂閱號,不定期推送有關(guān)的技術(shù)文章,只談技術(shù)不談八卦 showImg(https://segmentfault.com/img/remote/1460000019889841?w=640&h=426); [譯]使用 P...

    Java_oldboy 評論0 收藏0

發(fā)表評論

0條評論

Freeman

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<