JavaScript 中的“提升”是怎么回事?

开发 前端
在执行JavaScript代码之前,js引擎首先会对其进行解析和编译。在编译阶段,变量和函数声明被放入内存,这被称为提升(hoisting)。

在执行JavaScript代码之前,js引擎首先会对其进行解析和编译。在编译阶段,变量和函数声明被放入内存,这被称为提升(hoisting)。

需要注意的是,声明只是被提升,而不是被初始化,这意味着如果一个变量在使用后被声明并初始化,则不会初始化它的值。

[[403683]]

function

使用 function 声明时,可以在定义之前调用这个函数,它会按预期正常工作。例如:

  1. hello(); // 输出 'Hello world!' 
  2.  
  3. function hello() { 
  4.   console.log('Hello world!'); 
  5.  
  6. hello(); // 输出 'Hello world!' 

在上面的例子中, function 声明被提升到其作用域的顶部,并且由于函数声明的性质,在声明之前就可用。不过这是函数提升行为的唯一案例。

var

另一方面,var 声明的行为有所不同,在其初始化之前进行访问会返回 undefined。例如:

  1. console.log(x); // 输出 'undefined' 
  2. f(); // 抛出异常:'Uncaught TypeError: f is not a function' 
  3.  
  4. var x = 1
  5. var f = () => 'Hi!'; 
  6.  
  7. console.log(x); // 输出 '1' 
  8. f(); // 返回 'Hi!' 

正如你在这个例子中所看到的,var 声明被提升到它作用域的顶部,但是变量的值只有在初始化代码被执行时才会初始化,所以在初始化这行代码之前是 undefined。

const 和 let

const 和 let 声明被提升,但它们没有被初始化为 undefined。而是会给你一个错误,这也是 class 声明的行为方式。例如:

  1. console.log(y); // 抛出异常: 'Uncaught ReferenceError: Cannot access "y" before initialization' 
  2. g();  // 抛出异常: 'Uncaught ReferenceError: Cannot access "g" before initialization' 
  3.  
  4. let y = 2
  5. const g = () => 'Hey!'; 
  6.  
  7. console.log(y); // 输出 '2' 
  8. f(); // 返回 'Hey!' 

一般情况下,在初始化之前访问用 var 声明的变量会默默地失败,对 const 或 let做同样的事情会导致一个清晰的、易于调试的错误。

总结

 

  • 在使用变量、函数、对象和类之前,务必要先定义它们。ESLint 可能可以帮你解决这个问题。
  • 在项目中要尽可能的使用 const 和 let,而不是 var 。这样可以减少很多麻烦。
  • 如果可能的话,只使用箭头函数或 function 声明。一致性有助于减少混乱。

 

责任编辑:赵宁宁 来源: 前端先锋
相关推荐

2023-03-29 08:24:30

2020-02-18 11:19:36

物联网病毒物联网IOT

2021-07-31 19:21:34

Python下划线数值

2022-04-15 08:54:39

PythonAsync代码

2023-03-05 15:41:58

MySQL日志暴涨

2013-04-18 09:56:05

2021-05-11 11:51:15

飞机Wi-Fi通信

2024-01-08 08:35:28

闭包陷阱ReactHooks

2016-11-22 19:54:56

点击率预估推荐算法广告

2023-10-12 08:54:20

Spring事务设置

2019-07-23 15:34:29

MySQL存储引擎

2018-05-08 08:46:47

Linux内存释放

2021-08-10 09:28:10

ViteES Modules Dev Server

2009-11-13 13:42:38

ADO.NET数据服务

2019-02-17 10:05:24

TCPSocket网络编程

2021-07-30 07:28:16

伪类伪元素CSS

2017-11-24 11:10:38

区块链矿工分叉

2022-12-13 08:36:42

D-SMARTOracle数据库

2021-10-15 21:16:00

手机内存漏洞

2015-03-25 14:44:05

DNS苹果
点赞
收藏

51CTO技术栈公众号