[Day13] Hoisting

提升(Hoisting) 在 JavaScript 里指的是在执行代码之前,直译器(interpreter)把变数及函式的宣告先分配到记忆体里的现象,实际上在程序码里的位置还是一样,但看起来像是把变数及函式的宣告移到程序顶端,故称为 Hoisting。而提升只是方便解释这个现象,他背後运作的原理跟移动程序码没有关系。

若未宣告 a 变数,就 console.log(a) 会印出什麽?会直接报错,对吧。

如果在下面加了一行宣告,那情况就不同了,

console.log(a); // 回传 undefined
var a = 5; 宣告在後面

咦?为什麽?程序是一行一行读取的,a 未宣告情况应该要跟上面一样报错吧?这就是 Hoisting 的基本现象。

可以观察到,一般正常宣告变数後,console.log 会印出他的值,而 Hoisting 後显示的是 undefined,原因是 Hoisting 只会对宣告做提升,赋值不会。我们可以把它「想像」成下面这个情况

var a // 宣告被 hoisting
console.log(a); // 回传 undefined
a = 5; // 而赋值没有被 hoisting

把一样的情况放在函式的宣告,虽然没有读取到 c 的赋值,但外面 foo(13) 的呼叫传值进来,产生出来的结果。

function foo(c) {
  console.log(c); // 13
  var c = 2; 
}
foo(13);

所以除了变数的宣告外,函式的的宣告也会被 hosting,而且优先权比变数还高,证明如下例:

console.log(d); // [function: d]
var d = 20;
function d() {}

let 与 const 的 hoisting


如果我们以为上图的状况跟 var 不同,就以为 let 跟 const 没有hoisting 那就错了,来看看它们到底有没有 hoisting 的状况(因结果差不多用 let 举例):

var a = 10;
function test(){
  console.log(a); //  Cannot access 'a' before initialization
  let a = 33;
}
test()

若 let 没有 Hoisting 那函式应该会往外找到 var a = 10,但结果是报错 Cannot access 'a' before initialization,回应并没有找到 a 的初始化,代表 let(与 const) 存在 Hoisting。

参考资料

008 天重新认识 JavaScript
Huli 我知道你懂 hoisting,可是你了解到多深?
你不知道 Combo : 前菜 Hoisting


<<:  EP 20: Custom Launch Screen for Android

>>:  Day 13: 时间管理、预估、压力 (待改进中... )

D7 第三周整理笔记

当周进度: ALG101 到 单元六:内建函式做做看 JS102 先自首,这周进度很多部分我当初都跳...

[Day 3]开胃沙拉-Python安装及Vagrant虚拟环境架设

在上一篇我们下载完了准备工具後 这篇我们要来开始架设我们的程序环境了 这一篇我们会教大家 如何下载P...

Day 1-酸酸甜甜的湘粤美人-糖醋排骨

30天铁人赛,自我挑战组,想了很久不知道第一道该上什麽菜 想到自我挑战,决定第一篇先来自我挑战一下,...

铁人赛 Day9-- PHP SQL基本语法(四) -- SELECT 到底在SELECT什麽 & WHERE 基本语法

>SELECT:查询 SELECT 基本语法 SELECT '栏位名称' FROM '资料表名...

Day12. UX/UI 设计流程之二: Flow Chart (以 Axure RP 实作)

透过 Functional Map 将 User Story 里抽象的「需求」转换成「功能」描述之...