什么是Reflect?


ES6 为了操作对象而提供的新API,未来的新方法将只部署在Reflect对象上!

初探Reflect

Reflect与Proxy是相辅相成的,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法!

const obj = { name: "song" };
const proxy = new Proxy(obj, {
  get(target, name) {
    // reflect保证原生行为能够正常执行
    return Reflect.get(target, name);
  },
  set(target, name, value) {
    return Reflect.set(target, name, value);
  },
  has(target, name) {
    // 通过in操作符会调用has方法
    return Reflect.has(target, name);
  }
});
// reflect 将原有的命令式 都转化为函数行为
console.log("name" in proxy);
console.log(Reflect.has(proxy, "name")); // 也可以直接通过Reflect来判断

Reflect静态方法

Reflect对象一共有 13 个静态方法。我们依次用老写法和新写法做对比!

1.Reflect.get

获取对象中对应key的值

const my = {
    name:'song',
    age:18,
    get mny(){
        return this.a + this.b
    }
}
console.log(my['age']); // 老写法
console.log(Reflect.get(my,'age'));
console.log(Reflect.get(my,'mny',{a:1,b:2})); // 可以指定this指向

2.Reflect.set

设置对象中key对应的值

const my = {
  name: "song",
  age: 18,
  set mny(val) {
    this.value = val;
  }
};
let mny = { value: 0 };
my.mny = 100; // 老写法
Reflect.set(my, "mny", 100);
Reflect.set(my, "mny", 100, mny); // 给对象设置属性,并且传递this
console.log(mny); // {value:100}

3.Reflect.has

判断某个key是否属于这个对象

const my = {
    name:'song'
}
console.log('name' in my);
console.log(Reflect.has(my,'name'));

4.Reflect.defineProperty

定义对象的属性和值,等价于Object.defineProperty

const person = {};
Object.defineProperty(person,'name',{
    configurable:false,
    value:'song'
});
console.log(person.name); // 老写法,后续会被废弃

Reflect.defineProperty(person,'name',{
    configurable:false,
    value:'song'
})
console.log(person.name);

5.Reflect.deleteProperty

删除对象中某个属性

const person = {};
Reflect.defineProperty(person,'name',{
    configurable:false,
    value:'song'
});
// delete person.name; 无返回值
const flag = Reflect.deleteProperty(person,'name');
console.log(flag); // 返回是否删除成功

6.Reflect.construct

实例化类,等价于new

class Person{
    constructor(sex){
        console.log(sex);
    }
}
new Person('女'); // 老写法
Reflect.construct(Person,['男']);

7.Reflect.getPrototypeOf

读取proto,等价于Object.getPrototypeOf,不同的是如果方法传递的不是对象会报错!

class Person {}
// 老写法
console.log(Object.getPrototypeOf(Person) === Reflect.getPrototypeOf(Person));

8.Reflect.setPrototypeOf

设置proto,等价于Object.setPrototypeOf,不同的是返回一个boolean类型表示是否设置成功!

let person = {name:'song'};
let obj = {age:18};
// Object.setPrototypeOf(person,obj); // 老写法
Reflect.setPrototypeOf(person,obj);
console.log(person.age);

9.Reflect.apply

想必apply方法大家都很了解了, Reflect.apply 等价于Function.prototype.apply.call

const func = function(a,b){
    console.log(this,a,b);
}
func.apply = () =>{
    console.log('apply')
}
// func.apply({name:'song'},[1,2]); // 调用的是自己身上的方法
Function.prototype.apply.call(func,{name:'song'},[1,2]); // 老写法
Reflect.apply(func,{name:'song'},[1,2]); // 是不是非常的简单!

10.Reflect.getOwnPropertyDescriptor

等价于Object.getOwnPropertyDescriptor,获取属性描述对象

const obj = {name:1};
// const descriptor = Object.getOwnPropertyDescriptor(obj,'name'); // 老写法
const descriptor = Reflect.getOwnPropertyDescriptor(obj,'name');
console.log(descriptor);

11.Reflect.preventExtensions

让一个对象变的不可扩展,也就是永远不能再添加新的属性,等价于 Object.preventExtensions

const person = {};
// 旧写法
Object.preventExtensions(person); // 设置对象不可扩展
Reflect.preventExtensions(person);
person.a = 1;
console.log(person.a); // undefined

12.Reflect.isExtensible

表示当前对象是否可扩展,等价于Object.isExtensible

const person = {};
Reflect.preventExtensions(person);
Object.isExtensible(person) // 老写法 false
Reflect.isExtensible(person) // false

13.Reflect.ownKeys

用于返回对象的所有属性,包括Symbol属性

const person = {
    age:18,
    [Symbol('name')]:'song'
};
console.log(Object.getOwnPropertyNames(person)); // [ 'age' ] 老写法
console.log(Object.getOwnPropertySymbols(person)); // [ Symbol(name) ] 老写法
console.log(Reflect.ownKeys(person)); // [ 'age', Symbol(name) ]
到此我们把Reflect的所有用法已经讲解完毕,内容比较干!其实核心就是将原有的Object的部分方法放到了Reflect上,至于难度完全没看到!

图片描述


Wen前端严选
876 声望99 粉丝

精选前端前沿技术,涵盖前端完整技术体系!进阶高级前端!