这种起重如何与料斗一起工作?

Hao Wu

我被问到一个问题

{
  function foo() {
    console.log('A');
  }
  
  foo();
  
  foo = 1;
  
  function foo() {
    console.log('B');
  }
  
  foo = 2;

  console.log(foo);
}
console.log(foo);

为什么使用第三个输出1而不是2


应该没有作用域块foo创建以来,既没有let,也不const在该块。但是第二个foo输出2表示确实存在另一个引用foo

到底是怎么回事?

PS我正在使用Chrome Version 89.0.4389.90 (Official Build) (x86_64)

乔纳斯·威尔姆斯

根据函数声明处网络兼容语义,已阻止范围变量的值绑定到外部范围²。此代码等效于:

let outerFoo; // the functions create a binding outside of the scope

{
  let innerFoo; // but also inside
  // due to hoisting, functions get bound before any code get's executed:
  innerFoo = function foo() {
    console.log('A');
  };
  innerFoo =   function foo() {
    console.log('B');
  };
  
  // At the place of the function declaration, the variable leaves the scope
  /* function foo() {
    console.log('A');
  } */
  outerFoo = innerFoo;

  innerFoo();
  
  innerFoo = 1;
  
  // this also applies to the second declaration
  /* function foo() {
    console.log('B');
  } */
  outerFoo = innerFoo;
  
  innerFoo = 2;

  console.log(innerFoo);
}
console.log(outerFoo);

²这基本上就是规范描述的方式:

When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 15.2.6:
a. Let fenv be the running execution context's VariableEnvironment.
b. Let benv be the running execution context's LexicalEnvironment.
c. Let fobj be ! benv.GetBindingValue(F, false).
d. Perform ! fenv.SetMutableBinding(F, fobj, false).

规范另外指出:

在ECMAScript 2015之前,ECMAScript规范未将FunctionDeclaration的出现定义为Block语句的StatementList的元素。但是,对这种形式的FunctionDeclaration的支持是一个允许的扩展,大多数浏览器托管的ECMAScript实现都允许它们。不幸的是,这些声明的语义在这些实现之间有所不同。由于存在这些语义差异,因此,使用块级功能声明的现有Web ECMAScript代码仅在用法仅取决于此类声明的所有浏览器实现的语义交集的情况下,才可在浏览器实现中移植。

因此,Safari可能会像往常一样执行此操作,而Chrome(和Firefox)则遵循该规范。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何让Cabal和Nix一起工作

来自分类Dev

扭曲如何与原子操作一起工作?

来自分类Dev

Jruby和OSGi-如何一起工作?

来自分类Dev

如何配置Spring和Angular一起工作

来自分类Dev

虚拟机一起重新启动,如何避免这种情况?

来自分类Dev

如何使onDragListener和onTouchListener一起工作?

来自分类Dev

hashmap如何与Integer作为键一起工作

来自分类Dev

试图了解混杂如何与BlueBird一起工作

来自分类Dev

JavaScript和JSF如何一起工作?

来自分类Dev

如何使Reader和ReaderT一起工作

来自分类Dev

如何使ExcelDNA与R.Net一起工作

来自分类Dev

我如何让jQuery与我一起工作?

来自分类Dev

如何使Apache POI和JAXB一起工作?

来自分类Dev

如何使Webpack和Node一起工作?

来自分类Dev

如何使Webpack和Node一起工作?

来自分类Dev

平均负载如何与现代CPU一起工作?

来自分类Dev

spark RangeBetween如何与降序一起工作?

来自分类Dev

Job queue如何与promise一起工作?

来自分类Dev

如何使Tkinter和Selenium一起工作

来自分类Dev

setState如何与备注中的反应一起工作

来自分类Dev

如何使Pynput的线程与转义序列一起工作?

来自分类Dev

std :: cout如何与char指针一起工作?

来自分类Dev

红宝石如何与数组数组一起工作

来自分类Dev

insertOrThrow如何与UNIQUE约束一起工作?

来自分类Dev

Jruby和OSGi-如何一起工作?

来自分类Dev

如何使onDragListener和onTouchListener一起工作?

来自分类Dev

如何让Picasso和OkHttp一起工作?

来自分类Dev

超越如何与隔离范围一起工作

来自分类Dev

我如何让jQuery与我一起工作?