在ECMAScript 2015中调用Reflect.apply()对Function.prototype.apply()有什么好处吗?

时间:2016-01-10 15:39:02

标签: javascript functional-programming ecmascript-6

我只是想知道是否有充分理由打电话:

Reflect.apply(myFunction, myObject, args);

而不是:

myFunction.apply(myObject, args);

3 个答案:

答案 0 :(得分:13)

您可以在规范中比较Function.prototype.applyReflect.apply的定义。

基本上它们是等价的,但有区别:如果参数列表是nullundefinedFunction.prototype.apply将调用没有参数的函数,Reflect.apply会抛出。

function func() {
  return arguments.length;
}
func.apply(void 0, null); // 0
Reflect.apply(func, void 0, null); // TypeError: null is not a non-null object

另一个不同之处在于,当您使用func.apply时,您会假设

  • funcFunction个实例,即它继承自Function.prototype
  • func没有apply自己的属性,可以隐藏Function.prototype.apply

Reflect.apply并不需要这样做。例如,

var obj = document.createElement('object');
typeof obj; // "function" -- can be called
obj.apply; // undefined -- does not inherit from Function.prototype
Reflect.apply(obj, thisArg, argList); // -- works properly
var func = a => a;
func.apply = a => 0;
func.apply(void 0, [123]); // 0 -- Function.prototype.apply is shadowed by an own property
Reflect.apply(func, void 0, [123]); // 123 -- works properly

答案 1 :(得分:7)

另请参阅SO问题What does the Reflect object do in JavaScript?,其中包含最常见答案中的此文字:

  

现在我们有了模块,“@ reflect”模块对于之前在Object上定义的许多反射方法来说是一个更自然的地方。出于向后兼容的目的,Object上的静态方法不太可能消失。但是,新方法可能会添加到“@reflect”模块而不是“Object构造函数”

我的理解是,在以前的JS迭代中,与“反射”相关的工具已经分散在语言周围,作为Object原型和Function原型的一部分。 Reflect对象是将它们集中在一个屋檐下的努力。

因此,就你的问题而言,虽然存在差异(参见Oriol的回答),但两者存在的原因是在ES规范中向未来证明反射工具的普遍转变。

答案 2 :(得分:0)

我能想到的一个用途是在流动管理或执行函数数组的函数中使用Reflect.apply

function execFuncs(funcArr){
 var obj = this.someObj;
 funcArr.forEach(function(func){
    Reflect.apply(func,obj)
 });
}

哪个更方便

function execFuncs(funcArray){
  var obj = this.someObj;
  funcArray.forEach(function(func){
      func.prototype.apply(obj)
  })
}

因为你有更多的控制权。