Reflect
- 从 Reflect 对象上可以获得语言内部的方法
- 修改某些 Object 方法的返回结果,让其变得更合理。比如 Object.defineProperty 在无法定义属性时会抛出一个错误,而 Reflect.defineProperty 则会返回 false
- 让 Object 操作都变成函数行为。
- 只要是 Proxy 对象的方法,就能在 Reflect 对象上找到相应的方法,无论 Proxy 怎么修改默认行为,总可以在 Reflect 上获取默认行为
静态方法
Reflect.apply(target, thisArg, args)
等同于 Function.prototype.apply.call(func, thisArg, args),用于绑定 this 对象后执行给定函数。Reflect.construct(target, args)
等同于 new target(…args),提供了一种不使用 new 来调用构造函数的方法:1
2
3
4
5
6
7
8function Greeting(name) {
this.name = name
}
//new 的写法
const instance = new Greeting("张三")
//Reflect.construct 写法
const instance = Reflect.construct(Greeting, ["张三"])
- Reflect.get(target, name, receiver)
查找并返回 target 的 name 属性,如果没有返回 undefined。如果 name 属性部署了 getter,则 getter 的 this 绑定 receiver:1
2
3
4
5
6
7
8
9let obj = {
foo: 1,
bar: 2,
get baz() {
return this.foo + this.bar
},
}
Reflect.get(obj, "foo") //1
Reflect.get(obj, "baz") //3如果第一个参数不是 object,会报错1
2
3
4
5
6
7
8
9
10
11
12let obj = {
foo: 1,
bar: 2,
get gaz() {
return this.foo + this.bar
},
}
let myobj = {
foo: 2,
bar: 4,
}
Reflect.get(obj, "gaz", myobj) //myobj.foo + myobj.bar 6
Reflect.set 会触发 Proxy.defineProperty 拦截:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17let p = {
a: "a",
}
let handler = {
set(target, key, value, receiver) {
console.log("set")
Reflect.set(target, key, value, receiver)
},
defineProperty(target, key, attribute) {
console.log("defineProperty")
Reflect.defineProperty(target, key, attribute)
},
}
let obj = new Proxy(p, handler)
obj.a = "A"
//set
//defineProperty - Reflect.set(target, name, value, receiver)
设置 target 的 name 属性等于 value。如果 name 属性设置了 setter,则 setter 的 this 绑定 receiver:1
2
3
4
5
6
7
8
9let obj = {
foo: 1,
set bar(value) {
return (this.foo = value)
},
}
obj.foo //1
Reflect.set(obj, "foo", 2)
obj.foo //2如果第一个参数不是 object,会报错1
2
3
4
5
6
7
8
9
10
11let obj = {
foo: 1,
set bar(value) {
return (this.foo = value)
},
}
let myobj = {
foo: 0,
}
Reflect.set(obj, "bar", 4, myobj)
myobj.foo //4 - Reflect.defineProperty(target, name, descriptor)
用来定义对象的属性。 - Reflect.deleteProperty(target, name)
等同于 delete obj[name],用于删除对象的属性,返回一个布尔值,删除成功返回 true,否则返回 false。 - Reflect.has(target, name)
对应 name in target 中的 in 运算符,如果第一个参数不是对象,Reflect.has 和 in 都会报错。 - Reflect.ownKeys(target)
返回对象的所有属性,包括 Symbol 属性。 - Reflect.isExtensible(target)
返回一个布尔值,表示当前对象是否可拓展。 - Reflect.preventExtensions(target)
用于使一个对象变为不可拓展的,返回一个布尔值,代表是否成功。 - Reflect.getOwnPropertyDescriptor(target, name)
基本等同于 Object.getOwnPropertyDescriptor(target, propertyKey),用于获得指定属性的描述对象。 - Reflect.getPrototypeOf(target)
用于读取对象的prop属性,对应 Object.getPrototypeOf(obj)。 - Reflect.setPrototypeOf(target, prototype)
用于设置对象的prop属性,返回第一个参数对象。
用 Proxy 实现观察者模式
Observe mode 指的是函数自动观察数据对象的模式,一旦对象有变化,函数就会自动执行。
思路:使用 observable 和 observe 这两个函数,observable 函数返回一个原始对象的 Proxy 代理,拦截赋值操作,触发充当观察者的各个函数。
1 | const queueObservers = new Set() |