Reflect

Reflect领有Object对象的一些外部办法,某些办法会同时在Object对象和Reflect对象上部署,也就是说Object对象上存在的办法,通过Reflect也能够拜访到。
单论Reflect的话,能够这么了解,Reflect就是继承了Object的某些内置办法,并且提供了优化

Object对象上的某些办法会有些缺点,例如:在Object.defineProperty上对一个不可写或不可枚举的属性进行gettersetter时会抛出谬误,对于这个谬误,咱们须要try catch去捕捉,而Reflect.defineProperty则会抛出false来示意本次操作失败(Reflect对对象的操作都会抛出truefalse来示意是否操作胜利)。
Object

const obj = { name : '东方不败' }Object.defineProperty(obj,'age',{    value : 100,    writable : true,  // 只读    configurable : false  // 不可删除和批改})Object.defineProperty(obj,'age',{    get(){ return 200 }})console.log(obj.age); //  TypeError : Cannot redefine property: age// 报错,不能从新定义属性

Reflect

const obj2 = { name : '东方求败' }Object.defineProperty(obj2,'age',{    value : 100,    writable : true,  // 只读    configurable : false  // 不可删除和批改})let status = Reflect.defineProperty(obj2,'age',{    get(){ return }})console.log(status); //  falseconsole.log(obj2.age); // 100// Reflect会抛出false示意此次操作失败

Object的局部操作是命令式的

let obj3 = {    name : '东方不败',    age : 100}console.log('name' in obj3);  // trueconsole.log(delete obj3.age);  // trueconsole.log(obj3);  // {name: '东方不败'}

Reflect的操作是函数式的

let obj4 = {    name : '东方求败',    age : 100}console.log(Reflect.has(obj4,'name'));  // trueconsole.log(Reflect.deleteProperty(obj4,'age')); // trueconsole.log(obj4);  // {name: '东方求败'}

通过下面的案例能够晓得,Object外部的局部办法能够在Reflect上拜访,Reflect对象一共有13个静态方法,如下:

1、Reflect.apply(target, thisArg, args)2、Reflect.construct(target, args)3、Reflect.get(target, name, receiver)4、Reflect.set(target, name, value, receiver)5、Reflect.defineProperty(target, name, desc)6、Reflect.deleteProperty(target, name)7、Reflect.has(target, name)8、Reflect.ownKeys(target)9、Reflect.isExtensible(target)10、Reflect.preventExtensions(target)11、Reflect.getOwnPropertyDescriptor(target, name)12、Reflect.getPrototypeOf(target)13、Reflect.setPrototypeOf(target, prototype)

上面是对于下面一些办法的应用解释

Reflect.get(target,name,receiver)

Reglect.get()有三个参数,别离是

 1、`target` :指标对象 2、`name`:对象属性 3、`receiver`: 代理对象(可疏忽)

作用:查找并返回target对象的name属性,如果该属性不存在则返回undefined

let o = {    name : '西方',    text : '不败'}console.log(Reflect.get(o,'name'));  // 西方


Reflect.set(target, name, value, receiver)

用于设置target对象的name属性等于value,如果批改胜利返回true,失败返回false

  let o2 = {    name : '艺术概论',  }// 如果这里设置为不可批改那么back 会输入false,price的值则为undefined//   Object.defineProperty(o2,'price',{//     configurable : false//   })  let back = Reflect.set(o2,'price',100)  console.log(back); // true  console.log(o2);  // {name: '艺术概论', price: 100}


Reflect.has(obj, name)

相当于Object里的in运算符,判断以后属性在指标对象内是否存在,true存在,false不存在

let o3 = {    name : '中国工艺美术史'}console.log('name' in o3);  // trueconsole.log(Reflect.has(o3,'name')); // true

如果Reflect.has的第一个参数不是对象会报错


Reflect.deleteProperty(obj, name)

相当于Object的删除操作:delete obj.name,用于删除对象的属性

let o4 = {    book : '疾风劲草',    text : '一臂之力'}// Objectdelete o4.bookconsole.log(o4);  // {text: '一臂之力'}// ReflectReflect.deleteProperty(o4,'text')console.log(o4);  // {}


Reflect.construct(target, args)

相当于new class(params),这里的Reflect能够不必new来创立调用构造函数的办法

function Person(name){    this.name = name}// new 写法let onNew = new Person('西方')// Reflect.constructlet onNew2 = Reflect.construct(Person,['不败'])

Reflect.construct的第一个参数不是函数会报错


Reflect.getPrototypeOf(obj)

对应Object.getPrototypeOf(obj),用于读取对象的__proto__属性

let o5 = new String()// Object.getPrototypeOf()console.log(Object.getPrototypeOf(o5) == String.prototype); // true// Reflect.getPrototypeOf()console.log(Reflect.getPrototypeOf(o5) == String.prototype); // true


Reflect.setPrototypeOf(obj, newProto)

对应Object.setPrototypeOf(obj, newProto),用于设置指标对象的原型(prototype)

let o6 = {}Reflect.setPrototypeOf(o6,Array.prototype)console.log(o6.length);  // 0


Reflect.defineProperty(target, propertyKey, attributes)

相当于Object.definePropertyReflect.defineProperty()用来定义对象的属性。

let o7 = {    name : '东方不败'}Reflect.defineProperty(o7,'age',{    value : 100,    configurable: true,    enumerable : true,    writable : true})console.log(o7);  // {name: '东方不败', age: 100}

如果Reflect.defineProperty()的第一个参数不是对象,会抛出谬误。


Reflect.getOwnPropertyDescriptor(target, propertyKey)

对应Object.getOwnPropertyDescriptor,用来取得指定属性的形容对象

let o8 = {    name : '东方不败'}Reflect.defineProperty(o8,'age',{    value : 100,    configurable: true,    enumerable : true,    writable : true})let back8 = Reflect.getOwnPropertyDescriptor(o8,'age')console.log(back8);  // {value: 100, writable: true, enumerable: true, configurable: true}

如果Reflect.getOwnPropertyDescriptor()的第一个参数不是对象,会抛出谬误。


Reflect.isExtensible (target)

相当于Object.isExtensible,返回布尔值,示意以后对象是否扩大

let o9 = {}let back9 = Reflect.isExtensible(o9)console.log(back9);  // true

如果参数不是对象会报错,非对象原本就是不可扩大的

console.log(Reflect.isExtensible(100));  // 报错


Reflect.preventExtensions(target)

相当于Object.preventExtensions,能够让指标对象变为不可扩大状态,返回布尔值示意是否设置胜利

let b = {}let info =  Reflect.preventExtensions(b)console.log(info); // trueconsole.log(Reflect.isExtensible(b)); // false

如果参数不是对象会报错


Reflect.ownKeys (target)

用于返回指标对象的所有属性,包含Symbol

let address = Symbol.for('武汉')let b2 = {    name : '东方不败',    age : 100,    [address] : '世界城广场'}let info2 = Reflect.ownKeys(b2)console.log(info2); // ['name', 'age', Symbol(武汉)]

如果Reflect.ownKeys ()的参数不是对象会报错


Reflect.apply(func, thisArg, args)

用于绑定this对象后执行给定函数。如果要给行数绑定一个this对象,能够应用apply的形式,但入股函数本人定义了本人的apply办法,就只能写成Function.prototype.apply.call(fn, obj, args)的办法嵌套,而Reflect则能够简化。

 let arr = [1,2,3,4,5,6,7]  // 旧写法 let a = Math.min.apply( Math, arr) let a2 = Math.max.apply( Math, arr) let a3 = Object.prototype.toString.call(a) console.log(a);   // 1 console.log(a2);  // 7 console.log(a3);  // [object Number] // 新写法 let a4 = Reflect.apply( Math.min, Math, arr) let a5 = Reflect.apply( Math.max, Math, arr) let a6 = Reflect.apply( Object.prototype.toString, a4, []) console.log(a4);  // 1 console.log(a5);  // 7 console.log(a6);  // [object Number]
apply办法:Function.apply(obj,args)办法能接管两个参数  obj:这个对象将代替Function类里this对象args:这个是数组,它将作为参数传给Function

事实上Reflect上存在的一些动态函数对应与ES2015之前的Object上可用的办法,只管某些办法在行为上看起来类似,但它们之间经常存在着一些轻微的差别。Reflect对象一共有13中静态方法,下表具体介绍了ObjectReflect API上可用办法之间的差别。请留神,如果API中不存在某种办法,则将其标记为N/A

办法ObjectReflect
defineProperty()Object.defineProperty() 返回传递给函数的对象。如果未在对象上胜利定义属性,则返回TypeError。如果在对象上定义了属性,则Reflect.defineProperty()返回true,否则返回false。
defineProperties()Object.defineProperties() 返回传递给函数的对象。如果未在对象上胜利定义属性,则返回TypeError。N/A
set()N/A如果在对象上胜利设置了属性,则Reflect.set()返回true,否则返回false。如果指标不是Object,则抛出TypeError
get()N/AReflect.get()返回属性的值。如果指标不是Object,则抛出TypeError。
deleteProperty()N/A如果属性从对象中删除,则Reflect.deleteProperty()返回true,否则返回false。
getOwnPropertyDescriptor()如果传入的对象参数上存在Object.getOwnPropertyDescriptor() ,则会返回给定属性的属性描述符,如果不存在,则返回undefined。如果给定属性存在于对象上,则Reflect.getOwnPropertyDescriptor() 返回给定属性的属性描述符。如果不存在则返回undefined,如果传入除对象(原始值)以外的任何货色作为第一个参数,则返回TypeError
getOwnPropertyDescriptors()Object.getOwnPropertyDescriptors() 返回一个对象,其中蕴含每个传入对象的属性描述符。如果传入的对象没有领有的属性描述符,则返回一个空对象。N/A
getPrototypeOf()Object.getPrototypeOf()返回给定对象的原型。如果没有继承的原型,则返回null。在 ES5 中为非对象抛出TypeError,但在 ES2015 中强制为非对象。Reflect.getPrototypeOf()返回给定对象的原型。如果没有继承的原型,则返回 null,并为非对象抛出TypeError。
setPrototypeOf()如果对象的原型设置胜利,则Object.setPrototypeOf()返回对象自身。如果设置的原型不是Object或null,或者被批改的对象的原型不可扩大,则抛出TypeError。如果在对象上胜利设置了原型,则Reflect.setPrototypeOf() 返回 true,否则返回 false(包含原型是否不可扩大)。如果传入的指标不是Object,或者设置的原型不是Object或null,则抛出TypeError。
isExtensible()如果对象是可扩大的,则 Object.isExtensible()返回 true,否则返回 false。如果第一个参数不是对象(原始值),则在 ES5 中抛出TypeError。在 ES2015 中,它将被强制为不可扩大的一般对象并返回false。如果对象是可扩大的,则Reflect.isExtensible() 返回true,否则返回false。如果第一个参数不是对象(原始值),则抛出TypeError。
preventExtensions()Object.preventExtensions() 返回被设为不可扩大的对象。如果参数不是对象(为原始值),则在 ES5 中抛出 TypeError。在 ES2015 中,则将参数视为不可扩大的一般对象,并返回对象自身。如果对象已变得不可扩大,则 Reflect.preventExtensions() 返回 true,否则返回 false。如果参数不是对象(为原始值),则抛出 TypeError。
keys()Object.keys()返回一个字符串数组,该字符串映射到指标对象本人的(可枚举)属性键。如果指标不是对象,则在 ES5 中抛出TypeError,但将非对象指标强制为 ES2015 中的对象N/A
ownKeys()N/AReflect.ownKeys()返回一个属性名称数组,该属性名称映射到指标对象本人的属性键。如果指标不是Object,则抛出TypeError。

上述表格的数据比照起源链接:比拟 Reflect 和 Object 办法


案例源码:https://gitee.com/wang_fan_w/es6-science-institute

如果感觉这篇文章对你有帮忙,欢送点亮一下star哟