Reflect 对象

Reflect 对象

Reflect 对象与 Proxy 对象一样,也是 ES6 为了操作对象而提供的新 API

简单来说两点,一个就是将 Object 对象的一些明显属于语言内部的方法(比如 Object.defineProperty),放到 Reflect 对象上,另一个就是让 Object 操作都变成函数行为,因为 ES5 很多 Object 操作都是命令式的(另外一个原因就是这些方法可能是全局的,或者要通过原型来调用,统一起来),这里只简单的介绍几个常用的方法,详细的可见 ECMAScript 6 入门Reflect - MDN

Reflect.apply(target, thisArgument, argumentsList)

ES5Function.prototype.apply 方法是类似的,比如查找数组中最大数

1
2
3
4
5
6
// ES5
Math.max.apply(undefined, [1, 2, 3, 4, 5])
Function.prototype.apply.call(Math.max, undefined, [1, 2, 3, 4, 5])

// ES6
Reflect.apply(Math.max, undefined, [1, 2, 3, 4, 5])

切割字符串

1
2
3
4
5
6
// ES5 
'hello world'.slice(2, 8) // 'llo wo'
String.prototype.slice.apply('hello world', [2, 8]) // 'llo wo'

// ES6
Reflect.apply(String.prototype.slice, 'hello world', [2, 8]) // 'llo wo'

Reflect.construct(target, argumentsList[, newTarget])

与使用 new target(...args) 方法类似,相当于提供了一种新的不使用 new 来调用构造函数的方法

  • target 表示被运行的目标函数
  • argumentsList 调用构造函数传递的参数数组或者伪数组
  • newTarget 参数为构造函数,表示使用 Reflect.construct 后生成的对象是谁的实例
  • 如果没有传递第三个参数,默认和 target 一样

如果没有传递第三个参数,那么 target 就是唯一的构造函数,但是如果传递了第三个参数,那就表示实例将由两部分组成,实例的属性部分(constructor)由第一个参数生成,实例的方法部分由第三个参数生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class A1 {
constructor(name) {
console.log('Class A1 is invoked!')
this.name = name
}
getName() {
console.log(this.name)
return this.name
}
}

class B1 {
constructor(age) {
console.log('Class B1 is invoked!')
this.age = age
}
getAge() {
console.log(this.age)
return this.age
}
}

// 使用 A1 类作为构造函数
let a1 = Reflect.construct(A1, ['happy'])

// 使用 B1 类作为构造函数
let b1 = Reflect.construct(A1, ['happy'], B1)

console.log(a1)
console.log(b1)

// A1 {name: 'happy'}
// name: 'happy'
// __proto__:
// constructor: class A1
// getName: ƒ getName()
// __proto__: Object

// B1 {name: 'happy'}
// name: 'happy'
// __proto__:
// constructor: class B1
// getAge: ƒ getAge()
// __proto__: Object

Reflect.defineProperty(target, propertyKey, attributes)

Object.defineProperty 相似,不过如果 Object.defineProperty 的属性定义失败了,就会抛出一个错误,而 Reflect.defineProperty 如果定义属性失败的话就会返回 false

1
2
3
4
5
6
7
8
9
let obj = {}

let result = Reflect.defineProperty(obj, 'name', {
configurable: true,
enumerable: true,
value: 'happy'
})

console.log(result) // true

Reflect.getPrototypeOf(target)

Object.getPrototypeOf 方法是一样的,都是返回一个对象的原型,也就是内部的 [[Prototype]] 属性的值,如果要获取原型的那个值不是一个对象,那么函数 Reflect.getPrototypeOf 会抛出一个异常,对于给定对象的原型,如果没有继承的属性,则返回 null

Reflect.ownKeys(target)

返回由目标对象自身的属性键组成的数组,包括 Symbol 的值

1
2
3
4
5
6
7
8
9
10
11
12
13
let a = Symbol.for('a')
let b = Symbol.for('b')

let obj = {
[a]: 10,
[b]: 20,
key1: 30,
key2: 40
}

Object.getOwnPropertyNames(obj) // [ 'key1', 'key2' ]
Object.getOwnPropertySymbols(obj) // [ Symbol(a), Symbol(b) ]
Reflect.ownKeys(obj) // [ 'key1', 'key2', Symbol(a), Symbol(b) ]

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×