Reflect反射
es6提供了一个全新的api----Reflect,其将object对象一些内部的方法,放到Reflect对象上,将来可能彻底取代Object对象内部的这些方法,方法的返回值也更改为true或false
new.target
在介绍API之前我们先说一个属性,new.targer指向直接被new执行的构造函数
在函数中使用
在函数中使用new.target,会返回undefined,可以用来判断一个函数是否作为构造函数来使用
(function(){ console.log(new.target) // undefined }())
在构造函数中使用
构造函数中的new.target,会指向被new执行的构造函数,如下所示
class A{ constructor(){ console.log(new.target) // [class A] console.log(new.target.name) // A } } class B extends A{ constructor(){ super() // [class B extends A] // B } }
API
下面我们介绍一下Reflect的API
Reflect.construct(c, args, 可选newTarget)
当传两个参数时,类似new运算符,返回一个实例对象,第一个参数为构造函数,第二个参数为参数组成的数组
function x(){} Reflect.construct(x, []) // x {}
当传第3个参数时,前两个参数不变,第三个参数为一个新的构造函数,如下代码所示
函数执行并没有变,this.a this.b还是x1中的值,但new.target变为了x2,所以其实,第三个参数的作用就是改变了new.target的指向,将其指向为第三个参数
function x1(){ this.a = 10 this.b = 20 console.log(this.a, this.b, new.target) } function x2(){ this.a = 100 this.b = 200 console.log(this.a, this.b, new.target) } let o1 = Reflect.construct(x1, [], x2) // 10 20 [Function: x2]
Reflect.set(o, name, value, 可选receiver)
类似 o[name] = value 成功返回true,失败返回false,若o不是对象抛出TypeError,
如果指定了可选参数receiver,则将其做为receiver中的方法调用,如下代码所示:
let n1 = { a:1 } let n2 = { a:3 } Reflect.set(n1, "b", 10, n2) n1 // { a: 1 } n2 // { a: 3, b: 10 }
Reflect.apply(f, o, args)
等同于 f.apply(o, args),让函数f作为o的方法进行调用
Reflect.defineProperty(o, name, descriptor)
Reflect.defineProperty与Object.defineProperty类似,Object.defineProperty成功会返回对象o,失败会抛出TypeError,Reflect.defineProperty成功会返回true,失败会返回false
Reflect.deleteProperty(o, name)
删除某个属性,成功会返回true,失败会返回false,类似执行delete o[name]
Reflect.get(o, name, 可选receiver)
类似o[name],若调动get访问器的属性,且指定了receiver,则相当于在receiver上调用了get访问器获取了属性值
Reflect.getOwnPropertyDescriptor(o, name)
基本等于Object.getOwnPropertyDescriptor,只不过该反射API第一个参数必须是对象,否则会抛出TypeError
Reflect.getPrototypeOf(o)
返回原型或null,对于原始值会抛出TypeError,基本等于Object.getPrototypeOf(),只不过Object.getPrototypeOf()会将原始值包装成对象
Reflect.has(o, name)
类似 name in o,返回true或false
Reflect.isExtensible(o)
判断对象o是否可扩展,在对象o可扩展时返回为true,否则返回为false,若o不是对象,则抛出TypeError,类似Object.isExtensible(),但Object.isExtensible()在o不是对象时会返回false
Reflect.ownKeys(o)
返回所有key组成的数组,字符串和符号都会被返回,若o不是对象,则抛出TypeError,相当于Object.getOwnPropertyNames()和Object.getOwnPropertySymbols()的结果组合
Reflect.preventExtensions(o)
将对象o的可扩展性设置为false,并返回true,若o不是对象,抛出TypeError,Object.preventExtensions()具有相同的效果,但返回对象o,非对象也不会抛出TypeError
Reflect.setPrototypeOf(o, p)
类似Object.setPrototypeOf(),成功返回true,失败返回false,若o不是对象或p既不是对象也不是null,抛出TypeError