Reflect与Proxy一样,是为了更好地操作对象而设计的,Proxy代理通过拦截修改某些方法,而Reflect是将一些方法移植到该对象上,使某些方法变为更加合理。
var obj=new Proxy({},{
set(target,name,value){
console.log(value);
obj.name=value;
}
})
obj.name='jack';
//会无限打印出'jack',因为该操作一直被拦截。
Reflect一共有13个方法,与Proxy对象的方法一一对应,大部分与Object对象的方法同名的方法作用都是相同的。
该方法传入三个参数,第一个参数为要查找的对象,第二个参数为要查找的属性名,第三个参数为查找对象中读取函数中this绑定的对象。
该方法用于获取target对象中属性名为name的值,如果没有该属性,则返回undefined。若有第三个参数,则读取函数中this指向第三个参数的对象,若没有第三个参数,则this指向目标对象。
var obj={
foo:1,
bar:2,
get fn(){
return this.foo+this.bar;
}
}
var outObj={
foo:4,
bar:4
}
Reflect.get(obj,'foo')
// 1
Reflect.get(obj,'fn')
//3
Reflect.get(obj,'fn',outObj)
// 8
上面代码中,最后依次第三个参数为outObj对象,所以Reflect.get调用的方法fn中的this指向outObj对象,所以foo属性加bar属性才为8,没有传入参数时指向obj对象,所以最后结果为3。
方法的第一个参数若不为对象,则会报错,最后一个参数不为对象不会报错。下面出现的方法第一个参数也一样必须为对象,否则会报错(Reflect.apply和Reflect.construct方法第一个参数得是个方法)。
Reflect.get(1,'foo')
// Uncaught TypeError: Reflect.get called on non-object at Object.get
该方法传入四个参数,第一个参数为要查找的对象,第二个参数为要查找的属性名,第三个参数为要给对应属性名设置的值,第四个参数为查找对象中赋值函数中this绑定的对象。
该方法用于设置对象的属性值,同样的在赋值函数中若有this,有第四个参数时this指向第四个参数的对象,没有第四个参数时指向目标对象。在设置时,若有对应的属性名,则修改属性名,若没有,则给对象一个新的属性。
var obj={
foo:1,
set fn(value){
this.foo=value;
}
}
var outObj={
foo:10
}
Reflect.set(obj,'foo',2)
console.log(obj);
// {foo: 2}
Reflect.set(obj,'bar',2)
console.log(obj);
// {foo: 2, bar: 2}
Reflect.set(obj,'fn',3,outObj)
console.log(obj);
// {foo: 2, bar: 2}
console.log(outObj)
// {foo: 3}
同样的,如果第一个参数不是对象时会报错。
该方法传入两个参数,第一个参数为查找的对象,第二个参数为查找的属性名。
该方法查找name属性是否在对象obj中,即返回 obj in name。
var obj={
foo:1
}
Reflect.has(obj,'foo')
// true
该方法传入两个参数,第一个参数为要执行操作的对象,第二个参数为要删除的属性
该方法等同于delete obj[name],用于删除对象的属性,该方法返回一个布尔值,若删除成功或找不到该属性返回true,删除失败返回false。
var obj={
foo:1
}
Reflect.deleteProperty(obj,'foo')
// true 删除成功
Reflect.deleteProperty(obj,'bar')
// true 找不到对应的属性
该方法传入两个参数,第一个参数为要新建的方法名,第二个参数为传入的参数数组
该方法等同于使用new运算符,new target(...args),调用一个构造函数。
function fn(name){
this.name=name;
}
var person=Reflect.construct(fn,['jack']);
console.log(person);
// fn {name: "jack"}
该方法传入一个参数,即要读取原型的对象。
该方法用于读取指定对象的原型对象,等同于Object.getPrototype
var pro={}
var obj=Object.create(pro);
Reflect.getPrototypeOf(obj)===pro
// true
该方法传入两个参数,第一个参数为要设置的对象,第二个参数为要作为原型的对象。
该方法用于设置原型的对象,即将第一个参数的原型设置为第二个参数
var obj={}
var pro={}
Reflect.setPrototypeOf(obj,pro)
// true
Reflect.getPrototypeOf(obj)===pro
// true
该方法传入三个参数,第一个参数为要操作的对象,第二个参数为要设置的属性名,第三个参数为要设置的属性的描述对象
该方法用于设置对象的属性的描述对象,等同于Object.definePrototype,阮一峰的书中提及尽可能地使用该方法,后者会被替代。
var obj={}
Reflect.defineProperty(obj,'foo',{value:10})
console.log(obj);
{foo: 10}
该方法传入两个参数,第一个参数为要操作的对象,第二个参数为属性名。
该方法等同于Object.getOwnPrototyDescriptor,该方法会替代后者,获取属性的描述对象。
var obj={
foo:1
}
Reflect.getOwnPropertyDescriptor(obj,'foo')
// {value: 1, writable: true, enumerable: true, configurable: true}
该方法传入一个参数,即要操作的对象。
该方法等同于Object.isExtensible,返回一个布尔值,表示对象是否可扩展。
var obj={
foo:1
}
Reflect.isExtensible(obj)
// true
该方法传入一个参数,即要操作的对象。
该方法等同于Object.preventExtensions,用于让一个对象变为不可扩展,返回一个布尔值,表示操作是否成功。
var obj={
foo:1
}
Reflect.preventExtensions(obj)
// true
Reflect.isExtensible(obj)
// false
该方法传入一个参数,即要操作的对象。
该方法等同于Object.getOwnPrototyNames与Object.getOwnPrototySymbols得到的属性名值合,即获取对象自身的属性,包括Symbol值作属性名的属性,不能获取继承的属性。
var obj={
foo:1
}
obj[Symbol()]=2
Reflect.ownKeys(obj)
// ["foo", Symbol()]
参考自阮一峰的《ECMAScript6入门》
ES6学习笔记目录
ES6学习笔记(一)let和const
ES6学习笔记(二)参数的默认值和rest参数
ES6学习笔记(三)箭头函数简化数组函数的使用
ES6学习笔记(四)解构赋值
ES6学习笔记(五)Set结构和Map结构
ES6学习笔记(六)Iterator接口
ES6学习笔记(七)数组的扩展
ES6学习笔记(八)字符串的扩展
ES6学习笔记(九)数值的扩展
ES6学习笔记(十)对象的扩展
ES6学习笔记(十一)Symbol
ES6学习笔记(十二)Proxy代理
ES6学习笔记(十三)Reflect对象
ES6学习笔记(十四)Promise对象
ES6学习笔记(十五)Generator函数
ES6学习笔记(十六)asnyc函数
ES6学习笔记(十七)类class
ES6学习笔记(十八)尾调用优化
ES6学习笔记(十九)正则的扩展
ES6学习笔记(二十)ES Module的语法