ES6:Reflect

163 阅读3分钟

一、Reflect是什么

Reflect是ES6提供的一个内置对象,Reflect的所有属性/方法都是静态的,共有13个静态方法,使用起来和Math一样

      console.log(Reflect) // Reflect {defineProperty: ƒ, deleteProperty: ƒ, apply: ƒ, construct: ƒ, get: ƒ, …}
      console.log(Object.prototype.toString.call(Reflect)) // [object Reflect]

二、Reflect.apply()

1、语法

      Reflect.apply(target, thisArgument, argumentList)

2、可以替代函数原型上的apply方法,但是使用时有些区别:

      const obj = {
        age: 18
      }

      function fn(a, b, c) {
        return this.age + a + b + c
      }

      console.log(fn.apply(obj, [1, 2, 3])) // 24 老写法
      console.log(Reflect.apply(fn, obj, [1, 2, 3])) // 24 新写法

三、Reflect.construct

1、语法

      Reflect.construct(target, argumentList)

2、可以替代new target(...args),使用时有些区别:

      function Person(name, age) {
        this.name = name
        this.age = age
      }

      const p1 = new Person('张三', 18)
      const p2 = Reflect.construct(Person, ['张三', 18])

      console.log(p1) // Person {name: '张三', age: 18}
      console.log(p2) // Person {name: '张三', age: 18}

四、Reflect.get

1、语法

  1. target:必传,且必须是一个对象
  2. propertyKey:对象属性名
  3. receiver:Reflect.get的真正用途,在调用对象中的getter方法时,改变其中this的指向
      Reflect.get(target, propertyKey, receiver)

2、只传前2个参数时,和obj.语法获取属性值没有区别

      const obj = {
        name: '张三',
        age: 18,
        get info() {
          return `${this.name},${this.age}`
        },
        undefined: 1
      }

      console.log(obj.name) // 张三
      console.log(obj.age) // 18
      console.log(obj.info) // 张三,18
      console.log(obj.a) // undefined
      console.log(Reflect.get(obj, 'name')) // 张三
      console.log(Reflect.get(obj, 'age')) // 18
      console.log(Reflect.get(obj, 'info')) // 张三,18
      console.log(Reflect.get(obj, 'a')) // undefined
      console.log(Reflect.get(obj)) // 1 第二个参数是undefined

3、传入receiver参数

      console.log(Reflect.get(obj, 'info')) // 张三,18

      const xiaoming = {
        name: '小明',
        age: 10
      }
      console.log(Reflect.get(obj, 'info', xiaoming)) // 小明,10 obj中getter方法中的this被指向到xiaoming

五、Reflect.set

1、语法

  1. target:必传,且必须是一个对象
  2. propertyKey:对象属性名
  3. value:对象属性值
  4. receiver:Reflect.set的真正用途,在调用对象中的setter方法时,改变其中this的指向
      Reflect.set(target, propertyKey, value, receiver)

2、只传前3个参数,和使用obj.xx = 'xxx'赋值属性没有区别

      const obj = {
        name: '张三',
        age: 18,
        set setInfo({ name, age }) {
          this.name = name
          this.age = age
        }
      }
      console.log(obj) // {name: '张三', age: 18}
      Reflect.set(obj, 'setInfo', { name: 'xxx', age: 10 })
      console.log(obj) // {name: 'xxx', age: 10}

3、传入receiver参数

当传递了receiver时,setter中的this便指向receiver,所以是xiaoming这个对象借用了obj中的setInfo方法,改变了xiaoming自己,对obj没有影响

      const xiaoming = {
        name: '小明'
      }
      Reflect.set(obj, 'setInfo', { name: '大明', age: 10 }, xiaoming) 
      console.log(obj) // {name: '张三', age: 18}
      console.log(xiaoming) // {name: '大明', age: 10}

六、Reflect.defineProperty()

Object.defineProperty返回修改后的对象,Reflect.defineProperty返回布尔值

Object.defineProperty定义失败拦截:

      try {
        Object.defineProperty(obj, 'age', { value: 19 })
      } catch (e) {
        
      }

Reflect.defineProperty可以使用if语句:

      if (Reflect.defineProperty(obj, 'age', { value: 19 })) {

      } else {
        
      }

七、Reflect.getOwnPropertyDescriptor()

八、Reflect.getPrototypeOf()

九、Reflect.setPrototypeOf()

十、Reflect.isExtensible()

十一、Reflect.preventExtensions()

十二、Reflect.ownKeys()

Reflect.ownKeys = Object.getOwnPropertyNames + Object.getOwnPropertySymbols

      const s = Symbol()
      const obj = {
        name: '小明',
        0: 0,
        '-1': -1,
        [s]: Symbol(),
        100: 100,
        50: 50
      }
      obj.__proto__.a = 'a'
      Object.defineProperty(obj, 'age', { value: 18 })

      const arr1 = Object.getOwnPropertyNames(obj)
      const arr2 = Object.getOwnPropertySymbols(obj)
      const arr3 = Reflect.ownKeys(obj)

      console.log(arr1) // ['0', '50', '100', 'name', '-1', 'age']
      console.log(arr2) // [Symbol()]
      console.log(arr3) // ['0', '50', '100', 'name', '-1', 'age', Symbol()]

参考:Object.getOwnPropertyNames()

十三、Reflect.has()

1、语法

Reflect.has(target, propertyKey) // target必须是一个对象

2、作用和in操作符一样

      const person = {
        name: '小明'
      }
      person.__proto__.a = 'a'
      console.log('name' in person) // true
      console.log('toString' in person) // true
      console.log('a' in person) // true

      console.log(Reflect.has(person, 'name')) // true
      console.log(Reflect.has(person, 'toString')) // true
      console.log(Reflect.has(person, 'a')) // true

十四、Reflect.deleteProperty()

1、语法

Reflect.deleteProperty(target, propertyKey)

2、作用和delete操作符一样

      const obj = {
        name: '张三',
        age: 18
      }
      Reflect.defineProperty(obj, 'gender', {
        value: '男'
      })
      console.log(obj) // {name: '张三', age: 18, gender: '男'}
      console.log(delete obj.name) // true
      console.log(obj) // {age: 18, gender: '男'}
      console.log(delete obj['age']) // true
      console.log(obj) // {gender: '男'}
      console.log(delete obj['gender']) // false 删除不可删除属性时返回false
      console.log(obj) // {gender: '男'}

将delete替换为新语法,结果一样:

      console.log(obj) // {name: '张三', age: 18, gender: '男'}
      console.log(Reflect.deleteProperty(obj, 'name')) // true
      console.log(obj) // {age: 18, gender: '男'}
      console.log(Reflect.deleteProperty(obj, 'age')) // true
      console.log(obj) // {gender: '男'}
      console.log(Reflect.deleteProperty(obj, 'gender')) // false 删除不可删除属性时返回false
      console.log(obj) // {gender: '男'}