ES6-11 總結(jié)六 (代理Proxy 反射Reflect)

1 Proxy 代理

1.1 Es5 代理

let obj = {};
let newVal = '';
Object.defineProperty(obj, 'name', {
    get(){
        return newVal;
    },
    set(v){
        newVal = v;
        // this.name = v  如果這樣寫,,會(huì)無限觸發(fā)set
    }
});
obj.name = 123;
console.log(obj.name);  // 123

1.2 Es6 代理

1.2.1 基礎(chǔ)用法
let obj = {};
let p = new Proxy(obj,{});
obj.name = 123
console.log(p.name); // 123

1.2.2 get 方法 監(jiān)聽屬性讀取
舉例說明

let dict = {
    'xx' : 'xx'
};
dict = new Proxy(dict, {
    get(target, p, receiver){
        // target : Object xx: "xx"   
        // p : 傳進(jìn)來的xx    
        // receiver : Proxy
        
        return '自定義條件  賽選以后返回的值';
    }
});
console.log(dict['xx']);  // 自定義條件  賽選以后返回的值
1.2.3 set方法 監(jiān)聽設(shè)置屬性
舉例 : 只能設(shè)置number類型
必須返回一個(gè)boolean類型
let dict = {
    'xx' : 'xx'
};
dict = new Proxy(dict, {
    set(target, p, value, receiver){
        console.log(target, p, value, receiver);
          return  true
        打印結(jié)果 : {xx: "xx"}  "xx"  "123"   Proxy {xx: "xx"}
    }
});
dict['xx'] = '123';
1.2.4 has方法 判斷key是否在對(duì)象里面
let range = {
    start : 1,
    end : 10
};
// console.log(2 in range);  // false,此時(shí)沒被代理

range = new Proxy(range, {
    has(target, p){
        console.log(target, p);  // {start: 1, end: 10} "2"
        return p >= target.start && p <= target.end;
    }
});
console.log(2 in range); //true
console.log(11 in range); //false
1.2.5 ownkeys 方法 監(jiān)聽循環(huán)遍歷
let obj = {
    name : 'xxx',
    [Symbol('es')] : 'es6'
};
Object.getOwnPropertyNames(obj); //  ["name"]   非Symbol類型
Object.keys(obj); //  ["name"]   非Symbol類型
for(let key in obj){console.log(key);}   // name 
Object.getOwnPropertySymbols(obj); // [Symbol(es)]   Symbol

舉例,,,設(shè)置以 _ 開頭的字段,,為私有屬性
let userName = {
    name : 'xx',
    age : 18,
    _passWord : '***'
};
userName = new Proxy(userName, {
    ownKeys(target){
        return Object.keys(target)
                     .filter(key => {
                         // console.log(key); // name  age  _passWord
                         return !key.startsWith('_');
                     });
    }
});
for(let userNameKey in userName){
    console.log(userNameKey);  // name  age
}
1.2.6 deleteProperty 方法 攔截delete方法
必須返回一個(gè)boolean類型
let userName = {
    name : 'xx',
    age : 18,
    _passWord : '***'
};
userName = new Proxy(userName, {
    deleteProperty(target, p){
        // 是否以下劃線開頭
        if(p.startsWith("_")){
            delete target[p]
        }
    }
});
delete userName["age"]
console.log(userName);  // {name: "xx", age: 18, _passWord: "***"}

delete userName["_passWord"]
console.log(userName);  // {name: "xx", age: 18}   
1.2.7 apply方法 攔截函數(shù)的調(diào)用,,以及call,apply等
一個(gè)求和函數(shù)
let GetSum = (...args) => {
    let num = 0;
    args.forEach(item => {
        num += item;
    });
    return num;
};

GetSum = new Proxy(GetSum, {
    apply(target, thisArg, argArray){
        console.log(target);   // GetSum函數(shù)
        console.log(thisArg);  // GetSum(1, 2): undefined
        console.log(argArray); // [1, 2] GetSum的參數(shù)
        return target(...argArray) * 2;
    }
});
GetSum(1, 2);  // 6   代理以后*2
GetSum.call(null, 1, 2);  // 6   代理以后*2    第一個(gè)參數(shù)是指向的對(duì)象
GetSum.apply(null, [1, 2, 3]);  // 12   第一個(gè)參數(shù)是指向的對(duì)象   第二個(gè)是數(shù)組
1.2.8 construct方法 攔截new
let newClass = class{
    constructor(name){
        this.name = name;
    }
};
newClass = new Proxy(newClass, {
    construct(target, argArray, newTarget){
        console.log(target);  // newClass這個(gè)的class
        console.log(argArray); // ["xx"] 參數(shù)的數(shù)組
        console.log(newTarget); // {length: 1, prototype: {…}, name: "newClass"}
        return new target('我改變了參數(shù)');
    }
});
let a = new newClass('xx');
console.log(a);  // newClass {name: "我改變了參數(shù)"}
1.2.9 proxy總結(jié)
image.png

image.png

2 Reflect反射

2.1 將Object的語法轉(zhuǎn)移到Reflect上面
設(shè)計(jì)之初,很多方法都掛載在Object上面,,es6轉(zhuǎn)移一部分到Reflect
Object.defineProperty  => Reflect.defineProperty
2.2 修改某些Object方法的返回值
Object.defineProperty (沒有返回值) 去定義屬性   如果有些屬性無法被定義 :
如果不能被定義拋出異常
try{
    Object.defineProperty()
}catch(e){
}

Reflect.defineProperty有返回值(布爾類型),,,如果不能定義返回false
2.3 讓Object操作變成函數(shù)行為
"assign" in Object  // true  Object下面 是否有assign這個(gè)方法
Reflect.has(Object,"assign")  // true
2.3 Reflect對(duì)象的方法和Proxy對(duì)象的方法一一對(duì)應(yīng)
get set delete ownKeys
let user = {
    name : 'xx',
    _passWord : '123456'
};
user = new Proxy(user, {
    get(target, p, receiver){
        if(p.startsWith('_')){
            throw new Error('不可訪問');
        } else{
            // return target[p]  和下面的這種寫法一樣
            return Reflect.get(target, p);
        }
    },
    set(target, p, value, receiver){
        // target[p] = value
        if(p.startsWith('_')){
            throw new Error('不可訪問');
        } else{
            Reflect.set(target, p, value);
            return true;
        }
    },
    deleteProperty(target, p){
        if(p.startsWith('_')){
            throw new Error('不可訪問');
        } else{
            // delete target[p]
            Reflect.defineProperty(target, p);
            return true;
        }
    },
    ownKeys(target){
        return Object.keys(target)
                     .filter(key => {
                         // console.log(key); // name  age  _passWord
                         return !key.startsWith('_');
                     });
        // 可直接把Object.keys換成  Reflect.keys
    },
});

// get
console.log(user.name); //  xx
try{
    console.log(user._passWord);
} catch(e){
    console.log(e.message);
}   //  會(huì)打印不可訪問

// set
user.name = 11;
console.log(user.name);  // 11
try{
    user._passWord = 11;
} catch(e){
    console.log(e.message);
}   //  會(huì)打印不可訪問

// delete 與上一致
apply
let getSum = (...args) => {
    let num = 0;
    args.forEach((item) => {
        num += item;
    });
    return num;
};
console.log(getSum(1, 2));  // 3

getSum = new Proxy(getSum, {
    apply(target, thisArg, argArray){
        // return target(...argArray) * 2;

        // 改變誰,,,改變成誰,,,參數(shù)
        return Reflect.apply(target, target, [...argArray]) * 2;
    }
});
console.log(getSum(1, 2));  // 6
console.log(getSum.apply(null, [1, 2]));  // 6
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末书释,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子赊窥,更是在濱河造成了極大的恐慌爆惧,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锨能,死亡現(xiàn)場(chǎng)離奇詭異扯再,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)址遇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門熄阻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人傲隶,你說我怎么就攤上這事饺律。” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵复濒,是天一觀的道長(zhǎng)脖卖。 經(jīng)常有香客問我,道長(zhǎng)巧颈,這世上最難降的妖魔是什么畦木? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮砸泛,結(jié)果婚禮上十籍,老公的妹妹穿的比我還像新娘。我一直安慰自己唇礁,他們只是感情好勾栗,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盏筐,像睡著了一般围俘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上琢融,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天界牡,我揣著相機(jī)與錄音,去河邊找鬼漾抬。 笑死宿亡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的纳令。 我是一名探鬼主播挽荠,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼泊碑!你這毒婦竟也來了坤按?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤馒过,失蹤者是張志新(化名)和其女友劉穎臭脓,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腹忽,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡来累,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了窘奏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘹锁。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖着裹,靈堂內(nèi)的尸體忽然破棺而出领猾,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布摔竿,位于F島的核電站面粮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏继低。R本人自食惡果不足惜熬苍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望袁翁。 院中可真熱鬧柴底,春花似錦、人聲如沸粱胜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽焙压。三九已至凿歼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間冗恨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工味赃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掀抹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓心俗,卻偏偏與公主長(zhǎng)得像傲武,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子城榛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351