共计 7354 个字符,预计需要花费 19 分钟才能阅读完成。
Reflect
Reflect
领有 Object
对象的一些外部办法,某些办法会同时在 Object
对象和 Reflect
对象上部署,也就是说 Object
对象上存在的办法,通过 Reflect
也能够拜访到。
单论 Reflect 的话,能够这么了解,Reflect 就是继承了 Object 的某些内置办法,并且提供了优化
Object
对象上的某些办法会有些缺点,例如:在 Object.defineProperty
上对一个不可写或不可枚举的属性进行 getter
或setter
时会抛出谬误,对于这个谬误,咱们须要 try catch
去捕捉,而 Reflect.defineProperty
则会抛出 false
来示意本次操作失败(Reflect
对对象的操作都会抛出 true
和false
来示意是否操作胜利)。
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); // false
console.log(obj2.age); // 100
// Reflect 会抛出 false 示意此次操作失败
Object
的局部操作是命令式的
let obj3 = {
name : '东方不败',
age : 100
}
console.log('name' in obj3); // true
console.log(delete obj3.age); // true
console.log(obj3); // {name: '东方不败'}
而 Reflect
的操作是函数式的
let obj4 = {
name : '东方求败',
age : 100
}
console.log(Reflect.has(obj4,'name')); // true
console.log(Reflect.deleteProperty(obj4,'age')); // true
console.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); // true
console.log(Reflect.has(o3,'name')); // true
如果 Reflect.has
的第一个参数不是对象会报错
Reflect.deleteProperty(obj, name)
相当于 Object
的删除操作:delete obj.name
,用于删除对象的属性
let o4 = {
book : '疾风劲草',
text : '一臂之力'
}
// Object
delete o4.book
console.log(o4); // {text: '一臂之力'}
// Reflect
Reflect.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.construct
let 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.defineProperty
,Reflect.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); // true
console.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
中静态方法,下表具体介绍了 Object
和Reflect API
上可用办法之间的差别。请留神,如果 API
中不存在某种办法,则将其标记为N/A
。
办法 | Object | Reflect |
---|---|---|
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/A | Reflect.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/A | Reflect.ownKeys()返回一个属性名称数组,该属性名称映射到指标对象本人的属性键。如果指标不是 Object,则抛出 TypeError。 |
上述表格的数据比照起源链接:比拟 Reflect 和 Object 办法
案例源码:https://gitee.com/wang_fan_w/es6-science-institute
如果感觉这篇文章对你有帮忙,欢送点亮一下 star 哟