【问题标题】:From where is an IIFE actually invoked?IIFE 是从哪里实际调用的?
【发布时间】:2018-09-26 06:17:10
【问题描述】:

看一个简单的 IIFE 示例

((x) => x)(1) // returns 1

如果我从一个可以作为回调传递的常规(但匿名)函数的角度来考虑这个:

setTimeout(function() {alert(1)}, 1000)

匿名函数仍在被调用。 IIFE 类似地看起来像作为回调传递给返回函数的某个函数

看起来这个返回的函数是用 1 的参数调用的,然后 IIFE 被 some function

返回的函数调用>

这是正确的吗? some function 定义在什么对象上?它是窗口/全局吗?或者这是 JavaScript 实现功能而不是语言功能?

【问题讨论】:

  • setTimeout(function() {alert(1)}, 1000) 这不是 IIFE
  • The IIFE looks like it is passed as a callback to some function that returns a function. 该描述与您的示例都不匹配。 IIFE 是一个立即调用的函数表达式。第一个示例是 IIFE,因为...您立即执行它。但你不会在任何地方通过它。第二个示例没有 IIFE。很简单,IIFE 或多或少定义了myFynction(a) { return a+1 },然后执行它myFunction(2) //returns 3,但一次完成,而不是两行。
  • 可能有用的资源:@​​987654321@stackoverflow.com/questions/8228281/…

标签: javascript iife


【解决方案1】:

IIFE 同样看起来像作为回调传递给返回函数的某个函数

没有。在

    f(1)

只有一个函数调用:直接调用f

//     v v function call operator
    (f)(1)
//  ^ ^ grouping

仍然只有一个函数调用。代码相当于f(1);只是添加了一些多余的括号。

我们不仅限于调用变量。我们可以使用任何我们想要的表达式(只要它是一个函数):

(function (x) { ... })(1)

// equivalent to:
     let f = function (x) { ... };
     f(1);
// but without needing a temporary variable

我们不能只写function () { ... }() 的唯一原因是function 关键字不能出现在语句的开头(如果出现,则将其解析为函数声明的开头,而不是函数表达)。但是例如

void function () { console.log("hello"); }();

console.log( function (x) { return x + 1; }(1) );

是完全有效的语句(包含 IIFE)。

=> 函数的情况略有不同。这里我们只需要关心函数体向右延伸多远。

(() => console.log("hello"))();

... 需要在函数表达式周围加上括号,否则末尾的 () 将被解析为函数体的一部分:console.log("hello")(),它将尝试调用从 console.log 返回的值。

【讨论】:

  • just some redundant parens were added. 在这种情况下可能是多余的,但在一般情况下它不是多余的。这是为了 1. 明确它是一个 IIFE 和 2. 防止未包装的 IIFE 进行一些不直观的解析。
  • @vlaz 如果function 出现在语句的开头,这并不是多余的。否则就是多余的。
  • 这意味着在一般情况下它不是多余的。此外,a = function(){}() 可能很难理解,具体取决于函数的长度,因此您可能假设 a 是一个函数,但实际上它是 IIFE 的值。 "根据经验,虽然编写明确的代码在技术上可能是防止 JavaScript 解析器抛出 SyntaxError 异常所必需的,但编写明确的代码也是相当必要的,以防止其他开发人员向您抛出“WTFError”异常! i>"from here
  • 也可以使用二元运算符来代替括号。所以例如 !function(){}() 也可以使用。
  • @vlaz 没错,但这只是惯例问题,而不是硬语言规则。你必须知道代码作者使用了哪些约定,因为没有什么能阻止我写a = (function () { ... });,这(尽管有括号)不是 IIFE。
猜你喜欢
  • 2020-10-16
  • 2018-02-07
  • 1970-01-01
  • 2019-04-06
  • 2016-04-22
  • 1970-01-01
  • 1970-01-01
  • 2011-09-02
  • 1970-01-01
相关资源
最近更新 更多