Proxy代理

代理
  • ES5 代理方式
//es5 代理方式
let obj={}
let newVal=''
Object.defineProperty(obj,'name',{      
    get(){
        console.log('get');
        return newVal
    },
    set(val){
        console.log('set');
        newVal=val
    }
})
obj.name='es' //set
console.log(obj.name);  //get es
  • ES6 Proxy
let obj={}
let p=new Proxy(obj,{})
p.name='hi'
console.log(obj.name); //hi
for(let key in obj){console.log(key);} //name
  • ES6 Reflect
//es6中使用Reflect.defineProperty 將Object屬于語言內(nèi)部的方法放到Reflect上  更加規(guī)范
let obj={}
Object.defineProperty(obj,'name',{})
Reflect.defineProperty(obj,'name',{})

//返回boolean  修改某些Object方法的返回結(jié)果魔吐,讓其變得更合理
// if(Reflect.defineProperty()){}else{}

//讓Object操作變成函數(shù)行為
console.log('assign' in Object)  //true
console.log(Reflect.has(Object,'assign')) //true

//Reflect對(duì)象的方法于Proxy對(duì)象的方法一一對(duì)應(yīng)
常用攔截方法
  • get
    攔截對(duì)象屬性的讀取憾筏,比如proxy.foo和proxy['foo']
// 判斷數(shù)組的下標(biāo)是否有值,有值返回值蔚舀,沒值返回下標(biāo)
let arr=[7,8,9]
arr=new Proxy(arr,{
    get(target,prop){  
        // console.log(target,prop);  //arr[1]->target [7,8,9],prop '1'
        return prop in target ? target[prop] : 'error'
    }
})
console.log(arr[1]); //8
console.log(arr[3]); //error

//字典翻譯,輸入hello返回你好阐滩,輸入字典沒有的返回原值
let dict={
    'hello':'你好',
    'world':'世界'
}
dict=new Proxy(dict,{
    get(target,prop){  
        return prop in target ? target[prop] : prop
    }
})
console.log(dict['world']); //世界
console.log(dict['good']); //good
  • set
    攔截對(duì)象屬性的設(shè)置虑省,返回一個(gè)布爾值斗搞,比如proxy.foo=v或proxy['foo']=v
//限制arr內(nèi)限制只能設(shè)置number值,其他值返回錯(cuò)誤
let arr=[]
arr=new Proxy(arr,{
    set(target,prop,val){
        if(typeof val==='number'){
            target[prop]=val
            return true
        }else{
            return false
        }
    }
})
arr.push(1) 
console.log(arr[0]); //1
arr.push(2) 
console.log(arr[1],arr.length); //2 2
  • has
    攔截propKey in proxy的操作慷妙,返回一個(gè)布爾值
//判斷是否在范圍內(nèi)僻焚,返回布爾型值
let range={
    start:1,
    end:5
}
range=new Proxy(range,{
    has(target,prop){
        return prop>=target.start && prop<=target.end
    }
})
console.log(2 in range); //true
console.log(9 in range); //false
  • ownKeys
    攔截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)膝擂、Object.keys(proxy)虑啤、for...in循環(huán),返回一個(gè)數(shù)組
//使用Symbol例子
let obj={
    name:'daji',
    [Symbol('es')]:'es'
}
console.log(Object.getOwnPropertyNames(obj)) //['name']
console.log(Object.getOwnPropertySymbols(obj))  //[Symbol(es)]
console.log(Object.keys(obj)) //['name']
for(let key in obj){
    console.log(key); //name
}

//不想被遍歷出私有屬性以下劃線開頭的 _parssword 使用ownKeys
let userinfo={
    name:'daji',
    age:18,
    _password:'***'
}
userinfo=new Proxy(userinfo,{
    ownKeys(target){
        return Object.keys(target).filter(key=>!key.startsWith('_'))
    }
})
for(let key in userinfo){
    console.log(key); //name age
}
console.log(Object.keys(userinfo)); //['name','age']
  • deleteProperty
    攔截delete proxy[proKey] 返回一個(gè)布爾值
//阻止對(duì)私有屬性的任何訪問 _password
let user={
    name:'daji',
    age:18,
    _password:'***'
}
user=new Proxy(user,{
    get(target,prop){           //不允許獲取
        if(prop.startsWith('_')){
            throw new Error('不可訪問')
        }else{
            return target[prop]
            //return Reflect.get(target,prop)
        }
    },
    set(target,prop,val){          //不允許設(shè)置 返回布爾型值
        if(prop.startsWith('_')){
            throw new Error('不可訪問')
        }else{
            target[prop]=val    //Reflect.set(target,prop,val)
            return true
        }
    },    
    deleteProperty(target,prop){           //不允許刪除 返回布爾型值
        if(prop.startsWith('_')){
            throw new Error('不可刪除')
        }else{
            delete target[prop]   //Reflect.delete(target,prop)
            return true
        }
    },
    ownKeys(target){           //不允許遍歷
        return Object.keys(target).filter(key=>!key.startsWith('_'))   
       //return Reflect.ownKeys(target).filter(key=>!key.startsWith('_'))  
    }
})

//get 測試
// console.log(user.age); //18
// console.log(user._password); //報(bào)錯(cuò)Error: 不可訪問

//set 測試
user.age=100
console.log(user.age); //100
//捕獲異常寫法
try{
    user._password='xxx'
}catch(e){
    console.log(e.message);  //不可訪問
}

//刪除 測試
try{
   delete user._password
}catch(e){
    console.log(e.message);  //不可刪除
}

//遍歷 測試
for(let key in user){
    console.log(key);  //name age
}
  • apply
    攔截函數(shù)調(diào)用架馋,apply和call操作
let sum=(...args)=>{
    let num=0
    args.forEach(item=>{
        num+=item
    })
    return num
}
sum=new Proxy(sum,{
    apply(target,ctx,args){   //ctx上下文
        return target(...args)*2    //return Reflect.apply(target,target,[...args])*2
    }
})
console.log(sum(1,2));  //6
console.log(sum.call(null,1,2,3));  //null不改變指向 12
console.log(sum.apply(null,[1,2,3]));  //12
  • construct
    construct 攔截new 返回一個(gè)對(duì)象
let User=class{
    constructor(name){
        this.name=name
    }
}
User=new Proxy(User,{
    construct(target,args,newTarget){  //args構(gòu)造函數(shù)的參數(shù)
        return new target(...args)
    }
})
console.log(new User('hi'));  // User {name: "hi"}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末狞山,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子叉寂,更是在濱河造成了極大的恐慌萍启,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屏鳍,死亡現(xiàn)場離奇詭異勘纯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)钓瞭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門驳遵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人山涡,你說我怎么就攤上這事堤结。” “怎么了鸭丛?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵竞穷,是天一觀的道長。 經(jīng)常有香客問我鳞溉,道長瘾带,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任穿挨,我火速辦了婚禮月弛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘科盛。我一直安慰自己帽衙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布贞绵。 她就那樣靜靜地躺著厉萝,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谴垫,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天章母,我揣著相機(jī)與錄音,去河邊找鬼翩剪。 笑死乳怎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的前弯。 我是一名探鬼主播蚪缀,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼恕出!你這毒婦竟也來了询枚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤浙巫,失蹤者是張志新(化名)和其女友劉穎金蜀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體的畴,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡渊抄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了苗傅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抒线。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖渣慕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抱慌,我是刑警寧澤逊桦,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站抑进,受9級(jí)特大地震影響强经,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜寺渗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一匿情、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧信殊,春花似錦炬称、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春跷车,著一層夾襖步出監(jiān)牢的瞬間棘利,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國打工朽缴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留善玫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓密强,卻偏偏與公主長得像蝌焚,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子誓斥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 什么是Proxy代理 ES6 讓開發(fā)者能進(jìn)一步接近 JS 引擎的能力只洒,這些能力原先只存在于內(nèi)置對(duì)象上。語言通過代理...
    27億光年中的小小塵埃閱讀 486評(píng)論 0 1
  • 一劳坑、概述 Proxy 用于修改某些操作的默認(rèn)行為毕谴,等同于在語言層面做出修改,所以屬于一種“元編程”(meta pr...
    了凡和纖風(fēng)閱讀 265評(píng)論 0 1
  • 來自深入理解ES6第十二章距芬,由于最近業(yè)務(wù)中經(jīng)常用到涝开,記錄一下 這里內(nèi)容都太學(xué)術(shù)了,有一篇簡單介紹Proxy作用的文...
    NowhereToRun閱讀 1,010評(píng)論 0 1
  • 前面的話 ??ES5和ES6致力于為開發(fā)者提供JS已有卻不可調(diào)用的功能框仔。例如在ES5出現(xiàn)以前舀武,JS環(huán)境中的對(duì)象包含...
    CodeMT閱讀 1,451評(píng)論 0 2
  • ES:給開發(fā)者提供了一個(gè)新特性:Proxy,就是代理的意思离斩。也就是我們這一節(jié)要介紹的知識(shí)點(diǎn)银舱。以前,ATM還沒有那么...
    幸宇閱讀 463評(píng)論 0 0