美文网首页
阮一峰ES6教程读书笔记(十三)Reflect对象

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

作者: 前端艾希 | 来源:发表于2019-10-27 15:19 被阅读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

    相关文章

      网友评论

          本文标题:阮一峰ES6教程读书笔记(十三)Reflect对象

          本文链接:https://www.haomeiwen.com/subject/xkzpvctx.html