ES6 Reflect用法详解

624 阅读2分钟

Reflect设计的目的:

  • 将Object对象上明显属于对象内部的方法放到Reflect上,
  • 修改某些Object方法的返回结果,使其变得更合理一些,
  • 让Obj的一些操作变成函数式行为
  • Reflect的方法与Procxy一一对应,

Reflect是通过Introspection来实现反射,主要用于获取底层原生的方法,类似的Introspection方法有:

  • Object.keys:返回一个可以通过object直接访问的可迭代字符串元素的数组
  • Object.getOwnPropertyNames: 返回一个包含所有属性名数组

常用的方法

  • Reflect.apply()
  • Reflect.construct()
  • Reflect.defineProperty()
  • Reflect.deleteProperty()
  • Reflect.get()
  • Reflect.getOwnPropertyDescriptor()
  • Reflect.getPrototypeOf()
  • Reflect.has()
  • Reflect.isExtensible()
  • Reflect.ownKeys()
  • Reflect.preventExtensions()
  • Reflect.set()
  • Reflect.setPrototypeOf()

用法

  • 将Object对象的属于语言内部的方法放到Reflect对象上,即从Reflect对象上拿Object对象内部方法。
  • 使用Object.defineProperty(obj,name,desc)
  • Reflect.defineProperty(obj,name,desc)
//Object.defineProperty()是什么??
let user = {};
let defaultName = "狂奔的蜗牛";
let handler = {
  get:function(){
    console.log("你是不是来获取值啦");
    return defaultName;
  },
  set:function(value){
    console.log("你是不是来设置值啦");
    defaultName = value;
  }
}


Object.defineProperty(user,'name',handler)
Reflect.defineProperty(user,'name',handler)

console.log(user.name);
user.name = "狂奔的萝卜";
console.log(user.name);
// 你是不是来获取值啦
// 狂奔的蜗牛
// 你是不是来设置值啦
// 你是不是来获取值啦
// 狂奔的萝卜
  • 让Object操作变成函数行为
'name' in obj  //旧
Reflect.has(obj, 'name') //新
delete obj['name'] //旧
Reflect.deleteProperty(obj, 'name') //新
//该方法返回一个布尔值。如果删除成功或者被删除的属性不存在,就返回true;如果删除失败或被删除的属性依然存在,则返回false
  • 生成一个构造函数
//旧
let Person=function(name){
    this.firstName = name
}
let person = new Person('fang')
let person = Reflect.constructor('Person', 'fang')
  • get方法
//新
var myObject = {
  foo: 1,
  bar: 2,
  get baz() {
    return this.foo + this.bar;
  },
}

Reflect.get(myObject, 'foo') // 1
Reflect.get(myObject, 'bar') // 2
Reflect.get(myObject, 'baz') // 3
//新
let obj={
 get yu(){
    return this.firstName + this.lastName
 }
}
let nameObj = {
    firstName:'fang',
    lastName: 'shuqin',
}
Reflect.get(obj,'yu', nameObj)
  • 解决Proxy操作后对象中需要访问原生方法的问题

当使用Proxy去包裹一个对象的时候,可以自定义其默认的方法,但是如果想调用此对象的原生的方法,此时直接通过访问对象来调用是获取不到原生方法的,所以此时需要使用Reflect来解决这个问题

const employee = {
    firstName: 'fang',
    lastName: 'shuqin',
    fullName:'',
}
let logHandler ={
    get: function(target, fileName){
        console.log(target[fileName])
        return Reflect.get(target, fileName)
    },
    set: function(target, fileName) {
    console.log('fileName', target[fileName])
        
    }
}
let p = new Proxy(employee, logHandler)
p.firstName
p.lastName
p.fullName='dada'

//注意:用函数包了一层
// console.log(target[fileName])
//return Reflect.get(target, fileName)
//这两个都会返回值
/*
*fang
VM267:8 shuqin
VM267:12 fileName 
VM267:8 fang
VM267:8 shuqin
*/
let func = ()=>{
let p = new Proxy(employee, logHandler) ;       p.firstName;
  p.lastName;
}
func()
  • 在apply中的可读性
Function.property.apply.call(func, obj, arr) //旧
Reflect.apply(func, obj, call) //新