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]
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‘);
原文:https://www.cnblogs.com/dwzheng/p/10474090.html