es6-Reflect

116 阅读3分钟

Reflect对象的设计目的

  1. Reflect对象上可以拿到语言内部的方法(现在Object也能,但是之后Reflect只有才能拿到)
  2. 比Object的写法更规范
  3. 让Object操作都变成函数行为
  4. Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。

Reflect的13个静态方法

Reflect.apply(target, thisArg, args)
Reflect.construct(target, args)
Reflect.get(target, name, receiver)
Reflect.set(target, name, value, receiver)
Reflect.defineProperty(target, name, desc)
Reflect.deleteProperty(target, name)
Reflect.has(target, name)
Reflect.ownKeys(target)
Reflect.isExtensible(target)
Reflect.preventExtensions(target)
Reflect.getOwnPropertyDescriptor(target, name)
Reflect.getPrototypeOf(target)
Reflect.setPrototypeOf(target, prototype)

// 以上 方法 obj(第一个参数不是对象 会报错)
var myObject = {
  foo: 1,
  bar: 2,
  get baz() {
    return this.foo + this.bar;
  }
}

var myReceiverObject = {
  foo: 4,
  bar: 4,
};
  1. Reflect.get(obj, name, receiver)
Reflect.get(myObject, 'foo') // 1
Reflect.get(myObject, 'bar') // 2
Reflect.get(myObject, 'baz') // 3

Reflect.get(myObject, 'san') // undefined---不存在返回 undefined

Reflect.get(myObject, 'baz', myReceiverObject) // 8 --- name 有 get 属性 读取函数的this绑定receiver
Reflect.get(myObject, 'bar', myReceiverObject) // 2 --- name 无 get 属性 读取函数this绑定的仍旧是obj

Reflect.get(1, 'foo') // obj 不是对象会报错
Reflect.get(false, 'foo') // obj 不是对象会报错
  1. Reflect.set(obj, name, value, receiver)
Reflect.set(myObject, 'foo', 2) // true --- 返回true 原来有该属性 修改成功
Reflect.set(myObject, 'san', 2) // true --- 返回true 原来无该属性 新增成功

Reflect.set(1, 'foo', {}) // obj 不是对象会报错
Reflect.set(false, 'foo', {}) // obj 不是对象会报错

// name 有 set 属性 读取函数this绑定的是 receiver
var myObject = {
  foo: 4,
  set bar(value) {
    return this.foo = value;
  },
};
var myReceiverObject = {
  foo: 0,
};
Reflect.set(myObject, 'bar', 1, myReceiverObject);
myObject.foo // 4
myObject.bar // undefined
myReceiverObject.foo // 1
myReceiverObject.bar // undefined

// Proxy对象和 Reflect对象联合使用===需要捋捋
  1. Reflect.has(obj, name) 对应 name in obj 的运算
'foo' in myObject // true 旧写法
Reflect.has(myObject, 'foo') // true 新写法
  1. Reflect.deleteProperty(obj, name) 对应 delete obj[name]
delete myObject.foo // true 旧写法
Reflect.deleteProperty(myObject, 'foo') // true 新写法
  1. Reflect.construct(Obj, args) 对应 new Obj(...args)
function Person(name) {
  this.name = name
}
let ming = new Person('xiaoming') // new 的写法
let hong = Reflect.construct(Person, ['xiaoming']) // 新写法
  1. Reflect.getPrototypeOf(obj) 对应 Object.getPrototypeOf(obj)
Reflect.getPrototypeOf(ming) === Object.getPrototypeOf(ming) === Reflect.getPrototypeOf(hong) // true
  1. Reflect.setPrototypeOf(obj, newProto) 对应 Object.setPrototypeOf(obj, newProto)
    obj 是 undefined或null,均报错。 obj 是 不是对象,Reflect 报错,Object 返回 obj值
const myObj = {};
Object.setPrototypeOf(myObj, Array.prototype); // 旧写法
Reflect.setPrototypeOf(myObj, Array.prototype);  // 返回 true(成功)/false(失败)  新写法
myObj.length // 0
  1. Reflect.apply(func, thisArg, args) 对应 Function.prototype.apply.call(func, thisArg, args)fn.apply(thisArg, args)
let name = 1 // 判断name是什么类型
Object.prototype.toString.call(name) // 旧写法
Reflect.apply(Object.prototype.toString, name, []) // 新写法 没有参数 args要写成[]
  1. Reflect.defineProperty(target, propertyKey, attributes) 对应 Object.defineProperty(target, propertyKey, attributes)
function myData() {}
Object.defineProperty(myData, 'now', { value: () => Date.now() })
Reflect.defineProperty(myData, 'now', { value: () => Date.now() })

//  这个方法可以与Proxy.defineProperty配合使用。 === 需要捋捋
const p = new Proxy({}, {
  defineProperty(target, prop, descriptor) {
    console.log(descriptor);
    return Reflect.defineProperty(target, prop, descriptor);
  }
});
p.foo = 'bar';
// {value: "bar", writable: true, enumerable: true, configurable: true}
p.foo // "bar"
  1. Reflect.getOwnPropertyDescriptor(target, propertyKey) 对应 Object.getOwnPropertyDescriptor
var myObject = {};
Object.defineProperty(myObject, 'hidden', {
  value: true,
  enumerable: false,
});
Object.getOwnPropertyDescriptor(myObject, 'hidden'); // 旧写法
Reflect.getOwnPropertyDescriptor(myObject, 'hidden'); // 新写法
  1. Reflect.isExtensible (target) 对应 Object.isExtensible 是否可扩展, 返回布尔值
const myObject = {};
Object.isExtensible(myObject) // true 旧写法
Reflect.isExtensible(myObject) // true 新写法
  1. Reflect.preventExtensions (target) 对应 Object.preventExtensions 让一个对象变为不可扩展
var myObject = {};
Object.preventExtensions(myObject) // Object {} 旧写法
Reflect.preventExtensions(myObject) // true 新写法
  1. Reflect.ownKeys方法用于返回对象的所有属性,基本等同于Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和。
var myObject = {
  foo: 1,
  bar: 2,
  [Symbol.for('baz')]: 3,
  [Symbol.for('bing')]: 4,
};
// 旧写法
Object.getOwnPropertyNames(myObject) // ['foo', 'bar']
Object.getOwnPropertySymbols(myObject) //[Symbol(baz), Symbol(bing)]
Reflect.ownKeys(myObject) // ['foo', 'bar', Symbol(baz), Symbol(bing)] 新写法