Reflect和Object的异同

87 阅读3分钟

Reflect就是继承了Object的某些内置方法,并且提供了优化

Reflect拥有Object对象的一些内部方法,某些方法会同时在Object对象和Reflect对象上部署,也就是说Object对象上存在的方法,通过Reflect也可以访问到。

Object对象上的某些方法会有些缺陷,例如:在Object.defineProperty上对一个不可写或不可枚举的属性进行getter或setter时会抛出错误,对于这个错误,我们需要try catch去捕获,而Reflect.defineProperty则会抛出false来表示本次操作失败(Reflect对对象的操作都会抛出true和false来表示是否操作成功)。

异常

抛出错误

const obj = { name : '东方不败' }
Object.defineProperty(obj,'age',{
    value : 100,
    writable : true,  // 只读
    configurable : false  // 不可删除和修改
})

Object.defineProperty(obj,'age',{
    get(){ return 200 }
})
console.log(obj.age); //  TypeError : Cannot redefine property: age
// 报错,不能重新定义属性

返回false

const obj2 = { name : '西方求败' }
Object.defineProperty(obj2,'age',{
    value : 100,
    writable : true,  // 只读
    configurable : false  // 不可删除和修改
})

let status = Reflect.defineProperty(obj2,'age',{
    get(){ return 200}
})

console.log(status); //  false
console.log(obj2.age); // 100
// Reflect会抛出false表示此次操作失败

操作

Object的部分操作是命令式的

let obj3 = {
    name : '东方不败',
    age : 100
}

console.log('name' in obj3);  // true
console.log(delete obj3.age);  // true
console.log(obj3);  // {name: '东方不败'}

Reflect的操作是函数式的

let obj4 = {
    name : '西方求败',
    age : 100
}

console.log(Reflect.has(obj4,'name'));  // true
console.log(Reflect.deleteProperty(obj4,'age')); // true
console.log(obj4);  // {name: '西方求败'}

Reflect对象13个静态方法

Reflect.get(target,name,receiver)

1、target :目标对象。2、name:对象属性。3、receiver: 代理对象(可忽略)

let o = {
    name : '东方',
    text : '不败'
}
console.log(Reflect.get(o,'name'));  // 东方
Reflect.set(target, name, value, receiver)

用于设置target对象的name属性等于value,如果修改成功返回true,失败返回false

  let o2 = {
    name : '艺术概论',
  }
  let back = Reflect.set(o2,'price',100)
  console.log(back); // true
  console.log(o2);  // {name: '艺术概论', price: 100}
Reflect.has(obj, name)

相当于Object里的in运算符,判断当前属性在目标对象内是否存在,true存在,false不存在

let o3 = {
    name : '中国工艺美术史'
}

console.log('name' in o3);  // true
console.log(Reflect.has(o3,'name')); // true
Reflect.deleteProperty(obj, name)

相当于Object的删除操作:delete obj.name,用于删除对象的属性

let o4 = {
    book : '疾风劲草',
    text : '一臂之力'
}
// Object
delete o4.book
console.log(o4);  // {text: '一臂之力'}
// Reflect
Reflect.deleteProperty(o4,'text')
console.log(o4);  // {}
Reflect.construct(target, args)

相当于new class(params),这里的Reflect可以不用new来创建调用构造函数的方法

function Person(name){
    this.name = name
}
// new 写法
let onNew = new Person('东方')
// Reflect.construct
let onNew2 = Reflect.construct(Person,['不败'])
Reflect.getPrototypeOf(obj)

对应Object.getPrototypeOf(obj),用于读取对象的__proto__属性

let o5 = new String()

// Object.getPrototypeOf()
console.log(Object.getPrototypeOf(o5) == String.prototype); // true

// Reflect.getPrototypeOf()
console.log(Reflect.getPrototypeOf(o5) == String.prototype); // true
Reflect.setPrototypeOf(obj, newProto)

对应Object.setPrototypeOf(obj, newProto),用于设置目标对象的原型(prototype)

let o6 = {}
Reflect.setPrototypeOf(o6,Array.prototype)
console.log(o6.length);  // 0
Reflect.defineProperty(target, propertyKey, attributes)

相当于Object.defineProperty,Reflect.defineProperty()用来定义对象的属性。

let o7 = {
    name : '东方不败'
}

Reflect.defineProperty(o7,'age',{
    value : 100,
    configurable: true,
    enumerable : true,
    writable : true
})
console.log(o7);  // {name: '东方不败', age: 100}
Reflect.getOwnPropertyDescriptor(target, propertyKey)

对应Object.getOwnPropertyDescriptor,用来获得指定属性的描述对象

let o8 = {
    name : '东方不败'
}

Reflect.defineProperty(o8,'age',{
    value : 100,
    configurable: true,
    enumerable : true,
    writable : true
})

let back8 = Reflect.getOwnPropertyDescriptor(o8,'age')
console.log(back8);  // {value: 100, writable: true, enumerable: true, configurable: true}
Reflect.isExtensible (target)

相当于Object.isExtensible,返回布尔值,表示当前对象是否扩展

let o9 = {}
let back9 = Reflect.isExtensible(o9)
console.log(back9);  // true
Reflect.preventExtensions(target)

相当于Object.preventExtensions,可以让目标对象变为不可扩展状态,返回布尔值表示是否设置成功

let b = {}
let info =  Reflect.preventExtensions(b)
console.log(info); // true
console.log(Reflect.isExtensible(b)); // false
Reflect.ownKeys (target)

用于返回目标对象的所有属性,包括Symbol。类似Object.keys()

let address = Symbol.for('武汉')
let b2 = {
    name : '东方不败',
    age : 100,
    [address] : '世界城广场'
}

let info2 = Reflect.ownKeys(b2)
console.log(info2); // ['name', 'age', Symbol(武汉)]
Reflect.apply(func, thisArg, args)

用于绑定this对象后执行给定函数。如果要给行数绑定一个this对象,可以使用apply的方式,但入股函数自己定义了自己的apply方法,就只能写成Function.prototype.apply.call(fn, obj, args)的方法嵌套,而Reflect则可以简化。

 let arr = [1,2,3,4,5,6,7]
 
 // 旧写法
 let a = Math.min.apply( Math, arr)
 let a2 = Math.max.apply( Math, arr)
 let a3 = Object.prototype.toString.call(a)
 console.log(a);   // 1
 console.log(a2);  // 7
 console.log(a3);  // [object Number]

 // 新写法
 let a4 = Reflect.apply( Math.min, Math, arr)
 let a5 = Reflect.apply( Math.max, Math, arr)
 let a6 = Reflect.apply( Object.prototype.toString, a4, [])
 console.log(a4);  // 1
 console.log(a5);  // 7
 console.log(a6);  // [object Number]