Мне просто интересно, есть ли веские причины для вызова:
Reflect.apply(myFunction, myObject, args);
вместо:
myFunction.apply(myObject, args);
Мне просто интересно, есть ли веские причины для вызова:
Reflect.apply(myFunction, myObject, args);
вместо:
myFunction.apply(myObject, args);
Вы можете сравнить определение 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
См. также вопрос SO Что делает объект Reflect в JavaScript?, который включает этот текст в верхнем ответе:
Теперь, когда у нас есть модули, модуль "@reflect" является более естественным местом для многих методов отражения, ранее определенных для Object. Для целей обратной совместимости маловероятно, что статические методы на объекте исчезнут. Однако новые методы, вероятно, должны быть добавлены к модулю "@reflect", а не к конструктору Object
Я понимаю, что в предыдущих итерациях 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)
})
}
так как у вас больше контроля.