亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

【重溫基礎(chǔ)】14.元編程

cc17 / 1876人閱讀

摘要:本文是重溫基礎(chǔ)系列文章的第十四篇。元,是指程序本身。有理解不到位,還請指點,具體詳細的介紹,可以查看維基百科元編程。攔截,返回一個布爾值。

本文是 重溫基礎(chǔ) 系列文章的第十四篇。
這是第一個基礎(chǔ)系列的最后一篇,后面會開始復習一些中級的知識了,歡迎持續(xù)關(guān)注呀!
接下來會統(tǒng)一整理到我的【Cute-JavaScript】的JavaScript基礎(chǔ)系列中。

今日感受:獨樂樂不如眾樂樂。

系列目錄:

【復習資料】ES6/ES7/ES8/ES9資料整理(個人整理)

【重溫基礎(chǔ)】1.語法和數(shù)據(jù)類型

【重溫基礎(chǔ)】2.流程控制和錯誤處理

【重溫基礎(chǔ)】3.循環(huán)和迭代

【重溫基礎(chǔ)】4.函數(shù)

【重溫基礎(chǔ)】5.表達式和運算符

【重溫基礎(chǔ)】6.數(shù)字

【重溫基礎(chǔ)】7.時間對象

【重溫基礎(chǔ)】8.字符串

【重溫基礎(chǔ)】9.正則表達式

【重溫基礎(chǔ)】10.數(shù)組

【重溫基礎(chǔ)】11.Map和Set對象

【重溫基礎(chǔ)】12.使用對象

【重溫基礎(chǔ)】13.迭代器和生成器

本章節(jié)復習的是JS中的元編程,涉及的更多的是ES6的新特性。

1. 概述

元編程,其實我是這么理解的:讓代碼自動寫代碼,可以更改源碼底層的功能。
元,是指程序本身。
有理解不到位,還請指點,具體詳細的介紹,可以查看維基百科 元編程 。
從ES6開始,JavaScrip添加了對ProxyReflect對象的支持,允許我們連接并定義基本語言操作的自定義行為(如屬性查找,賦值,枚舉和函數(shù)調(diào)用等),從而實現(xiàn)JavaScrip的元級別編程。

Reflect: 用于替換直接調(diào)用Object的方法,并不是一個函數(shù)對象,也沒有constructor方法,所以不能用new操作符。

Proxy: 用于自定義對象的行為,如修改setget方法,可以說是ES5中Object.defineProperty()方法的ES6升級版。

兩者聯(lián)系: API完全一致,但Reflect一般在Proxy需要處理默認行為的時候使用。

參考資料

名稱 地址
Reflect MDN Reflect
Proxy MDN Proxy
元編程 MDN 元編程

本文主要從Proxy介紹,還會有幾個案例,實際看下怎么使用。

2. Proxy介紹

proxy 用于修改某些操作的默認行為,可以理解為一種攔截外界對目標對象訪問的一種機制,從而對外界的訪問進行過濾和修改,即代理某些操作,也稱“代理器”。

2.1 基礎(chǔ)使用

基本語法:

let p = new Proxy(target, handler);

proxy實例化需要傳入兩個參數(shù),target參數(shù)表示所要攔截的目標對象,handler參數(shù)也是一個對象,用來定制攔截行為。

let p = new Proxy({}, {
    get: function (target, handler){
        return "leo";
    }
})
p.name; // leo
p.age;  // leo
p.abcd; // leo

上述a實例中,在第二個參數(shù)中定義了get方法,來攔截外界訪問,并且get方法接收兩個參數(shù),分別是目標對象所要訪問的屬性,所以不管外部訪問對象中任何屬性都會執(zhí)行get方法返回leo。

注意

只能使用Proxy實例的對象才能使用這些操作。

如果handler沒有設(shè)置攔截,則直接返回原對象。

let target = {};
let handler = {};
let p = new Proxy(target, handler);
p.a = "leo"; 
target.a;  // "leo"

同個攔截器函數(shù),設(shè)置多個攔截操作

let p = new Proxy(function(a, b){
    return a + b;
},{
    get:function(){
        return "get方法";
    },
    apply:function(){
        return "apply方法";
    }
})

這里還有一個簡單的案例:

let handler = {
    get : function (target, name){
        return name in target ? target[name] : 16;
    }
}

let p = new Proxy ({}, handler);
p.a = 1;
console.log(p.a , p.b);
// 1   16

這里因為 p.a = 1 定義了p中的a屬性,值為1,而沒有定義b屬性,所以p.a會得到1,而p.b會得到undefined從而使用name in target ? target[name] : 16;返回的默認值16

Proxy支持的13種攔截操作
13種攔截操作的詳細介紹:打開阮一峰老師的鏈接。

get(target, propKey, receiver)

攔截對象屬性的讀取,比如proxy.foo和proxy["foo"]。

set(target, propKey, value, receiver)

攔截對象屬性的設(shè)置,比如proxy.foo = v或proxy["foo"] = v,返回一個布爾值。

has(target, propKey)

攔截propKey in proxy的操作,返回一個布爾值。

deleteProperty(target, propKey)

攔截delete proxy[propKey]的操作,返回一個布爾值。

ownKeys(target)

攔截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循環(huán),返回一個數(shù)組。該方法返回目標對象所有自身的屬性的屬性名,而Object.keys()的返回結(jié)果僅包括目標對象自身的可遍歷屬性。

getOwnPropertyDescriptor(target, propKey)

攔截Object.getOwnPropertyDescriptor(proxy, propKey),返回屬性的描述對象。

defineProperty(target, propKey, propDesc)

攔截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一個布爾值。

preventExtensions(target)

攔截Object.preventExtensions(proxy),返回一個布爾值。

getPrototypeOf(target)

攔截Object.getPrototypeOf(proxy),返回一個對象。

isExtensible(target)

攔截Object.isExtensible(proxy),返回一個布爾值。

setPrototypeOf(target, proto)

攔截Object.setPrototypeOf(proxy, proto),返回一個布爾值。如果目標對象是函數(shù),那么還有兩種額外操作可以攔截。

apply(target, object, args)

攔截 Proxy 實例作為函數(shù)調(diào)用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。

construct(target, args)

攔截 Proxy 實例作為構(gòu)造函數(shù)調(diào)用的操作,比如new proxy(...args)。

2.2 取消Proxy實例

使用Proxy.revocable方法取消Proxy實例。

let a = {};
let b = {
    get: function(target, name) {
        return "[[" + name + "]]";
    }
};
let revoke = Proxy.revocable(a, b);
let proxy = revoke.proxy;

proxy.age;           // "[[age]]"
revoke.revoke();
proxy.age;           // Uncaught TypeError: Cannot perform "get" on a proxy that has been revoked

proxy.age = 10;      // Uncaught TypeError: Cannot perform "set" on a proxy that has been revoked
delete proxy.age;    // Uncaught TypeError: Cannot perform "deleteProperty" on a proxy that has been revoked
typeof proxy;        // "object"
2.3 實現(xiàn) Web服務(wù)的客戶端
const service = createWebService("http://le.com/data");
service.employees().than(json =>{
    const employees = JSON.parse(json);
})

function createWebService(url){
    return new Proxy({}, {
        get(target, propKey, receiver{
            return () => httpGet(url+"/"+propKey);
        })
    })
}
3. Proxy實踐 3.1 數(shù)據(jù)攔截驗證

通過Proxy代理對象的setget方法來進行攔截數(shù)據(jù),像Vue就是用數(shù)據(jù)攔截來實現(xiàn)數(shù)據(jù)綁定。

let handler = {
    // 攔截并處理get方法
    // 可以理解為設(shè)置get方法返回的默認值
    get : function (target, key){
        return key in target ? target[key] : 30;
    },
    
    // 攔截并處理set方法
    // 可以理解為設(shè)置set方法的默認行為
    set : function (target, key, value){
        if(key === "age"){
            if (!Number.isInteger(value)){
                throw new TypeError("age不是一個整數(shù)!");
            }
            if (value > 200){
                throw new TypeError("age不能大于200!");
            }
        }
        // 保存默認行為
        target[key] = value;
    }
}

let p = new Proxy({}, handler);
p.a = 10;         // p.a   => 10
p.b = undefined;  // p.b   => undefined
p.c;              // 默認值 30
p.age = 100;      // p.age => 100
p.age = 300;      // Uncaught TypeError: age不能大于200!
p.age = "leo";    // Uncaught TypeError: age不是一個整數(shù)!
3.2 函數(shù)節(jié)流

通過攔截handler.apply()方法的調(diào)用,實現(xiàn)函數(shù)只能在1秒之后才能再次被調(diào)用,經(jīng)??梢杂迷诜乐怪貜褪录挠|發(fā)。

let p = (fun, time) => {
    // 獲取最后點擊時間
    let last = Date.now() - time;
    return new Proxy (fun, {
        apply(target, context, args){
            if(Date.now() - last >= time){
                fun.bind(target)(args);
                // 重復設(shè)置當前時間
                last = Date.now();
            }
        }
    })
}

let p1 = () => {
    console.log("點擊觸發(fā)");
}
let time = 1000; // 設(shè)置時間
let proxyObj = p(p1, time);
// 監(jiān)聽滾動事件
document.addEventListener("scroll", proxyObj);
3.3 實現(xiàn)單例模式

通過攔截construct方法,讓不同實例指向相同的constructer,實現(xiàn)單例模式。

let p = function(fun){
    let instance;
    let handler = {
        // 攔截construct方法
        construct: function(targer, args){
            if(!instance){
                instance = new fun();
            }
            return instance;
        }
    }
    return new Proxy(fun, handler);
}

// 創(chuàng)建一個construct案例
function Cons (){
    this.value = 0;
}

// 創(chuàng)建實例
let p1 = new Cons();
let p2 = new Cons();

// 操作
p1.value = 100; 
// p1.value => 100 , p2.value => 0
// 因為不是相同實例

// 通過Proxy實現(xiàn)單例
let singleton = p(Cons);
let p3 = new singleton();
let p4 = new singleton();
p3.value = 130; 
// p1.value => 130 , p2.value => 130
// 現(xiàn)在是相同實例
參考資料

1. MDN 元編程
2. ES6中的元編程-Proxy & Reflect
本部分內(nèi)容到這結(jié)束

Author 王平安
E-mail pingan8787@qq.com
博 客 www.pingan8787.com
微 信 pingan8787
每日文章推薦 https://github.com/pingan8787...
JS小冊 js.pingan8787.com

歡迎關(guān)注微信公眾號【前端自習課】每天早晨,與您一起學習一篇優(yōu)秀的前端技術(shù)博文 .

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

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

相關(guān)文章

  • 重溫基礎(chǔ)】15.JS對象介紹

    摘要:構(gòu)造函數(shù)通常首字母大寫,用于區(qū)分普通函數(shù)。這種關(guān)系常被稱為原型鏈,它解釋了為何一個對象會擁有定義在其他對象中的屬性和方法。中所有的對象,都有一個屬性,指向?qū)嵗龑ο蟮臉?gòu)造函數(shù)原型由于是個非標準屬性,因此只有和兩個瀏覽器支持,標準方法是。 從這篇文章開始,復習 MDN 中級教程 的內(nèi)容了,在初級教程中,我和大家分享了一些比較簡單基礎(chǔ)的知識點,并放在我的 【Cute-JavaScript】系...

    booster 評論0 收藏0
  • 重溫基礎(chǔ)】18.相等性判斷

    摘要:通常在轉(zhuǎn)換不同數(shù)據(jù)類型時,相等和不相等會遵循以下規(guī)則若有一個操作數(shù)是布爾值,則比較前會將布爾值轉(zhuǎn)換為數(shù)值轉(zhuǎn)為,轉(zhuǎn)為。 本文是 重溫基礎(chǔ) 系列文章的第十八篇。今日感受:優(yōu)化自己的代碼,也是很愉快的事情。 系列目錄: 【復習資料】ES6/ES7/ES8/ES9資料整理(個人整理) 【重溫基礎(chǔ)】1-14篇 【重溫基礎(chǔ)】15.JS對象介紹 【重溫基礎(chǔ)】16.JSON對象介紹 【重溫基礎(chǔ)...

    趙春朋 評論0 收藏0
  • 重溫基礎(chǔ)】16.JSON對象介紹

    摘要:系列目錄復習資料資料整理個人整理重溫基礎(chǔ)篇重溫基礎(chǔ)對象介紹本章節(jié)復習的是中的關(guān)于對象相關(guān)知識。概念概念有三點全稱對象表示法。對象沒有分號,而對象有。序列化對象時,所有函數(shù)及原型成員都會被忽略,不體現(xiàn)在結(jié)果上。 本文是 重溫基礎(chǔ) 系列文章的第十六篇。今日感受:靜。 系列目錄: 【復習資料】ES6/ES7/ES8/ES9資料整理(個人整理) 【重溫基礎(chǔ)】1-14篇 【重溫基礎(chǔ)】15...

    0x584a 評論0 收藏0
  • 重溫基礎(chǔ)】22.內(nèi)存管理

    摘要:內(nèi)存泄露內(nèi)存泄露概念在計算機科學中,內(nèi)存泄漏指由于疏忽或錯誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存。判斷內(nèi)存泄漏,以字段為準。 本文是 重溫基礎(chǔ) 系列文章的第二十二篇。 今日感受:優(yōu)化學習方法。 系列目錄: 【復習資料】ES6/ES7/ES8/ES9資料整理(個人整理) 【重溫基礎(chǔ)】1-14篇 【重溫基礎(chǔ)】15.JS對象介紹 【重溫基礎(chǔ)】16.JSON對象介紹 【重溫基礎(chǔ)】1...

    Pandaaa 評論0 收藏0
  • 重溫基礎(chǔ)】19.閉包

    摘要:系列目錄復習資料資料整理個人整理重溫基礎(chǔ)篇重溫基礎(chǔ)對象介紹重溫基礎(chǔ)對象介紹重溫基礎(chǔ)介紹重溫基礎(chǔ)相等性判斷本章節(jié)復習的是中的關(guān)于閉包,這個小哥哥呀,看看。這里隨著閉包函數(shù)的結(jié)束,執(zhí)行環(huán)境銷毀,變量回收。 本文是 重溫基礎(chǔ) 系列文章的第十九篇。今日感受:將混亂的事情找出之間的聯(lián)系,也是種能力。 系列目錄: 【復習資料】ES6/ES7/ES8/ES9資料整理(個人整理) 【重溫基礎(chǔ)】...

    nanfeiyan 評論0 收藏0

發(fā)表評論

0條評論

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