ES6(2015)Reflect
Posted 优小U
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6(2015)Reflect相关的知识,希望对你有一定的参考价值。
Reflect
对象与Proxy
对象一样,也是ES6
为了操作对象
而提供的新 API。
1. 设计目的
- 将
Object
属于语言内部的方法放到Reflect
上
let obj = {}
let newVal = ''
Reflect.defineProperty(obj, 'name', {
get() {
return newVal
},
set(val) {
newVal = val
}
})
obj.name = 'xiaoming'
console.log(obj.name) // xiaoming
- 修改某些Object方法的返回结果,让其变得更合理
// ES5 Object 报错
try {
Object.defineProperty(target, property, attributes)
// success
} catch (e) {
// failure
}
// ES6 Reflect 返回Boolean值
if (Reflect.defineProperty(target, property, attributes)) {
// success
} else {
// failure
}
- 让Object操作变成函数行为
// ES5
'assign' in Object // true
// ES6
Reflect.has(Object, 'assign') // true
Reflect
对象的方法与Proxy
对象的方法一一对应,只要是Proxy
对象的方法,就能在Reflect
对象上找到对应的方法。
Proxy(target, {
set: function(target, name, value, receiver) {
var success = Reflect.set(target, name, value, receiver)
if (success) {
console.log('property ' + name + ' on ' + target + ' set to ' + value)
}
return success
}
})
与大多数全局对象不同,Reflect没有构造函数。你不能将其与一个new运算符一起使用,或者将Reflect对象作为一个函数来调用。Reflect的所有属性和方法都是静态的(就像Math对象)
2. 常用方法
Reflect.apply()
语法:Reflect.apply(target, thisArgument, argumentsList)
Reflect.apply(Math.floor, undefined, [1.75])
// 1
Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111])
// "hello"
Reflect.apply(RegExp.prototype.exec, /ab/, ['confabulation']).index
// 4
Reflect.apply(''.charAt, 'ponies', [3])
// "i"
该方法与ES5中Function.prototype.apply()方法类似:调用一个方法并且显式地指定this变量和参数列表(arguments) ,参数列表可以是数组,或类似数组的对象。
// ES5
Function.prototype.apply.call(Math.floor, undefined, [1.75])
Reflect.construct()
语法:Reflect.construct(target, argumentsList[, newTarget])
Reflect.construct允许你使用可变的参数来调用构造函数
var obj = new Foo(...args)
var obj = Reflect.construct(Foo, args)
var d = Reflect.construct(Date, [2021, 6, 4])
d instanceof Date // true
d.getFullYear() // 2021
如果使用 newTarget 参数,则表示继承了 newTarget 这个超类:
function someConstructor() {}
var result = Reflect.construct(Array, [], someConstructor)
Reflect.getPrototypeOf(result) // someConstructor.prototype
Array.isArray(result) // true
Reflect.defineProperty()
静态方法 Reflect.defineProperty()
基本等同于 Object.defineProperty()
方法,唯一不同是返回 Boolean
值。
语法:Reflect.defineProperty(target, propertyKey, attributes)
const people = {}
Reflect.defineProperty(people, 'name', {
value: 'xiaoming'
}) // true
people.name // "xiaoming"
Reflect.deleteProperty()
Reflect.deleteProperty
允许你删除一个对象上的属性。返回一个 Boolean 值表示该属性是否被成功删除。
语法:Reflect.deleteProperty(target, propertyKey)
var obj = {
x: 1,
y: 2
}
Reflect.deleteProperty(obj, "x") // true
obj // { y: 2 }
var arr = [1, 2, 3, 4, 5]
Reflect.deleteProperty(arr, "3") // true
arr // [1, 2, 3, , 5]
// 如果属性不存在,返回 true
Reflect.deleteProperty({}, "foo") // true
// 如果属性不可设置,返回 false
Reflect.deleteProperty(Object.freeze({
foo: 1
}), "foo") // false
Reflect.get()
Reflect.get()
方法的工作方式,就像从 object 中获取属性target[propertyKey]
,但它是作为一个函数执行的。
语法: Reflect.get(target, propertyKey[, receiver])
// Object
var obj = {
x: 1,
y: 2
}
Reflect.get(obj, 'x') // 1
// Array
Reflect.get(['zero', 'one'], 1) // "one"
// Proxy with a get handler
var x = {
p: 1
}
var obj = new Proxy(x, {
get(t, k, r) {
return k + 'bar'
}
})
Reflect.get(obj, 'foo') // "foobar"
Reflect.set()
允许你在对象上设置属性。它的作用是给属性赋值并且就像 property accessor 语法一样,但是它是以函数的方式。
语法:Reflect.set(target, propertyKey, value[, receiver])
// Object
var obj = {}
Reflect.set(obj, "prop", "value") // true
obj.prop // "value"
// Array
var arr = ["duck", "duck", "duck"]
Reflect.set(arr, 2, "goose") // true
arr[2] // "goose"
// It can truncate an array.
Reflect.set(arr, "length", 1) // true
arr // ["duck"]
// With just one argument, propertyKey and value are "undefined".
var obj = {}
Reflect.set(obj) // true
Reflect.getOwnPropertyDescriptor(obj, "undefined")
// { value: undefined, writable: true, enumerable: true, configurable: true }
Reflect.getOwnPropertyDescriptor()
静态方法 Reflect.getOwnPropertyDescriptor()
与 Object.getOwnPropertyDescriptor()
方法相似。如果在对象中存在,则返回给定的属性的属性描述符,否则返回undefined
。Reflect.getOwnPropertyDescriptor()
的第一个参数不是一个对象(一个原始值),那么将造成 TypeError 错误;而对于Object.getOwnPropertyDescriptor
,非对象的第一个参数将被强制转换为一个对象处理。
语法:Reflect.getOwnPropertyDescriptor(target, propertyKey)
Reflect.getOwnPropertyDescriptor({
x: 'hello'
}, 'x')
// {value: "hello", writable: true, enumerable: true, configurable: true}
Reflect.getOwnPropertyDescriptor({
x: 'hello'
}, 'y')
// undefined
Reflect.getOwnPropertyDescriptor([], 'length')
// {value: 0, writable: true, enumerable: false, configurable: false}
Reflect.getPrototypeOf()
静态方法 Reflect.getPrototypeOf()
与 Object.getPrototypeOf()
方法是一样的。都是返回指定对象的原型(即,内部的 [[Prototype]] 属性的值)。
语法:Reflect.getPrototypeOf(target)
Reflect.has()
检查一个对象是否拥有某个属性, 相当于in 操作符。
语法:Reflect.has(target, propertyKey)
Reflect.isExtensible()
判断一个对象是否可扩展 (即是否能够添加新的属性),它与 Object.isExtensible()
方法一样。
Reflect.ownKeys()
返回一个由目标对象自身的属性键组成的数组。它的返回值等同于 Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))
语法:Reflect.ownKeys(target)
Reflect.preventExtensions()
阻止新属性添加到对象。
语法:Reflect.preventExtensions(target)
// Objects are extensible by default.
var empty = {}
Reflect.isExtensible(empty) // === true
// ...but that can be changed.
Reflect.preventExtensions(empty)
Reflect.isExtensible(empty) // === false
Reflect.setPrototypeOf()
改变指定对象的原型 (即,内部的 [[Prototype]] 属性值)。
语法:Reflect.setPrototypeOf(target, prototype)
Reflect.setPrototypeOf({}, Object.prototype) // true
// It can change an object's [[Prototype]] to null.
Reflect.setPrototypeOf({}, null) // true
// Returns false if target is not extensible.
Reflect.setPrototypeOf(Object.freeze({}), null) // false
// Returns false if it cause a prototype chain cycle.
var target = {}
var proto = Object.create(target)
Reflect.setPrototypeOf(target, proto) // false
以上是关于ES6(2015)Reflect的主要内容,如果未能解决你的问题,请参考以下文章