淺談 var、let 和 const (二)
前言
在ES6之前县貌,JavaScript沒有塊級(jí)作用域(一對(duì)花括號(hào){}即為一個(gè)塊級(jí)作用域)术陶,只有全局作用域和函數(shù)作用域。在前一篇文章中窃这,我們講到了 var瞳别、let 和 const 的塊級(jí)作用域征候,今天我們主要學(xué)習(xí)下變量提升和函數(shù)提升杭攻。
聲明方式 | 變量提升 | 暫時(shí)性死區(qū) | 重復(fù)聲明 | 初始值 | 作用域 |
---|---|---|---|---|---|
var | 允許 | 不存在 | 允許 | 不需要 | 除塊級(jí) |
let | 不允許 | 存在 | 不允許 | 不需要 | 塊級(jí) |
const | 不允許 | 存在 | 不允許 | 需要 | 塊級(jí) |
1. 變量提升
定義:變量提升,即將變量聲明提升到它所在作用域的最開始的部分疤坝。變量聲明在編譯階段被處理兆解,而變量賦值則留在原地等待執(zhí)行。
- var 命令會(huì)發(fā)生“變量提升”現(xiàn)象跑揉,即變量可以在聲明之前使用锅睛,值為undefined埠巨。
- let 和 const不存在變量提升,所聲明的變量一定要在聲明后使用现拒,否則報(bào)錯(cuò)辣垒。
下面給出代碼來解釋
var 命令 — 存在變量提升
console.log(global); // undefined
var global = 'global';
console.log(global); // global
function fn () {
console.log(a); // undefined
var a = 'a';
console.log(a); // a
}
fn();
由于js的變量提升,導(dǎo)致代碼實(shí)際上是按照以下來執(zhí)行的
var global; // 變量提升印蔬,全局作用域范圍內(nèi)勋桶,此時(shí)只是聲明,并沒有賦值
console.log(global); // undefined
global = 'global'; // 此時(shí)才賦值
console.log(global); // global
function fn () {
var a; // 變量提升侥猬,函數(shù)作用域范圍內(nèi)
console.log(a); // undefined
a = 'a';
console.log(a); // a
}
fn();
let — 不存在變量提升
console.log(a);
let a = 1;
//報(bào)錯(cuò)! Uncaught ReferenceError: Cannot access 'a' before initializatio
const — 不存在變量提升
console.log(a);
const a = 1;
//報(bào)錯(cuò)! Uncaught ReferenceError: Cannot access 'a' before initializatio
使用 let 和 const 命令聲明變量之前例驹,該變量是不可用的。
2. 函數(shù)提升
? JavaScript中退唠,創(chuàng)建函數(shù)主要有兩種方式:函數(shù)聲明式和函數(shù)表達(dá)式鹃锈。
- 函數(shù)聲明 (Function Declaration);
// 函數(shù)聲明
function funDeclaration(type){
return type === "Declaration";
}
- 函數(shù)表達(dá)式 (Function Expression)。
// 函數(shù)表達(dá)式
var funExpression = function(type){
return type === "Expression";
}
// 或者let瞧预、const
? 編譯階段屎债,JavaScript 引擎能把 函數(shù)聲明 提升到頂部(即使聲明函數(shù)的代碼在調(diào)用它的代碼后面)
- 函數(shù)聲明提升優(yōu)先于變量聲明 (函數(shù)的提升優(yōu)先級(jí)最高)。
- 函數(shù)聲明提升優(yōu)于函數(shù)表達(dá)式(函數(shù)表達(dá)式實(shí)際上是變量聲明的一種)垢油。
下面給出代碼來解釋
函數(shù)聲明
console.log(fn(1));
function fn(a) {
return a
}
// 1
由于函數(shù)提升扔茅,函數(shù)聲明被置于執(zhí)行環(huán)境頂部,即使調(diào)用函數(shù)的代碼在聲明函數(shù)之前也可以正確訪問秸苗。
函數(shù)表達(dá)式
var
console.log(fn(1));
var fn = function (a) {
return a;
}
//報(bào)錯(cuò)召娜!Uncaught TypeError: fn is not a function
// 相當(dāng)于
var fn;
console.log(fn(1));
fn = function (a) {
return a;
}
let(const和let類似)
console.log(fn(1));
let fn = function (a) {
return a;
}
// 報(bào)錯(cuò)!Uncaught ReferenceError: Cannot access 'fn' before initialization