1. 程式人生 > >Reflect

Reflect

找到 解釋 foo per 基礎 怎麽 def 分享圖片 const

Reflect

為操作對象提供的新api,可以拿到語言內部的方法

一. 設計目的:

1.將Object對象的一些明顯屬於語言內部的方法(比如Object.defineProperty)放在reflect中,當前某些方法會在object和reflect中共同存在,後續新的方法都只會在reflect對象中存在,後續新的方法都只會在reflect對象中

2.修改object方法中的返回結果,讓其更合理

3.讓object操作都變成函數行為,某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)讓它們變成了函數行為

4.reflect對象的方法與proxy對象的方法一一對應,只要proxy對象的方法,就能在reflect對象上找到對應的方法。這就讓proxy對象可以方便的調用對象的方法,完成默認的行為,作為修改行為的基礎,不管proxy怎麽修改默認行,你總可以在reflect上獲取默認行為

    let obj1={}
    let  temp1=new Proxy(obj1,{
        set:function (target,name,value,receiver) {
            let success=Reflect.set(target,name,value,receiver);
            
if(success){ console.log(`property ${name} on ${target} set to ${value}`) } return success } }) temp1.a="a"//property a on [object Object] set to a obj1.a="a"//沒有調用set

二. 靜態方法

Reflect對象一共有 13 個靜態方法。

Reflect.apply(target, thisArg, args)</br>

Reflect.construct(target, args)</br>
Reflect.get(target, name, receiver)</br>
Reflect.set(target, name, value, receiver)</br>
Reflect.defineProperty(target, name, desc)</br>
Reflect.deleteProperty(target, name)</br>
Reflect.has(target, name)</br>
Reflect.ownKeys(target)</br>
Reflect.isExtensible(target)</br>
Reflect.preventExtensions(target)</br>
Reflect.getOwnPropertyDescriptor(target, name)</br>
Reflect.getPrototypeOf(target)</br>
Reflect.setPrototypeOf(target, prototype)</br>
上面這些方法的作用,大部分與Object對象的同名方法的作用都是相同的,而且它與Proxy對象的方法是一一對應的。下面是對它們的解釋。

三.具體靜態方式實例

1.Reflect.get(target, name, receiver)

let myObject={
        foo:1,
        getFoo(){
            return  this.foo
        },
        get baz(){
            return  this.foo
        }
    }
    let myReceiveObject={
        foo:2
    }
    console.log(Reflect.get(myObject,‘foo‘)) //1
    console.log(Reflect.get(myObject,‘foo‘,myReceiveObject))//1
    console.log(Reflect.get(myObject,‘getFoo‘,myReceiveObject))//ƒ getFoo(){return  this.foo}
    console.log(Reflect.get(myObject,‘baz‘,myReceiveObject))//部署了讀取函數(getter),則讀取函數的this綁定receiver

2. Reflect.set(target, name, value, receiver)

let  myObject2={
    foo:1,
    set bar(value){
       return  this.foo=value
    }
}
let myReceiveObject2={
    foo:2
}
console.log("2.2 set :"+myObject2.foo)//2.2 set :1
console.log( Reflect.set(myObject2,‘bar‘,2))//true
console.log("2.2 Reflect set :"+myObject2.foo)//2.2 Reflect set :2
console.log("2.2 "+Reflect.set(myObject2,‘bar‘,4,myReceiveObject2))//2.2 true
console.log("2.2_"+myObject2.foo)//2.2_2
console.log("2.2_"+myReceiveObject2.foo)//2.2_4

let p = {
    a: ‘a‘
};

let handler = {
    set(target, key, value, receiver) {
        console.log(‘set‘);
        Reflect.set(target, key, value, receiver)
        //寫receiver 就說明Reflect.set是調用obj裏面的,就會觸發obj defineProperty
        // 如果不寫的話就不會調用定義在 obj裏面的
    },
    defineProperty(target, key, attribute) {//
        console.log(‘defineProperty‘);
        Reflect.defineProperty(target, key, attribute);
    }
};

let obj = new Proxy(p, handler);
obj.a = ‘A‘;//set     defineProperty

3 Reflect.has(obj, name)

    function Greeting(name,age) {
        this.name = name;
        this.age = age;
    }
    // new 的寫法
    const instance = new Greeting(‘張三‘);
    // Reflect.construct 的寫法
    const instance5 = Reflect.construct(Greeting, [‘張三‘,‘22‘]);

4 Reflect.getPrototypeOf(obj)

    let myObj7={a:2}
    Object.setPrototypeOf(myObj7,Array.prototype)
    myObj7.pop()//擁有了Array的prototype 
    console.log(myObj7)//[ a: 2]

5.Reflect.apply(func, thisArg, args)方法等同於Function.prototype.apply.call(func, thisArg, args)

//func 方法 thisArg this指針 args參數 可以為null

一般來說,如果要綁定一個函數的this對象,可以這樣寫fn.apply(obj, args),但是如果函數定義了自己的apply方法,

就只能寫成Function.prototype.apply.call(fn, obj, args),采用Reflect對象可以簡化這種操作。

技術分享圖片
   //原始寫法
    let  ages8=[11,33,12,54,18,96]
    let obj8={
        age:8
    }
    Math.min(ages8)
    console.log(Math.min.apply(Math,ages8))//11   第一參數表示this的指向
    console.log("demo8"+ Math.min.apply(null,ages8)) //11
    console.log(Object.prototype.toString.apply(ages8))//[object Array]
    console.log(Array.prototype.toString.apply(obj8))//[object Object]
    // 1原始寫法  更改this紙箱
    function Animal(){
        this.name = "Animal";
        this.showName = function(){
//            alert(this.name);
            console.log(this.name)
        }
    }
    function Cat(){
        this.name = "Cat";
    }
    var animal = new Animal();
    var cat = new Cat();
    //通過call或apply方法,將原本屬於Animal對象的showName()方法交給對象cat來使用了。    
    //輸入結果為"Cat"    
    animal.showName.call(cat,",");//showName  借用到cat中   this指針借用到cat中  call 第二個參數可以是任意
    animal.showName.apply(cat,[]);//apply第二個參數必須是數組 也可以是arguments
    //新的寫法
    let temp9= Reflect.apply(Math.min,Math,ages8)
    console.log(Reflect.apply(Math.min,Math,ages8)) //11
    console.log(Reflect.apply(Math.min,null,ages8))//11
    const type = Reflect.apply(Object.prototype.toString, temp9, []);
  console.log(type)//[object Number]
View Code

6 Reflect.defineProperty(target, propertyKey, attributes)</br>

target 對象 propertyKey 屬性名 { value: ‘xx‘}</br>

     MyDate7={}
     //舊寫法
    //  Reflect.defineProperty(MyDate7, ‘now‘,{value:Date.now()})
     //新寫法
     Reflect.defineProperty(MyDate7, ‘now‘, {
         value: () => {Date.now()} 
     });
    console.log("demo7"+ MyDate7.now)//demo7() => Date.now()

7.Reflect.getOwnPropertyDescriptor(target, propertyKey)

    var myObject8 = {};
    Object.defineProperty(myObject8, ‘hidden‘, {
        value: true,
        enumerable: false,
    });
    // 舊寫法
    var theDescriptor = Object.getOwnPropertyDescriptor(myObject8, ‘hidden‘);

    // 新寫法
    var theDescriptor = Reflect.getOwnPropertyDescriptor(myObject8, ‘hidden‘);

Reflect