Is there any benefit to call Reflect.apply() over

2020-05-30 03:10发布

I am just wondering if there is any good reason to call:

Reflect.apply(myFunction, myObject, args);

instead of:

myFunction.apply(myObject, args);

3条回答
甜甜的少女心
2楼-- · 2020-05-30 03:36

One use i can think of is using Reflect.apply in flow managment or in functions that execute an array of function

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

which much more convinient then

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

since you have more control.

查看更多
趁早两清
3楼-- · 2020-05-30 03:44

You can compare the definition of Function.prototype.apply and Reflect.apply in the spec.

Basically they are equivalent, but there is a difference: if the arguments list is null or undefined, Function.prototype.apply will call the function with no arguments, and Reflect.apply will throw.

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

Another difference is that, when you use func.apply, you assume

  • func is a Function instance, i.e. it inherits from Function.prototype
  • func has no apply own property which would shadow Function.prototype.apply

But Reflect.apply doesn't require that. For example,

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
查看更多
Emotional °昔
4楼-- · 2020-05-30 03:48

See also the SO question What does the Reflect object do in JavaScript?, which includes this text in the top answer:

Now that we have modules, a “@reflect” module is a more natural place for many of the reflection methods previously defined on Object. For backwards-compatibility purposes, it is unlikely that the static methods on Object will disappear. However, new methods should likely be added to the “@reflect” module rather than to the Object constructor

My understanding is that in previous iterations of JS, tools related to "reflection" have been scattered around the language, as part of the Object prototype and Function prototype. The Reflect object is an effort to bring them under one roof.

So, in the case of your question, although there are differences (see Oriol's answer), the reason for both to exist is a general move to future-proof reflection tooling in the ES spec.

查看更多
登录 后发表回答