iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
自我挑戰組

一個月的後端學習之旅系列 第 19

【DAY19】提升 Hoisting

  • 分享至 

  • xImage
  •  

JavaScript Hoisting 是指 JS 引擎在執行代碼之前,將 function、variables 或 class 的 declaration移動到其範圍頂部的過程

不論宣告變數的位置在哪,宣告的動作一律都會被「抬升」到函式的最頂端

// Hoisting 也會分配放進RAM
// let a;
// const z;
// var x = undefined;
// function hello() {...arguements...}

let a = 3;
const z = 6;
var x = 5;

hello();

function hello() {
  console.log("hello");
}

Hoisting 的優點之一是,它允許我們在 code 中,declare function 之前使用這個 function(但要小心,這個功能只對 function declaration 有用)

sayHello(); // 可以在宣告之前呼叫 function

function sayHello() {
  console.log("Hello!");
}

不適用於函式表達式function expression

sayHi(); // -> TypeError

let sayHi = function() {
  console.log("Hi!");
};
// 函式表達式,必須在它被賦值後才能使用它

Hoisting 也適用於 variables ,因此我們可以在 declaration 或 initialization 之前在 code 中使用 variables

console.log(myVar); // 可以在宣告之前使用變數

var myVar = 10;

注意 JavaScript 只 hoist declaration ,而不是 initialization !只有宣告這個動作有 hoisting的特性,賦值的動作不會 hoisting。

也就是說,let x = 10; 這段程式碼只有let x會被放到程式碼頂部

Hoisting 發生時,使用 var 做 declaration 的 variable 會給定初始值 undefined

// 上述例子
console.log(myVar); // 可以在宣告之前使用變數,但由於他的初始化並沒有被提升,會在宣告之前undefined

var myVar = 10;

使用 let, const 做 declaration 的 variable 並不會給定任何初始值

let myVar; // 沒有指定初始值
console.log(myVar); // -> undefined
const PI; // 沒有指定初始值
console.log(PI); // -> SyntaxError

使用 const 宣告陣列,不給定初始值,但需要注意的是,對於 const 來說,一旦給定了初始值,就不能再對其重新賦值

const colors = []; // 沒有指定初始值,但可以稍後賦值
colors.push("red");
console.log(colors); // -> ["red"]

let 可以 declare without initialization,且我們可以用 console.log()檢查 let 的變數值是 undefined

let myVar; // 宣告變數,但未初始化
console.log(myVar); // -> undefined

但這個 undefined 的 initialization 並不像 var 是發生在creation phasehoisting階段發生的,而是在execution phase的階段。

// Hoisting
// let x;

console.log(x); // -> ReferenceError:Cannot access 'x' before initialization
let x;

let x; // execution phase階段才會去定義x = undefined
console.log(x);// -> x is undefined

下一篇文章學習進階的作用域、閉包。


上一篇
【DAY18】全域執行環境、函式執行環境
下一篇
【DAY20】作用域、閉包
系列文
一個月的後端學習之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言