Я наткнулся на код здесь, где конструктор Function вызывается интересным образом:
var jscriptVersion; // ...some code
jscriptVersion = new Function("/*@cc_on return @_jscript_version; @*/")();
Сначала я подумал, что лишние скобки были ошибкой, но после небольшого тестирования в консоли я подумал, что, возможно, это ярлык для получения возвращаемого значения:
var a = new Function("return 'abc'");
var b = new Function("");
var c = new Function("")();
var d = new Function("return 'xyz'")();
console.info(a, typeof a); // f anonymous() { return 'abc' } , function
console.info(b, typeof b); // f anonymous() { } , function
console.info(c, typeof c); // undefined , undefined
console.info(d, typeof d); // xyz , string
Я предполагаю, что d
(почти, за исключением ключевого слова new
) функционально идентичен:
var d2 = function() { return 'xyz' }(); console.info(d2); // xyz
Но опять же, я буквально никогда не видел закрывающие круглые скобки после функционального выражения, которое не является IIFE, и я удивлен, что код, определяющий d2
, не приводит к SyntaxError.
Я просмотрел МДН, но не смог найти четкой информации о том, как это будет использоваться.
И это действительный JS или реализация двойных скобок различается в разных браузерах?
function() { return 'xyz' }();
было бы будет SyntaxError, но var d2 = function() { return 'xyz' }();
не потому, что он оценивается как функция выражение вместо функции утверждение.
Завершающие круглые скобки после new Function
немедленно вызовут функцию. Это в основном то же самое, что и IIFE, за исключением того, что вызываемая функция динамически создается из переданной строки — new Function
возвращает функцию, которая затем немедленно запускается, если за ней следует ()
.
var a = new Function("return 'abc'");
var b = new Function("");
var c = new Function("")();
var d = new Function("return 'xyz'")();
console.info(a, typeof a); // f anonymous() { return 'abc' } , function
// because that is the function that was constructed from the `return 'abc'` string
console.info(b, typeof b); // f anonymous() { } , function
// because the string passed was empty, so the function returned from new Function is empty
console.info(c, typeof c); // undefined , undefined
// because an empty function, when invoked, does not return anything:
// x = (() => {
// })();
// x is undefined
console.info(d, typeof d); // xyz , string
// because the constructed function's body returns the `xyz` string
// and the constructed function was invoked immediately
Любая функция, которая возвращает функцию, может иметь после вызова ()
, а не только new Function
или IIFE. Например:
const makeFn = arg => () => console.info(arg);
const fnThatLogs3 = makeFn(3);
fnThatLogs3();
makeFn(4)();
Вы делаете это, когда у вас есть функция, которая возвращает внутреннюю функцию, предназначенную для выполнения где-то еще.