ES6笔记( 十一 )- Reflect & Proxy

目录:

  1. Reflect
    • 反射的用途
    • Reflect常用方法
  2. 【 扩展 】Property Descriptor
    • 属性描述符简介和基本特性
    • 属性描述符的存取器属性( getter, setter )
    • 属性描述符的最佳实践
    • 存取器的意义
  3. Proxy
    • Proxy的使用
  4. 【 扩展 】观察者模式
  5. 【 扩展 】代理模式

Reflect

Reflect是一个内置的JS对象, 它提供了一系列方法, 可以让开发者通过调用这些方法, 访问JS的一些底层功能

由于他类似于其他语言的反射, 因此取名Reflect

反射的用途

使用Reflect可以实现诸如属性的取值和赋值, 调用普通函数, 调用构造函数, 判断对象是否包含某个属性等一切Object对象可以做的事儿他都可以做到

可能有的同学朋友就会问: 这些方法不是已经在Object中有了吗, ES6为什么还要用Reflect实现一次

因为ES官方认为JS应该减少魔法, 让代码更纯粹, 要提供给开发者直接操作底层的接口, 这些在Object中可给不了你, 而在Reflect中可以给你


// ES5的instanceof

// 这种语法你看的明白嘛? 这就是魔法, instanceof功能实现了你都不知道人家怎么做的
console.log( {
   }  instanceof Object ); 

ES6认为对属性内存的控制, 或者原型链的修改等等这些都是一种魔法, 底层帮你封装好了一切, 才让你有了这种语法, 因此ES6认为要减少这种魔法, 所以就将这些操作全部提取出来, 形成一个正常的api, 并高度聚合到一个对象之中, 于是就早就了Reflect对象, 比如

const obj = {
   
    a: 10
}

obj.a = 20; // 这样就赋值了, 这就是一种魔法, 你可能觉得不可思议, 但是底层写的其实是这样

Reflect.set(obj, 'a', 20);  // 你写了obj.a = 20, 实际上底层走的是一个set方法, 而你写的obj.a=20只是一个语法糖, 仅此而已

相信我上面已经说得比较清楚了, 你认为obj.a = 20是一个语法, 但充其量人家是一个语法糖, 底层人家依然是使用set的调用进行修改的, ES6认为这种语法糖太多了显得JS不够纯粹, 所以他决定把真正的底层方法展示出来聚合到Reflect对象中, 这就是Reflect的目的和原因

Reflect不是为了解决某些问题存在的, 他是为了迎合函数式编程的思想而存在的, 他不是必须的, 但是代表ES官方的一种期望

Reflect上的可能会用到的方法

  • Reflect.set( obj, prop, value ): 给某个对象的某个属性赋值

    const obj = {
         
        a: 10,
        b: 20
    }
    
    Reflect.set( obj, 'a', 100 );
    
    console.log(obj.a); // 100
    
  • Reflect.get( obj, prop ): 访问某个对象的某个属性值

    const obj = {
         
        a: 10,
        b: 20
    }
    
    console.log(Reflect.get( obj, 'a' )); // 10
    
  • Reflect.apply( func, thisArg, argList ): 修改函数的this指向

    function foo() {
         
        console.log(this.a);
    }
    
    const obj = {
         
        a: 10
    }
    
    Reflect.apply( foo, obj, null ); // 输出10
    
  • Reflect.construct( constructor, args ): 使用参数1的构造函数和参数2的参数集合返回一个构造函数的对象 ( ES6他认为new关键字都是魔法 )

    function Person( name, age ) {
         
        this.name = name;
        this.age = age;
    }
    
    const person1 = new Person('thor', 19); // ES6觉得这是魔法, 你可以继续选择用魔法, 也可以选择下面更加纯粹的底层
    const person2 = Relect.construct( Person, ['loki', 18] );
    
    console.log(person1); // { name: 'thor', age: 19 }
    console.log(person2); // { name: 'loki', age 18 }
    
  • 阿西吧, 不想写了, 基本上就是和Object上的方法名和功能一模一样, 而他们的区别笔者也说过了, 就连obj.xxx = xxxES6都认为是一种魔法, 因为真正是他调用了一个set函数去访问了底层的内存, 所以才有了Reflect.set, 也有了这么多Reflect的api, 如果你想深刻了解Reflect的api, 可以访问下面的网址

    Reflect API

【 回顾 】Property Descriptor

属性描述符简介和基本属性

属性描述符, 用于描述一个属性的相关信息

通过Object.getOwnPropertyDescriptor( 对象, 属性名 )可以得到某个对象的某个属性的属性描述符

const obj = {
   
    a: 1,
    b: 2
}

const descriptor = Object.getOwnPropertyDescriptor( obj, "a" );
console.log( descriptor );

在这里插入图片描述

从上面可以得知, 我们的属性描述符对象中有四个属性:

  • value: 属性值
  • configurable: 属性描述符对象中的属性的配置值是否是可以修改的
  • enumerable: 属性描述符对象描述的该属性是否是可以被枚举到的
  • writeable: 属性描述符对象描述的该属性是否是可以被修改的

如果在进行对象属性的修改和添加的时候需要配置其属性描述符, 可以使用Object.defineProperty( 对象, 属性, 属性描述符 )

  • 修改value

    修改value会直接影响到对象该属性对应的value值

    const obj = {
         
        a: 10,
        b: 20
    }
    
    
    Object.defineProperty(obj, 'a', {
         
        value: 3,
    })
    
    
    console.log(obj.a); // 输出3
    
  • 修改configurable

    修改configurable会导致后续再使用Object.defineProperty出错( 因为该属性已经变成不可配置的了, 除非你把设置configurable为false的那一行代码删掉 )

    const obj = {
         
        a: 10,
        b: 20
    }
    
    
    Object.defineProperty(obj, 'a', {
         
        configurable: false
    })
    
    
    Object.defineProperty(obj, 'a', {
         
        value: 3,
        configurable: true
    })
    

    在这里插入图片描述

  • 修改enumerable

    修改enumerable会导致属性不再能够被遍历找到

    const obj = {
         
        a: 10,
        b:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值