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

資訊專欄INFORMATION COLUMN

ES6之Proxy學(xué)習(xí)

UnixAgain / 3858人閱讀

摘要:在中構(gòu)造器的典型特點(diǎn)就是首字母大寫,我們通過原對(duì)象代理列表格式去創(chuàng)建對(duì)象創(chuàng)建的這個(gè)對(duì)象我們稱之為代理對(duì)象。就是原對(duì)象是當(dāng)前的屬性名是代理對(duì)象。理解為明星的經(jīng)理人消極怠工原封不動(dòng)地轉(zhuǎn)告外界的信息給明星本身。但是要注意與是兩個(gè)不同的對(duì)象。

ES6之Proxy

proxy的中文有代理的意思。在其他的程序設(shè)計(jì)語言中這個(gè)單詞也具有類似的含義。

它是什么

Proxy是一個(gè)構(gòu)造器。在js中構(gòu)造器的典型特點(diǎn)就是首字母大寫,我們通過new Proxy(原對(duì)象,{代理列表})格式去創(chuàng)建對(duì)象,創(chuàng)建的這個(gè)對(duì)象我們稱之為代理對(duì)象。
即:

代理對(duì)象 = new Proxy(原對(duì)象,{代理列表})

之所以要額外產(chǎn)生這么一個(gè)代理對(duì)象,好處在于可以保持原對(duì)象不變,在代理對(duì)象中添加新的功能,或者是改造某些功能。而這個(gè)原對(duì)象則可以在適當(dāng)?shù)臅r(shí)機(jī)回滾回去??梢耘c設(shè)計(jì)模式中的代理模式對(duì)比理解。

使用格式
var obj;
var proxyObj = new Proxy(obj, {
    對(duì)obj的操作1: 函數(shù)1,
    對(duì)obj的操作2: 函數(shù)2,
    ...
    
})
入門示例 Proxy的基本示范
var obj = {name:"fan",age:34}
console.info(obj.name)

var proxyObj = new Proxy(obj,{
    get:function(target,key,receiver){console.info(target,key,receiver); return "no"}
})

console.info(proxyObj.name) 
console.info(proxyObj.abc)

解釋如下:

proxxy對(duì)象是在obj對(duì)象的基礎(chǔ)之上創(chuàng)建的一個(gè)新對(duì)象。

proxyObj.name是要去獲取proxy對(duì)象的name屬性。.操作符會(huì)自動(dòng)去調(diào)用get()方法。這一點(diǎn)非常重要,在js中,對(duì)象是屬性的無序集合。對(duì)象只有屬性,其他什么都沒有. 而我們經(jīng)常說的調(diào)用對(duì)象的某個(gè)方法:例如數(shù)組對(duì)象arr的sort方法:arr.sort(),這里的sort也是arr對(duì)象的屬性(更嚴(yán)謹(jǐn)一點(diǎn),sort是arr.__proto__這個(gè)對(duì)象的屬性),與length屬性相比,sort屬性的屬性值是一個(gè)函數(shù),所以在它的后面加()來執(zhí)行這個(gè)函數(shù),而length屬性的值是一個(gè)數(shù)值,所以不需要加()就可以直接使用。再次強(qiáng)調(diào)一下:對(duì)象的.操作,會(huì)自動(dòng)去調(diào)用get。當(dāng)然,我們平時(shí)使用.操作時(shí),是沒有感知到這一點(diǎn)的。

在new Proxy的第二個(gè)參數(shù)中,明確設(shè)置了get的方法:當(dāng)訪問proxyObj的任意屬性時(shí),輸出target,key,receiver的值,并統(tǒng)一返回no。所以proxyObj.name和proxyObj.abc都會(huì)得到no。

寫到這里你會(huì)覺得原對(duì)象與代理對(duì)象之間有什么關(guān)系呢?為什么叫代理呢?

理解代理的作用

代理對(duì)象可以理解為明星的經(jīng)紀(jì)人。

外界 <----> 原對(duì)象;
外界 <----> 代理對(duì)象 <------> 原對(duì)象; 

還以上面的代碼為例,改進(jìn)一下需求:如果有人問obj的名字,就直接告訴對(duì)方; 如果有人問obj的年齡,就返回小5歲的年齡。

var obj = {name:"fan",age:34}
console.info(obj.age)           // 34
var proxyObj = new Proxy(obj,{
    get:function(target,key,receiver){
        console.info(target === obj);           //true
        console.info(receiver === proxyObj);    //true
        if("age" === key){
            return target[key] - 5;
        }
        else{
            return target[key]
        }
    }
})

console.info(proxyObj.age)  // 34- 5 = 29

解釋如下:

get函數(shù)中的三個(gè)參數(shù):target,key,receiver。 target就是原對(duì)象j,keys是當(dāng)前的屬性名;receiver是代理對(duì)象。你可以在get方法中做任意的自定義的處理。

代理對(duì)象與原對(duì)象的關(guān)系
var arr = [2,1]
var proxyArr = new Proxy(arr,{} )
proxyArr.push(3);
console.info(arr) // [2,1,3]
console.info(arr === proxyArr) // false
arr.sort();
console.info(proxyArr[0]) // 1

以上代碼中,這個(gè)代理對(duì)象并沒有做任何的特殊操作。理解為明星的經(jīng)理人消極怠工:原封不動(dòng)地轉(zhuǎn)告外界的信息給明星本身。所以在proxyArr上做到操作會(huì)直接影響到arr上。

同理,在arr上的操作,也會(huì)影響proxyArr。
但是要注意:proxyArr與arr是兩個(gè)不同的對(duì)象:arr !== proxyArr。

你可能會(huì)想一想:為什么proxyArr能夠直接使用push這個(gè)方法呢?原因是:

proxyArr.__proto__ === arr.__proto__ === Array.prototype

前一個(gè)等式成立的原因是由new Proxy的基因決定的:原對(duì)象被代理了嘛。

代理列表

在new Proxy的第二個(gè)參數(shù)中,可以設(shè)置的代理屬性如下:

var proxyObj = new Proxy(obj, {

    get: function(tagert,key,receiver){},
    set: function(tagert,key,receiver){},
    has: function(tagert,key){},
    deleteProperty: function(tagert,key){},
    ownKeys: function(tagert){},
    getOwnPropertyDescriptor: function(tagert,key){},
    defineProperty: function(tagert,key,desc){},
    preventExtensions: function(tagert){},
    getPrototypeOf: function(tagert){},
    isExtensible: function(tagert){},
    setPrototypeof: function(tagert,proto){},
    apply: function(tagert,obj,args){},
    construct: function(tagert,args){},
    
})
get() 代理的應(yīng)用 允許數(shù)組下標(biāo)是負(fù)值

在js中,數(shù)組的有效下表是從0開始的。

var arr = [1,2,3];
console.info(arr[0])  // 1
console.info(arr[-1]) // undefined
console.info(arr[100]) // undefined

值得注意的是,下表越界或者是負(fù)值的情況下,得到的結(jié)果是undefined,而不是報(bào)錯(cuò)。

下面我們希望數(shù)組可以取負(fù)值下表,規(guī)則如下:

-n表示倒數(shù)第n個(gè)元素。例如:-1表示倒數(shù)第一個(gè)元素。

使用Proxy解決如下:

var arr = [1,2,3];

var proxyArr = new Proxy(arr,{
    get: (target,prop)=>{
        let index = Number(prop);
        if(index < 0){
            prop = target.length + index;
        }
        return target[prop];
        
    }
})
console.info(arr[-1]);      // undefined
console.info(proxyArr[-1]); // 3

注意:

Number()可以把傳入的值轉(zhuǎn)成數(shù)值型。非數(shù)值 --> NaN;

如果是proxyArr.push(3),由于此時(shí)的prop是"push",所以不會(huì)進(jìn)入if分支。

如果是proxyArr[-1],此時(shí)的prop是"-1",所以會(huì)進(jìn)入到if分支:把prop從-1改成 2 ,從而實(shí)現(xiàn)了被代理的效果。

此時(shí),完全可以把proxyArr當(dāng)作一個(gè)數(shù)組來使用,sort,push等方法均可以調(diào)用。Array.isArray(proxyArr) === true

當(dāng)然,你也可以進(jìn)一步封裝成工廠函數(shù)。

function myArr(...args){
    var arr = new Array(...args);

    var proxyArr = new Proxy(arr,{
        get: (target,key)=>{
            let index = Number(key);
            if(index < 0){
                key = target.length + index;
            }
            return target[key];

        }
    })
    return proxyArr;
}
var obj = myArr([1,2,3]);
console.info(obj[0],obj[-1])
鏈?zhǔn)竭\(yùn)算
var double = n => n*2;
var pow2 = n => n*n;
var half = n => n/ 2;
var add1 = n => n+1;

function pipe (num){
    let funs = []
    let obj = new Proxy({},{
        get:function(target,prop){
            if(prop === "end"){
                return funs.reduce((val,currentfn)=>currentfn(val),num);
            }else{
                funs.push(window[prop])
            }
            return obj;
        }
    })

    return obj;
};

console.info( pipe(4).double.pow2.end);
console.info( pipe(4).pow.double.pow2.add1.end);

說明:

reduce

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

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

相關(guān)文章

  • 正則表達(dá)式

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

    yibinnn 評(píng)論0 收藏0
  • 前端進(jìn)階資源整理

    摘要:前端進(jìn)階進(jìn)階構(gòu)建項(xiàng)目一配置最佳實(shí)踐狀態(tài)管理之痛點(diǎn)分析與改良開發(fā)中所謂狀態(tài)淺析從時(shí)間旅行的烏托邦,看狀態(tài)管理的設(shè)計(jì)誤區(qū)使用更好地處理數(shù)據(jù)愛彼迎房源詳情頁中的性能優(yōu)化從零開始,在中構(gòu)建時(shí)間旅行式調(diào)試用輕松管理復(fù)雜狀態(tài)如何把業(yè)務(wù)邏輯這個(gè)故事講好和 前端進(jìn)階 webpack webpack進(jìn)階構(gòu)建項(xiàng)目(一) Webpack 4 配置最佳實(shí)踐 react Redux狀態(tài)管理之痛點(diǎn)、分析與...

    BlackMass 評(píng)論0 收藏0
  • ES6 系列 defineProperty 與 proxy

    摘要:存取描述符同時(shí)具有以下可選鍵值一個(gè)給屬性提供的方法,如果沒有則為。該方法返回值被用作屬性值。值得注意的是屬性描述符必須是數(shù)據(jù)描述符或者存取描述符兩種形式之一,不能同時(shí)是兩者??梢院雎苑椒ǖ姆祷刂怠? 前言 我們或多或少都聽過數(shù)據(jù)綁定這個(gè)詞,數(shù)據(jù)綁定的關(guān)鍵在于監(jiān)聽數(shù)據(jù)的變化,可是對(duì)于這樣一個(gè)對(duì)象:var obj = {value: 1},我們?cè)撛趺粗?obj 發(fā)生了改變呢? define...

    sean 評(píng)論0 收藏0
  • ES6Reflect

    摘要:查找并返回對(duì)象的屬性例例屬性部署了讀取函數(shù)返回的是的參數(shù)對(duì)象注意如果的第一個(gè)參數(shù)不是對(duì)象,則會(huì)報(bào)錯(cuò)。它返回一個(gè)布爾值,表示是否操作成功用于返回對(duì)象的所有屬性使用和實(shí)現(xiàn)觀察者模式請(qǐng)參考觀察者模式 1、什么是Reflect?為操作對(duì)象而提供的新API 2、為什么要設(shè)計(jì)Reflect?(1)將Object對(duì)象的屬于語言內(nèi)部的方法放到Reflect對(duì)象上,即從Reflect對(duì)象上拿Object...

    BingqiChen 評(píng)論0 收藏0
  • ES6Proxy & Reflection API

    摘要:的出現(xiàn),使用內(nèi)建對(duì)象的繼承得以實(shí)現(xiàn)。屬性不存在拋出異常是取值操作,而就是賦值操作,可以對(duì)屬性值進(jìn)行驗(yàn)證。屬性必須為數(shù)字拋出異常接受兩個(gè)參數(shù)被讀取屬性的原對(duì)象,即代理的目標(biāo)。這個(gè)可以攔截內(nèi)部方法,通過返回?cái)?shù)組的值可以覆寫其行為。 Proxy & Reflect extends的出現(xiàn),使用內(nèi)建對(duì)象的繼承得以實(shí)現(xiàn)。Proxy可以攔截JS引擎內(nèi)部目標(biāo)的底層對(duì)象操作,這些底層操作被攔截后會(huì)觸發(fā)響...

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

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

0條評(píng)論

UnixAgain

|高級(jí)講師

TA的文章

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