javascript 函数在块语句内提升

2024-02-10

{function foo(){};foo=1;function foo(){};foo=2;}
console.log(foo); // 1

谁能解释一下为什么这里输出“1”?

Edit: 似乎存在实现差异,在“Chrome”、“Firefox”、“Nodejs”中输出为“1”,但在“Safari”中输出为“2”


让我们美化该块并将其分解:

{
  function foo() {};
  foo = 1;

  function foo() {};
  foo = 2;
}
console.log(foo); // 1

块作用域函数声明通常将其变量名称提升到其块之外(其值为undefined),但仅在块内部接收一次值。您可以查看有关该行为的更多详细信息here https://stackoverflow.com/questions/31419897/what-are-the-precise-semantics-of-block-level-functions-in-es6.

但这种情况有点不同——你声明了一个函数twice在一个块中。看起来像第一个foo函数被分配给块外部可见的名称。如果您将属性描述符记录在window在代码中的不同点。

看起来,一旦达到重复的函数声明,就会进一步引用foo块内的变量名称引用绑定仅在块内。所以foo = 2在底部,因为它位于重复声明之后,所以只会导致2值绑定到foo在块内引用时的名称。块外的值仍然是块内的值foo最后举行before重复的函数声明:

// Variable name is hoisted: it exists on the global object, but is undefined
console.log(Object.getOwnPropertyDescriptor(window, 'foo'));
{
  // Function declaration: global foo gets assigned to
  function foo() {};
  console.log(window.foo);
  // Assignment to foo name: global foo gets assigned to
  foo = 1;
  // Assignment to foo name: global foo gets assigned to
  foo = 3;
  console.log(window.foo);

  // Duplicate function declaration: past this point, foo now no longer refers to the global foo
  // but to a locally-scoped identifier
  function foo() {};
  // See how the window value remains at 3:
  console.log(window.foo);

  // So this assignemnt only changes the binding of the `foo` inside this block
  // while window.foo remains at 3:
  foo = 2;
}
console.log(foo); // 3

查看原始代码的另一种方式:

{
  function foo() {}; // this ALSO does: window.foo = function foo() {};
  foo = 1; // this ALSO does: window.foo = 1

  function foo() {};  // this actually does: fooLocal = function foo() {};
  // further references to "foo" in this block refer to fooLocal
  foo = 2; // this actually does: fooLocal = 2
}
console.log(foo); // references window.foo
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

javascript 函数在块语句内提升 的相关文章

随机推荐

  • 如何在 Flutter 中创建圆形 CheckBox?或者改变CheckBox的样式,比如Flutter中选中的图片?

    我想创建一个像这样的圆形复选框 我尝试过多种变体 但似乎都不起作用 包括我尝试使用 ClipRRect 由于代码较多 这里只选取部分展示 new Row children
  • 使用Spring注入EntityManager(空指针异常)[重复]

    这个问题在这里已经有答案了 这是我的 ApplicationContext xml 中的代码
  • 实体框架迁移错误 - 序列不包含元素

    command 添加迁移等等 详细 error 序列不包含元素 在出现此错误之前我做了一些事情 我对代码优先模型进行了更改 但没有运行add migration然而 然后我添加了一个 EDMX 模型来直观地发挥一个想法 我意识到 EDMX
  • Vue JS 3:如何将数据从一个组件传递到另一个组件?

    我正在尝试共享存储在变量中的数据favorite count在收藏夹组件中Favorites vue文件 我想与应用程序组件共享该数据App vue文件 但我无法 我希望如果我改变的值favorite count在收藏夹组件中 它在应用程序
  • OpenERP 6.1中创建菜单项时访问规则禁止的操作

    当我尝试创建新的菜单项以在 OpenERP 6 1 中打开窗口时 出现以下错误 访问错误 访问规则禁止的操作 或对已删除的文档执行的操作 操作 创建 文档类型 ir values 我总是可以使用绕过所有安全检查的神奇管理员帐户 但如果可能的
  • Java 小程序 --> ClassNotFound 异常

    我正在学习Java并阅读这本书 在本书中 我有一个Java applet 练习 我可以在 Eclipse 的 appletviewer 中运行它并且运行良好 但我在将小程序集成到 HTML 中时遇到问题 这是我的java代码 package
  • 如何在 Decision Manager 中导出和导入本地项目?

    我正在使用红帽决策管理器 我已经完成了我的项目 我想将其部署到另一台电脑上 我所能得到的只是一个 jar 文件 但是当我导入它时 决策管理器响应 未找到项目 希望有任何帮助 Thanks 从 Red Hat Decision Manager
  • 在类模板实例化中显式使用某些参数的默认值

    一个类模板可以有多个参数 这些参数都有默认值 template
  • 绘制两个 xts 对象

    我在用着xtsExtra绘制两个 xts 对象 考虑以下对plot xts的调用 plot xts merge a b screens c 1 2 它用于在两个单独的面板中绘制 xts 对象 a 和 b 如何控制 y 轴的间距 具体来说 我
  • 安卓蓝牙连接错误

    我在堆栈跟踪中收到以下消息 我可以找到蓝牙设备 但是当我尝试打开套接字时会发生这种情况 10 30 22 23 08 901 ERROR BTL CFG 8633 WARNING service brcm bt INQ FILTER BDA
  • 以 DirectX 编程方式创建纹理

    我试图通过提供 rgba 值数组 使用该数组创建 ID3D11Texture2D 资源 然后将其映射到我的 20 x 20 正方形 在屏幕上创建一个白色 20 x 20 像素正方形 以下是创建方形纹理和着色器资源视图的代码 void Squ
  • Intel Core 2 Duo 预取

    有人有过在 Core 2 Duo 处理器上使用预取指令的经验吗 我一直在使用 标准 预取集 prefetchnta prefetcht1等 在一系列 P4 机器上取得了成功 但是当在 Core 2 Duo 上运行代码时 似乎prefetch
  • Task.WhenAll() 和 foreach(任务中的 var task) 有什么区别

    经过几个小时的努力 我在我的应用程序中发现了一个错误 我认为下面的两个函数具有相同的行为 但事实证明它们并非如此 谁能告诉我幕后到底发生了什么 以及为什么他们的行为方式不同 public async Task MyFunction1 IEn
  • 获取 WooCommerce 中所有“库存”产品的数量

    我有一个网站 产品被视为贸易 交易 因此 当有人进行交易 购买产品 时 它就会缺货 显示当前可用产品的剩余数量 基本上是库存 的 PHP 代码片段是什么 例如 快点 仅 10 个交易 woocommerce gt 产品 可用 提前致谢 我尝
  • 在 JavaScript 中,如何检查数组是否有重复的多个值?

    很抱歉我英语说得不好 这些是我的简单代码 带有一些参数数组 if link indexOf x 1 y 2 z 3 1 link push x 1 y 2 z 3 else alert Duplicate 用于 for 循环但不提醒重复 您
  • Nodejs v0.10.x(freebsd)“X509_STORE_add_cert:证书已在哈希表中”

    我正在使用异步 Web api 并且在高于 v0 8 9 的 Nodejs 版本中遇到问题 uname a FreeBSD home 9 1 STABLE FreeBSD 9 1 STABLE 0 2 月 1 日星期五 10 38 27 E
  • 如何在 Angular 单元测试中有条件地刷新 $timeout

    我的代码是这样的 function doThing if invalidInput console error Invalid input return timeout function MyService doThing 1000 我想测
  • 如何在C++中实现big int

    我想在 C 中实现一个 big int 类作为编程练习 一个可以处理大于 long int 的数字的类 我知道已经有几个开源实现 但我想编写自己的实现 我正在尝试了解什么是正确的方法 据我了解 一般策略是将数字作为字符串获取 然后将其分解为
  • 如果 url 变量为空则重定向到主页

    我无法让它正常工作 我有一个 view php 页面 它使用 ID 变量来检索数据库信息 所以我的网址是这样的 view php id 23 如果用户删除了 url 的 23 部分 我试图让它将用户 重定向 到主页 所以当你访问时 view
  • javascript 函数在块语句内提升

    function foo foo 1 function foo foo 2 console log foo 1 谁能解释一下为什么这里输出 1 Edit 似乎存在实现差异 在 Chrome Firefox Nodejs 中输出为 1 但在