我只是想知道是否有充分理由打电话:
Reflect.apply(myFunction, myObject, args);
而不是:
myFunction.apply(myObject, args);
答案 0 :(得分:13)
您可以在规范中比较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
答案 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)
})
}
因为你有更多的控制权。