new Function() 和 new Function()() 的区别

Difference between new Function() and new Function()()

我发现了一些代码 here,其中以一种有趣的方式调用了 Function 构造函数:

var jscriptVersion; // ...some code
jscriptVersion = new Function("/*@cc_on return @_jscript_version; @*/")();

起初我认为额外的括号是个错误,但在控制台中进行了一些测试后,我认为这可能是获取 return 值的捷径:

var a = new Function("return 'abc'");
var b = new Function("");
var c = new Function("")();
var d = new Function("return 'xyz'")();

console.log(a, typeof a);  // f anonymous() { return 'abc' } , function
console.log(b, typeof b);  // f anonymous() { } , function
console.log(c, typeof c);  // undefined , undefined
console.log(d, typeof d);  // xyz , string

我猜 d 是(几乎,除了 new 关键字)在功能上等同于:

var d2 = function() { return 'xyz' }(); console.log(d2); // xyz

但是我真的从来没有在不是 IIFE 的函数表达式后看到尾随括号,令我惊讶的是定义 d2 的代码不会导致 SyntaxError。

我查看了 MDN,但找不到关于如何使用它的明确信息。

这是有效的 JS 还是双括号的实现因浏览器而异?

new Function 后面的括号将立即调用该函数。它与 IIFE 基本相同,除了被调用的函数是根据传递的字符串动态构造的 - new Function returns 一个函数,如果后跟 [ 则立即 运行 =14=].

var a = new Function("return 'abc'");
var b = new Function("");
var c = new Function("")();
var d = new Function("return 'xyz'")();

console.log(a, typeof a);  // f anonymous() { return 'abc' } , function
                           // because that is the function that was constructed from the `return 'abc'` string
console.log(b, typeof b);  // f anonymous() { } , function
                           // because the string passed was empty, so the function returned from new Function is empty
console.log(c, typeof c);  // undefined , undefined
                           // because an empty function, when invoked, does not return anything:
                           // x = (() => {
                           // })();
                           // x is undefined
console.log(d, typeof d);  // xyz , string
                           // because the constructed function's body returns the `xyz` string
                           // and the constructed function was invoked immediately

returns 函数在调用后可以具有 () 的任何函数,而不仅仅是 new Function 或 IIFE。例如:

const makeFn = arg => () => console.log(arg);

const fnThatLogs3 = makeFn(3);
fnThatLogs3();

makeFn(4)();