ES6和ES5语法区别(Reflect对象和Object对象 )

概述

Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。

现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。

//ES5写法
try{
 Object.defineProperty(target,property,attributes);
   //success
} catch(e){
  //failure
}

//ES6写法
if(Reflect.defineProperty(target,property,attributes)){
  //success
}else{
  //failure
}

//ES5写法
Function.prototype.apply.call(Math.floor,undefined,[1.75]) //1

//ES6写法
Reflect.apply(Math.floor,undefined,[1.75]) //1

Reflect.get(target, name, receiver)

Reflect.get方法查找并返回target对象的name属性,如果没有该属性,则返回undefined。

var myObject = {
   foo:1,
   bar:2,
   get baz(){
      return this.foo + this.bar
   }
 }

Reflect.get(myObject,'foo') //1
Reflect.get(myObject,'bar') //2
Reflect.get(myObject,'baz') //3

如果name属性部署了读取函数(getter),则读取函数的this绑定receiver。

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

第一个参数不是对象,Reflect.get方法会报错。

Reflect.get(1, 'foo') // 报错
Reflect.get(false, 'foo') // 报错

Reflect.set(target, name, value, receiver)

Reflect.set方法设置target对象的name属性等于value值。

var myObject = {
   foo:1,
   set bar(value){
      return this.foo = value;
   }
}

myObject.foo //1

Reflect.set(myObject,'foo',2);
myObject.foo //2

Reflect.set(myObject,'bar',3);
myObject.foo //3

如果name属性设置了赋值函数,则赋值函数的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
myReceiverObject.foo // 1

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

Reflect.set(1, 'foo', {}) // 报错
Reflect.set(false, 'foo', {}) // 报错

Reflect.has(obj, name)

Reflect.has方法对应name in obj里面的in运算符。

var myObject = {
   foo:1,
}

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

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

Reflect.construct(target,args)

Reflect.construct方法等同于new target(…args),这提供了一种不使用new,来调用构造函数的方法。

function Greeting(name){
   this.name = name;
}

//new的写法
const instance = new Greeting('阿蔡');

//Reflect.construct写法
const instance = Reflect.construct(Greeting,['阿蔡']);

Reflect.getPrototypeOf(obj)

Reflect.getPrototypeOf方法用于读取对象的_proto_属性,对应Object.getPrototypeOf(obj)。

const myObj = new FancyThing();

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

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

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

Object.getPrototypeOf(1) // Number {[[PrimitiveValue]]: 0}
Reflect.getPrototypeOf(1) // 报错

Reflect.setPrototypeOf(obj, newProto)

Reflect.setPrototypeOf方法用于设置对象的_proto_属性,返回第一个参数对象,对应Object.setPrototypeOf(obj, newProto)。

const myObj = new FancyThing();

//ES5写法
Object.setPrototypeOf(myObj,OtherThing.prototyype);

//ES6写法
Reflect.setPrototypeOf(myObj,OtherThing.prototyype);

如果第一个参数不是对象,Object.setPrototypeOf会返回第一个参数本身,而Reflect.setPrototypeOf会报错。

Object.setPrototypeOf(1, {})
// 1

Reflect.setPrototypeOf(1, {})
// TypeError: Reflect.setPrototypeOf called on non-object

如果第一个参数是undefined或null,Object.setPrototypeOf和Reflect.setPrototypeOf都会报错。

Object.setPrototypeOf(null, {})
// TypeError: Object.setPrototypeOf called on null or undefined

Reflect.setPrototypeOf(null, {})
// TypeError: Reflect.setPrototypeOf called on non-object

Reflect.apply(func, thisArg, args)

Reflect.apply方法等同于Function.prototype.apply.call(func, thisArg, args),用于绑定this对象后执行给定函数。

一般来说,如果要绑定一个函数的this对象,可以这样写fn.apply(obj, args),但是如果函数定义了自己的apply方法,就只能写成Function.prototype.apply.call(fn, obj, args),采用Reflect对象可以简化这种操作。

const ages = [11, 33, 12, 54, 18, 96];

// ES5写法
const youngest = Math.min.apply(Math, ages);
const oldest = Math.max.apply(Math, ages);
const type = Object.prototype.toString.call(youngest);

// ES6写法
const youngest = Reflect.apply(Math.min, Math, ages);
const oldest = Reflect.apply(Math.max, Math, ages);
const type = Reflect.apply(Object.prototype.toString, youngest, []);

Reflect.defineProperty(target, propertyKey, attributes)

Reflect.defineProperty方法基本等同于Object.defineProperty,用来为对象定义属性。

function MyDate() {
  /*…*/
}

// ES5写法
Object.defineProperty(MyDate, 'now', {
  value: () => new Date.now()
});

// ES6写法
Reflect.defineProperty(MyDate, 'now', {
  value: () => new Date.now()
});

如果Reflect.defineProperty的第一个参数不是对象,就会抛出错误,比如Reflect.defineProperty(1, ‘foo’)。

Reflect.getOwnPropertyDescriptor(target, propertyKey)

Reflect.getOwnPropertyDescriptor基本等同于Object.getOwnPropertyDescriptor,用于得到指定属性的描述对象。

var myObject = {};
Object.defineProperty(myObject, 'hidden', {
  value: true,
  enumerable: false,
});

// ES5写法
var theDescriptor = Object.getOwnPropertyDescriptor(myObject, 'hidden');

// ES6写法
var theDescriptor = Reflect.getOwnPropertyDescriptor(myObject, 'hidden');

Reflect.getOwnPropertyDescriptor和Object.getOwnPropertyDescriptor的一个区别是,如果第一个参数不是对象,Object.getOwnPropertyDescriptor(1, ‘foo’)不报错,返回undefined,而Reflect.getOwnPropertyDescriptor(1, ‘foo’)会抛出错误,表示参数非法。

Reflect.isExtensible (target)

Reflect.isExtensible方法对应Object.isExtensible,返回一个布尔值,表示当前对象是否可扩展。

const myObject = {};

// ES5写法
Object.isExtensible(myObject) // true

// ES6写法
Reflect.isExtensible(myObject) // true

如果参数不是对象,Object.isExtensible会返回false,因为非对象本来就是不可扩展的,而Reflect.isExtensible会报错。

Object.isExtensible(1) // false
Reflect.isExtensible(1) // 报错

Reflect.preventExtensions(target)

Reflect.preventExtensions对应Object.preventExtensions方法,用于让一个对象变为不可扩展。它返回一个布尔值,表示是否操作成功。

var myObjet = {};

//ES5写法
Object.isExtensible(myObject) //true

//ES6写法
Reflect.preventExtensions(1) //true

如果参数不是对象,Object.isExtensible在 ES5 环境报错,在 ES6 环境返回这个参数,而Reflect.preventExtensions会报错。

// ES5
Object.preventExtensions(1) // 报错

// ES6
Object.preventExtensions(1) // 1

// 新写法
Reflect.preventExtensions(1) // 报错

Reflect.ownKeys (target)

Reflect.ownKeys方法用于返回对象的所有属性,基本等同于Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和。

var myObject = {
  foo:1,
  bar:2,
  [Symbol.for('baz')]:3,
  [Symbol.for('bing')]:4
};

//ES5写法
Object.getOwnPropertyNames(myObject)  //['foo', 'bar']

Object.getOwnPropertySymbols(myObject)
//[Symbol.for('baz'), Symbol.for('bing')]

// ES6写法
Reflect.ownKeys(myObject)
// ['foo', 'bar', Symbol.for('baz'), Symbol.for('bing')]

猜你喜欢

转载自blog.csdn.net/qq_35036255/article/details/80942572