【发布时间】:2016-01-10 15:39:02
【问题描述】:
我只是想知道是否有充分的理由打电话:
Reflect.apply(myFunction, myObject, args);
代替:
myFunction.apply(myObject, args);
【问题讨论】:
-
引用MDN,“不那么冗长,更容易理解”。
标签: javascript functional-programming ecmascript-6
我只是想知道是否有充分的理由打电话:
Reflect.apply(myFunction, myObject, args);
代替:
myFunction.apply(myObject, args);
【问题讨论】:
标签: javascript functional-programming ecmascript-6
您可以在规范中比较Function.prototype.apply和Reflect.apply的定义。
基本上它们是等价的,但有区别:如果参数列表是null 或undefined,Function.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 时,您假设
func 是一个 Function 实例,即它继承自 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
【讨论】:
Function.prototype.apply.call轻松克服
Function.prototype.apply 从 Function.prototype 继承,也没有添加自定义 call 自己的方法。
Function.prototype.apply,愿上帝怜悯您的灵魂。
undefined 可能被具有另一个值的局部变量所遮蔽。 void 0 总是返回原始的未定义值。
apply 因某些功能而被遮蔽,则可能是出于某种原因 - 记录、模拟等。使用 Reflect.apply() 将绕过所有这些。
另请参阅 SO 问题 What does the Reflect object do in JavaScript?,该问题在最佳答案中包含此文本:
现在我们有了模块,“@reflect”模块对于之前在 Object 上定义的许多反射方法来说是一个更自然的地方。出于向后兼容的目的,Object 上的静态方法不太可能消失。然而,新方法可能应该被添加到“@reflect”模块而不是对象构造函数中
我的理解是,在以前的 JS 迭代中,与“反射”相关的工具已经分散在语言周围,作为 Object 原型和 Function 原型的一部分。 Reflect 对象旨在将它们集中在一个屋檐下。
因此,就您的问题而言,尽管存在差异(请参阅 Oriol 的回答),但两者存在的原因是普遍转向 ES 规范中面向未来的反射工具。
【讨论】:
我能想到的一个用途是在流程管理或执行函数数组的函数中使用 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)
})
}
因为你有更多的控制权。
【讨论】: