Reflect
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.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