由浅入深,带你用JavaScript实现响应式原理( 三 )


deleteProperty(target, propertyKey)
delete操作符 , 相当于执行delete target[name]
apply(target, thisArgument, argumentsList)
对一个函数进行调用操作 , 可以传入一个数组作为调用参数 , Function.prototype.apply()
construct(target, argumentsList [, newTarget])
对构造函数进行new操作 , new target(...args)
getPrototypeOf(target)
Object.getPrototype()
setPrototypeOf(target, prototype)
设置对象原型的函数 , 返回一个boolean
isExtensible(target)
Object.isExtensible()
preventExtensions(target)
Object.preventExtensions() , 返回一个boolean
getOwnPropertyDescriptor(target, propertyKey)

Object.getOwnPropertyDescriptor() , 如果对象中存在该属性 , 则返回对应属性描述符 , 否则返回undefined
defineProperty(target, propertyKey, attributes)
Object.defineProperty() , 设置成功返回true
ownKeys(target)
返回一个包含所有自身属性(不包含继承属性)的数组 , 类似于Object.keys() , 但是不会受enumerable影响
具体Reflect和Object对象之间的关系和使用方法 , 可以参考MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect
3.4.Reflect的construct方法

construct方法有什么作用呢?具体的应用场景是什么?这里提一个需求 , 就明白construct方法的作用了 。
需求:创建Person和Student两个构造函数 , 最终的实例对象执行的是Person中的代码 , 带上实例对象的类型是Student 。
construct可接收的参数:
  • target:被运行的目标构造函数(Person);
  • argumentsList:类数组对象 , 参数列表;
  • newTarget:作为新创建对象原型对象的constructor属性(Student);
function Person(name, age) {this.name = namethis.age = age}function Student() {}const stu = Reflect.construct(Person, ['curry', 30], Student)console.log(stu)console.log(stu.__proto__ === Student.prototype)打印结果:实例对象的类型为Student , 并且实例对象原型指向Student构造函数的原型 。
由浅入深,带你用JavaScript实现响应式原理

文章插图
 
Reflect的construct方法就可以用于类继承的实现 , 可在babel工具中查看ES6转ES5后的代码 , 就是使用的Reflect的construct方法:
由浅入深,带你用JavaScript实现响应式原理

文章插图
 
4.receiver的作用
在介绍Proxy的set和get捕获器的时候 , 其中有个参数叫receiver , 具体什么是调用的代理对象呢?它的作用是什么?
如果原对象(需要被代理的对象)它有自己的getter和setter服务器属性时 , 那么就可以通过receiver来改变里面的this 。
// 假设obj的age为私有属性 , 需要通过getter和setter来访问和设置const obj = {name: 'curry',_age: 30,get age() {return this._age},set age(newValue) {this._age = newValue}}const objProxy = new Proxy(obj, {get: function(target, key, reveiver) {console.log(`obj对象的${key}属性被访问啦!`)return Reflect.get(target, key)},set: function(target, key, newValue, reveiver) {console.log(`obj对象的${key}属性被设置啦!`)Reflect.set(target, key, newValue)}})// 设置:objProxy.name = 'kobe'objProxy.age = 24// 访问:console.log(objProxy.name)console.log(objProxy.age)在没有使用receiver的情况下的打印结果为:name和age属性都被访问一次和设置一次 。
由浅入深,带你用JavaScript实现响应式原理

文章插图
 
但是由于原对象obj中对age进行了拦截操作 , 我们看一下age具体的访问步骤: