Подтвердить что ты не робот

Есть ли какая-либо польза для вызова Reflect.apply() над Function.prototype.apply() в ECMAScript 2015?

Мне просто интересно, есть ли веские причины для вызова:

Reflect.apply(myFunction, myObject, args);

вместо:

myFunction.apply(myObject, args);
4b9b3361

Ответ 1

Вы можете сравнить определение 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

Ответ 2

См. также вопрос SO Что делает объект Reflect в JavaScript?, который включает этот текст в верхнем ответе:

Теперь, когда у нас есть модули, модуль "@reflect" является более естественным местом для многих методов отражения, ранее определенных для Object. Для целей обратной совместимости маловероятно, что статические методы на объекте исчезнут. Однако новые методы, вероятно, должны быть добавлены к модулю "@reflect", а не к конструктору Object

Я понимаю, что в предыдущих итерациях JS инструменты, связанные с "отражением", были разбросаны по всему языку как часть прототипа Object и прототипа Function. Объект Reflect - это попытка привести их под одну крышу.

Итак, в случае вашего вопроса, хотя есть различия (см. ответ Oriol), причина для существования - это общий переход к инструментам отражения будущего в спецификации ES.

Ответ 3

Одно использование, о котором я могу думать, - использование 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)
  })
}

так как у вас больше контроля.