ES6精通之Reflect个人笔记

2019-12-19 Reflect

目录

  • Reflect 的简介和特点
  • Reflect 的静态方法
    • get()
    • set()
    • apply()
    • has()
    • construct()
    • deleteProperty()
    • defineProperty()
    • getOwnPropertyDescriptor()
    • getPrototypeOf()
    • isExtensible()
    • ownKeys()
    • preventExtensions()
    • setPrototypeOf()

Reflect 的简介和特点

设计目的:

(1)从Reflect对象上可以拿到语言内部的方法

(2)修改某些Object方法的返回结果,让其变得更合理。(Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。)

(3)让Object操作都变成函数行为(比如name in obj和delete obj[name])

(4)Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。

Reflect 的静态方法

Reflect.get(target, name, receiver)
  1. 作用:Reflect.get方法查找并返回target对象的name属性,如果没有该属性,则返回undefined
  2. 接收参数:目标对象,属性名,receiver(修改getter函数的this指向)
  3. 写法:
var myObject = {
  foo: 1,
  bar: 2,
  get baz() {
    return this.foo + this.bar;
  },
};

var myReceiverObject = {
  foo: 4,
  bar: 4,
};

Reflect.get(myObject, 'baz', myReceiverObject) // 8

4.注意
如果第一个参数不是对象,Reflect.get方法会报错

Reflect.set(target, name, value, receiver)
  1. 作用:拦截某个属性的赋值操作
  2. 接收参数: 目标对象,属性名,属性值,receiver(修改setter函数的this绑定)
  3. 写法
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
  1. 注意
    (1)如果 Proxy对象和 Reflect对象联合使用,前者拦截赋值操作,后者完成赋值的默认行为,而且传入了receiver,那么Reflect.set会触发Proxy.defineProperty拦截。不传不会触发,如果Proxy中同时有set和defineProperty,则set的优先级高于defineProperty
let p = {
  a: 'a'
};

let handler = {
  set(target, key, value, receiver) {
    console.log('set');
    Reflect.set(target, key, value, receiver)
  },
  defineProperty(target, key, attribute) {
    console.log('defineProperty');
    Reflect.defineProperty(target, key, attribute);
  }
};

let obj = new Proxy(p, handler);
obj.a = 'A';
// set
// defineProperty

(2)如果第一个参数不是对象,Reflect.set会报错。

Reflect.has(obj, name)
  1. 作用:Reflect.has方法对应name in obj里面的in运算符。
  2. 接收参数: 目标对象,要查询的属性
  3. 写法
var myObject = {
  foo: 1,
};

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

// 新写法
Reflect.has(myObject, 'foo') // true
Reflect.deleteProperty(obj, name)
  1. 作用:Reflect.deleteProperty方法等同于delete obj[name],用于删除对象的属性。
  2. 接收参数: 目标对象,要删除的属性
  3. 写法
var myObject = {
  foo: 1,
};

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

// 新写法
Reflect.has(myObject, 'foo') // true
Reflect.construct(obj, args)
  1. 作用:Reflect.Reflect.construct方法等同于new target(…args),这提供了一种不使用new,来调用构造函数的方法。
  2. 接收参数: 目标对象,函数参数
  3. 写法
function Greeting(name) {
  this.name = name;
}

// new 的写法
const instance = new Greeting('张三');

// Reflect.construct 的写法
const instance = Reflect.construct(Greeting, ['张三']);

4.注意:如果第一个参数不是函数则报错

Reflect.getPrototypeOf(obj)
  1. 作用:Reflect.getPrototypeOf方法用于读取对象的__proto__属性,对应Object.getPrototypeOf(obj)。
  2. 接收参数: 目标对象
  3. 写法
const myObj = new FancyThing();

// 旧写法
Object.getPrototypeOf(myObj) === FancyThing.prototype;

// 新写法
Reflect.getPrototypeOf(myObj) === FancyThing.prototype;

4.注意
Reflect.getPrototypeOf和Object.getPrototypeOf的一个区别是,如果参数不是对象,Object.getPrototypeOf会将这个参数转为对象,然后再运行,而Reflect.getPrototypeOf会报错。

Object.getPrototypeOf(1) // Number {[[PrimitiveValue]]: 0}
Reflect.getPrototypeOf(1) // 报错
Reflect.setPrototypeOf(obj, newProto)
  1. 作用:Reflect.setPrototypeOf方法用于设置目标对象的原型(prototype),对应Object.setPrototypeOf(obj,newProto)方法。它返回一个布尔值,表示是否设置成功。
  2. 接收参数: 目标对象,要设置的新原型
  3. 写法
const myObj = {};

// 旧写法
Object.setPrototypeOf(myObj, Array.prototype);

// 新写法
Reflect.setPrototypeOf(myObj, Array.prototype);

myObj.length // 0

4.注意
(1)如果第一个参数不是对象,Object.setPrototypeOf会返回第一个参数本身,而Reflect.setPrototypeOf会报错。
(2)如果第一个参数是undefined或null,Object.setPrototypeOf和Reflect.setPrototypeOf都会报错

Reflect.apply(func, thisArg, args)
  1. 作用:Reflect.deleteProperty方法等同于delete obj[name],用于删除对象的属性。
  2. 接收参数: 目标对象,要删除的属性
  3. 写法
var myObject = {
  foo: 1,
};

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

// 新写法
Reflect.has(myObject, 'foo') // true
Reflect.apply(func, thisArg, args)
  1. 作用:Reflect.deleteProperty方法等同于delete obj[name],用于删除对象的属性。
  2. 接收参数: 目标对象,要删除的属性
  3. 写法
var myObject = {
  foo: 1,
};

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

// 新写法
Reflect.has(myObject, 'foo') // true
Reflect.defineProperty(target, propertyKey, attributes)
  1. 作用:Reflect.deleteProperty方法等同于delete obj[name],用于删除对象的属性。
  2. 接收参数: 目标对象,要删除的属性
  3. 写法
var myObject = {
  foo: 1,
};

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

// 新写法
Reflect.has(myObject, 'foo') // true
Reflect.getOwnPropertyDescriptor(target, propertyKey)
  1. 作用:Reflect.deleteProperty方法等同于delete obj[name],用于删除对象的属性。
  2. 接收参数: 目标对象,要删除的属性
  3. 写法
var myObject = {
  foo: 1,
};

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

// 新写法
Reflect.has(myObject, 'foo') // true
Reflect.isExtensible (target)
  1. 作用:Reflect.deleteProperty方法等同于delete obj[name],用于删除对象的属性。
  2. 接收参数: 目标对象,要删除的属性
  3. 写法
var myObject = {
  foo: 1,
};

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

// 新写法
Reflect.has(myObject, 'foo') // true
Reflect.preventExtensions(target)
  1. 作用:Reflect.deleteProperty方法等同于delete obj[name],用于删除对象的属性。
  2. 接收参数: 目标对象,要删除的属性
  3. 写法
var myObject = {
  foo: 1,
};

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

// 新写法
Reflect.has(myObject, 'foo') // true
Reflect.ownKeys (target)
  1. 作用:Reflect.deleteProperty方法等同于delete obj[name],用于删除对象的属性。
  2. 接收参数: 目标对象,要删除的属性
  3. 写法
var myObject = {
  foo: 1,
};

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

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

参考文献
阮一峰官网(ES6 Promise对象)

你可能感兴趣的:(ES6)