阮一峰ES6教程读书笔记(十三)Reflect对象

2019-10-27  本文已影响0人  前端艾希

Reflect对象

About

随着学习的深入,我逐渐对JavaScript有了更宏观的认识,之前在工作中遇到的一些问题也得到了解释,我觉得学习就是这样,从微观到宏观,总有一天我吃透Javascript的架构,请继续加油!

1. Reflect概述

Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。针对Reflect的设计目的来说,我觉得大概分为四点:

1.1 简化Object对象

从 ES2015 开始,官方有意识的去调整Javascript的架构,使得其结构更加清晰,比如将一些全局方法部署到专门的对象上,又如像Reflect对象一样,将大部分以前属于Object的静态方法移植到Reflect对象上,以后可能Object只承担构造函数的责任,即Object上只有实例方法,将更多的操作对象的方法部署到专门的对象Reflect上。

1.2 改变Object静态方法的行为

之前,Object的静态方法的行为不是很难统一,有的有返回值,有点没有返回值,有的返回一个对象实例,而有的又返回布尔值,很不规范,比如:

var a = {}

Object.setPrototypeOf(a, Array.prototype) // Array {}
Reflect.setPrototypeOf(a, Object.prototype) // true

Object.setPrototypeOf(1, Array.prototype) // 1
Reflect.setPrototypeOf(1, Object.prototype) // Uncaught TypeError

Reflect.setPrototypeOf(Object.freeze(a), Array.prototype) // false

通过上面的代码我们可以发现,Object.setPrototypeOf总是返回第一个参数,我们并不知道操作是成功了还是失败了,是合法的还是非法的;但是Reflect.setPrototypeOf就不一样了,它会返回一个布尔值来告诉你是成功还是失败,我们可以用if...else去进行不同的操作。

1.3 让Objct操作都变成函数式操作

Reflect对象的方法都是函数式操作,即接受参数并有返回值,而Object就不一样了:

var a = {
    name: 'bing'
}

delete a.name // true
Reflect.deleteProperty(a, 'name') //true

变成函数式操作后,编程风格更严谨了

1.4 和Proxy一一对应

Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。

2. 静态方法

Reflect大部分与Object对象的同名方法的作用都是相同的,而且它与Proxy对象的方法是一一对应的。这里只记录几个常见的,更多的方法请参阅原著。

2.1 get(target, name, recevier)

Reflect.get方法查找并返回target对象的name属性,如果没有该属性,则返回undefined

var myObject = {
  foo: 1,
  bar: 2,
  get baz() {
    return this.foo + this.bar;
  },
}

Reflect.get(myObject, 'foo') // 1
Reflect.get(myObject, 'bar') // 2
Reflect.get(myObject, 'baz') // 3

get方法接受的第三个参数receiver是当target对象中被读取的propsetter方法的时候,setterthis可以绑定到reveiver

2.2 set(target, name, value, receiver)

Reflect.set()方法会设置target对象的name属性的值为value,如果name的属性设置了setter,那么setterthis就会绑定至rceivr

var myObject = {
  foo: 4,
  set bar(value) {
    return this.foo = value;
  },
};

var myReceiverObject = {
  foo: 0,
};

Reflect.set(myObject, 'bar', 1, myReceiverObject);
myObject.foo // 4
myReceiverObject.foo // 1

2.3 has(obj, name)

该方法相当于in运算符

var myObject = {
  foo: 1,
};

// 旧写法
'foo' in myObject // true

// 新写法
Reflect.has(myObject, 'foo') // true

2.4 defineProprty(targeet, name, attriDescObj)

Reflect.defineProperty方法基本等同于Object.defineProperty,用来为对象定义属性。未来,后者会被逐渐废除,请从现在开始就使用Reflect.defineProperty代替它。

function MyDate() {
  /*…*/
}

// 旧写法
Object.defineProperty(MyDate, 'now', {
  value: () => Date.now()
});

// 新写法
Reflect.defineProperty(MyDate, 'now', {
  value: () => Date.now()
});

参考链接

作者:阮一峰

链接:http://es6.ruanyifeng.com/#docs/reflect

上一篇 下一篇

猜你喜欢

热点阅读