JavaScript入門學習之旅(一)——JavaScript變數提升和函式提升
在JavaScript引擎正式編譯之前,會進行一次預編譯,在這個過程中,會將變數宣告及函式宣告提升至當前作用域的最頂端,其後才進行接下來的處理。
變數提升
未使用塊級作用域:
原始碼:
console.log(msg);// undefined
var msg = "This is a message";
console.log(msg);// This is a message
function fn () {
console.log(hello); // undefined
var hello = 'hello world';
console.log(hello); // hello world
}
fn();
JavaScript解析器的解析流程:
var msg;// 變數提升,全域性作用域範圍內,此時只是宣告,並沒有賦值
console.log(msg);// undefined
msg = "This is a message";// 此時才賦值
console.log(msg);// 列印出This is a message
function fn () {
var hello;// 變數提升,函式作用域範圍內,此時只是宣告,並沒有賦值
console.log(hello); // undefined
hello = 'hello world';// 此時才賦值
console.log(hello); // hello world
}
fn();
ES5只有全域性作用域和函式作用域,而ES6開始提供了塊級作用域。使用ES6語法的let建立的變數和const語法建立的常量,均不存在變數提升。
使用塊級作用域:
console.log(msg);//Uncaught ReferenceErrord
let msg = "This is a message";//沒有被執行
console.log(msg);//沒有被執行
function fn () {
console.log(hello); //Uncaught ReferenceErrord
let hello = 'hello world'; //沒有被執行
console.log(hello); //沒有被執行
}
fn();
IIFE與塊級作用域
一般的JavaScript函式有三種寫法。
1.函式關鍵字,也叫函式宣告語句寫法
function foo(){}; foo();
2.函式字面量,也叫函式表示式寫法
var foo = function(){}; foo();
3.funtion()建構函式
var foo = new function(): foo();
有時需要在定義函式之後,立即呼叫該函式。這種函式就叫做立即執行函式,全稱為立即呼叫的函式表示式IIFE(Imdiately Invoked Function Expression)。 通過立即呼叫的函式表示式,能夠實現塊級作用域的效果。
JavaScript引擎規定,如果function關鍵字出現在行首,一律解釋成函式宣告語句,而且宣告語句必須要有一個函式名。所以如下的程式碼demo會報錯。
function () {}; //Uncaught SyntaxError: Unexpected token (
正確的寫法是給函式宣告語句提供一個函式名。
function foo() {}; //undefined
接下來將函式宣告語句與JavaScript分組操作符進行組合,看上去這樣的組合好像並沒有什麼意義,並且會丟擲一個錯誤:
function foo() {} (); //Uncaught SyntaxError: Unexpected token )
錯誤在於JavaScript分組操作符需要指定一個值,不能為空。
正確的組合寫法:
function foo() {} (0);//0
或
function foo() {}; (0); //0 兩種寫法等價。
這樣也僅僅是實現了函式宣告語句與不報錯的分組操作符的組合。
所以需要將函式宣告語句改成函式表示式寫法,將function使用分組操作符進行組合。這樣就不需要再指定一個函式名。這個表示式將會在載入網頁時立即執行,而不需要單獨呼叫函式。執行後,函式內程式碼塊宣告的變數將只在區域性作用域內有效。無法被外層訪問到。
(function () {} () );
或者
(function () {}) ();
在ECMAScript6中,由於塊級作用域的出現,實際上使得獲得廣泛應用的立即執行函式表示式(IIFE)不再必要了。
// IIFE 寫法
(function () { var tmp = 0; }());
// 塊級作用域寫法
{ let tmp = 0; }
函式提升
函式提升與變數提升效果一致,但JavaScript只有函式宣告語句才存在函式提升.
原始碼:
console.log(msg1); // function msg1() {};
console.log(msg2); // undefined
function msg1() {}
var msg2 = function() {}
JavaScript解析器的解析流程:
function msg1() {}; // 函式提升,整個程式碼塊提升到檔案的最開始
console.log(msg1);
console.log(msg2);
var msg2 = function() {}
參考來源:
相關文章
- Javascript 函式和變數提升JavaScript函式變數
- javascript之變數提升與函式提升JavaScript變數函式
- JS——變數提升和函式提升JS變數函式
- JavaScript變數提升JavaScript變數
- 關於javascript中變數及函式的提升JavaScript變數函式
- 深入理解變數提升和函式提升變數函式
- JS 會有變數提升和函式提升JS變數函式
- 【JavaScript高階進階】JavaScript變數/函式提升的細節總結JavaScript變數函式
- 關於JavaScript變數提升JavaScript變數
- 深入理解js的變數提升和函式提升JS變數函式
- JS變數宣告和函式宣告提升JS變數函式
- 學習JavaScript中的“提升”JavaScript
- 深入淺出JS - 變數提升(函式宣告提升)JS變數函式
- 用預編譯去理解函式宣告提升和變數宣告提升編譯函式變數
- 函式內部的變數提升函式變數
- 淺談JS變數宣告和函式宣告提升JS變數函式
- 深入解析JS變數宣告和函式宣告提升JS變數函式
- [譯] 函式式 JavaScript 快速入門函式JavaScript
- JavaScript中的預解析(變數提升)介紹!JavaScript變數
- JavaScript中的預解析(變數提升)介紹JavaScript變數
- 變數和函式宣告提升,let和var const區別變數函式
- 3.JavaScript函式入門JavaScript函式
- JavaScript入門-函式function(二)JavaScript函式Function
- JavaScript入門-學習筆記(一)JavaScript筆記
- Go 入門 – 包,函式和變數Go函式變數
- JavaScript中變數提升是什麼?如何實現?JavaScript變數
- JavaScript 變數與函式宣告前置JavaScript變數函式
- JavaScript 高階函式快速入門JavaScript函式
- JavaScript是按順序執行的嗎?聊聊JavaScript中的變數提升JavaScript變數
- 《前端實戰總結》之變數提升,函式宣告提升及變數作用域詳解前端變數函式
- JavaScript 判斷變數是否是函式JavaScript變數函式
- JavaScript學習筆記(二)——函式和陣列JavaScript筆記函式陣列
- JavaScript 回顧學習:變數JavaScript變數
- JavaScript新手入門學習系列JavaScript
- javascript效能提升之路JavaScript
- JavaScript之宣告提升JavaScript
- JavaScript --有關提升JavaScript
- JavaScript變數的生命週期:為什麼let不被提升JavaScript變數
- JavaScript學習筆記 - 原生函式JavaScript筆記函式