代码之家  ›  专栏  ›  技术社区  ›  Asleepace

JS中空函数体返回什么?

  •  -1
  • Asleepace  · 技术社区  · 1 周前

    函数体是否为空 隐含地 返回 undefined 在JS?

    console.log((() => {})())

    显然,这是正确的吗?控制台输出 未定义 在上述示例中。。。

    // but let's do something crazy
    
    console.log(((undefined) => undefined)("defined"));
    
    console.log((() => {
      var undefined = "defined";
      return undefined; 
    })());

    好的,我们可以重新申报 未定义 本地(或全局,无严格模式)

    console.log(((undefined) => {
      var undefined = "defined_again";
    })("defined"));

    但产量仍然 未定义 ,看来不是 隐含地 返回 未定义 ,而是将整个表达式视为 void(expr) .

    TypeScript中似乎也是如此:

    const result = (() => {})()
    //    ^?: const result: void
    

    因此,如果空函数体确实隐式返回 未定义 如规范中所述,那么为什么JS忽略了 未定义 如果它在函数体中被重新声明?

    显然,最终的结果是 未定义 ,但我更好奇的是什么的实际实现行为 隐含地 返回?

    空功能体是否 事实上 还东西?

    2 回复  |  直到 1 周前
        1
  •  2
  •   user2357112    1 周前

    它回来了 undefined ,如特定的ECMAScript语言值 未定义 ,不执行变量查找 未定义 变量,并返回查找返回的任何内容。如果你想去看规格,你可以看到 rule 对于一个正常完成的函数,没有显式的 return

    1. 退货完成( 未定义 ).

    其中大胆 未定义 可变宽度字体表示 ECMAscript language value :

    在本规范中,ECMAScript语言值显示在 大胆的 示例包括 无效的 , 真的 ,或 “你好” 这些与ECMAScript源文本不同,例如 Function.prototype.apply let n = 42; .

    (是的,ECMAScript源文本有点尴尬 大胆。)

        2
  •  1
  •   Sergey A Kryukov    1 周前

    我希望你剪的#2已经清楚了。您引入变量 undefined ,并且它不引用全局只读属性 未定义 。这只是存储在堆栈上的局部变量。当您显式返回它时,外部堆栈会接收该值 'defined' ,并且变量本身在弹出堆栈的意义上被删除。

    重要的是要理解 未定义 不是a 全局变量 或者别的什么。没有这样的事情。存在全局对象 globalThis ,其他所有内容都可以是此对象的属性。当然,这个对象取决于环境。例如,在Web浏览器中,它与 window .

    不管怎样,

    console.log(globalThis.undefined === undefined);
    

    输出 true ,这是同一件事。

    该物业 globalThis.undefined 返回唯一对象,其值具有唯一性 原始的 类型。重要的是,您无法通过获取其 constructor ( undefined.constructor 将抛出异常): 未定义 不能被取消引用。然而,事实并非如此 null 但这是一个截然不同的物体。请注意,这两个表达式 myObject == null myObject == undefined 返回 真的 如果 myObject 未定义 无效的 ,这在实际应用中非常方便。然而, 未定义 不是 无效的 ,如果我们使用运算符,我们可以看到它 === .两者之间的区别 无效的 未定义 它对JavaScript非常具体。

    现在,以上所有内容都应该让您了解代码片段#3中发生了什么 var undefined = "defined_again" 尽管如此 未定义 你说呢?但什么是未定义的?变量引用 "defined_again" 再次,它是一个堆栈变量,返回后不存在,与 globalThis未定义 我希望这应该是清楚的。

    剩下的问题是解释为什么所有不返回任何东西的函数的行为都与返回的函数完全相同 globalThis未定义 。你知道,我不是在研究JavaScript实现,也不确定。我只是觉得具体的机制并不那么重要,甚至可能会有所不同。重要的是外观功能。本质上,你是对的,这就像 void .也许源代码的编译注入了 globalThis未定义 在每个功能中,或者 无效 在调用函数的级别上以某种方式检测到条件。如果返回的对象没有被丢弃,它将在调用堆栈帧中变得可访问,并被发现引用 globalThis未定义 ,没有别的。这才是最重要的。

    const a = () => { };
    console.log(a() === globalThis.undefined);
    

    输出 真的 .

        3
  •  0
  •   PMontgomery    1 周前

    这些实际上都没有记录空函数体。

    代码1 console.log((() => {})()) 正在获取一个空函数,执行它,并发送其结果( undefined )到console.log。就像你 console.log(undefined) .

    代码2.A正在传递一个函数的执行,该函数接受一个参数并返回与相同的参数 console.log((foo) => foo)("defined")) 。有一个奇怪的变量名并不重要

    代码2.B实际上与 console.log((()=> "defined")()) 。有一个奇怪的变量名仍然没关系。

    代码3。与1基本相同。你什么都不退,所以console.log回来了 未定义 因为这正是函数执行的结果。