JavaScript作用域

本篇文章的重點(diǎn)是學(xué)習(xí)如何使用 JavaScript 新的語(yǔ)法 let 聲明變量以及作用域的理解。

1、let 基本介紹

? ? JavaScript ES6 引入了 let ,用 let 聲明變量,解決了 JavaScript 沒(méi)有塊級(jí)作用域的問(wèn)題(注意:ES3 的 catch 分句會(huì)產(chǎn)生塊作用域)

? ? 對(duì)于新手而言,ES6 之前,JavaScript 沒(méi)有塊級(jí)作用域,使用 var 聲明變量,會(huì)讓 JavaScript 不易懂和難以調(diào)試,用不好甚至有內(nèi)存泄露的可能。至于為什么會(huì)這樣,主要是沒(méi)有清楚作用域的概念,下面首先了解一下什么是作用域。

2、作用域介紹

? ? 1)作用域

? ? ? ? 作用域簡(jiǎn)單的來(lái)說(shuō),就是一套尋找變量的規(guī)則,用于確定在何處以及如何查找變量。 在 ES6 代碼之前,只有全局作用域和函數(shù)作用域。

? ? 當(dāng)一個(gè)塊或函數(shù)嵌套在另一個(gè)函數(shù)時(shí),就發(fā)生了作用域嵌套,如下所示,就有三個(gè)嵌套作用域:

? ?function foo(a) {

? ? ? ? ? ? var b = a * 2;

? ? ? ? ? ? function bar(c) {

? ? ? ? ? ? ? ? ? ? console.log (a, b, c) ;

? ? ? ? ? ? }

? ? ? ? ? ? bar (b * 3);

? ? }

? ? foo ( 2 ) ; // 2, 4 , 12

// 1、全局作用域,其中有一個(gè)標(biāo)識(shí)符:foo;

// 2、? foo 創(chuàng)建的函數(shù)作用域,其中有三個(gè)標(biāo)識(shí)符:a ,bar 和 b

// 3、bar 創(chuàng)建的函數(shù)作用域,其中有一個(gè)標(biāo)識(shí)符:c?

? ?如何在嵌套作用域中尋找變量?

? ? 引擎從當(dāng)前作用域開(kāi)始查找變量,如果找不到,就會(huì)向上一級(jí)繼續(xù)查找。當(dāng)?shù)诌_(dá)最外層全局作用域時(shí),無(wú)論找到還是沒(méi)有找到,查找過(guò)程中都會(huì)停止。

2)全局作用域和函數(shù)作用域

? ? 使用 var 聲明變量時(shí),如果在函數(shù)外聲明,就是全局變量,任何函數(shù)都可以進(jìn)行使用,這就是全局作用域查找。

? ? 如果在函數(shù)內(nèi)使用 var 聲明變量,就是函數(shù)作用域查找,只能在函數(shù)內(nèi)部進(jìn)行訪問(wèn),外部不能進(jìn)行訪問(wèn):

????var a = 12; //全局作用域都能進(jìn)行訪問(wèn)

????function myFunction () {

? ? ? ? alert ( a );? // 12

? ? ? ? var b = 13 ;?????

? ? ? ? if ( true ) {

? ? ? ? ? ? var c = 14 ; // 函數(shù)內(nèi)部可以訪問(wèn)

? ? ? ? alert ( b ) ; //13

? ? ? ? }

? ? ? ? alert ( c ) ;? //14

? ? }

? ? myFunction ();

? ? alert ( b ) ;? //undefined

? ? 3)塊級(jí)作用域

在 ES6 中引入了 let ,避免了有 var 聲明變量的一些問(wèn)題,讓變量和函數(shù)不僅可以屬于所處的作用域,也可以屬于某個(gè)代碼塊 (通常是 { ... } 內(nèi)部) , 另外,在塊級(jí)作用域定義的變量,塊級(jí)作用域外是無(wú)法訪問(wèn)的。

?let a = 12 ; //全局作用域 , 可以訪問(wèn)

? function myFunction () {

? ? ? ? console.log ( a ) ; // 12

? ? ? ? let b = 13;

? ? ? ? if ( true ) {

? ? ? ? ? ? let c = 14;

? ? ? ? ? ? alert ( b );? //13

? ? ????}

? ? ? ? alert ( c ) ; //undefined {}外,因此無(wú)法訪問(wèn)

? ? }

myFunction ();

alert( b ) ; // undefined { } 外,因此無(wú)法訪問(wèn)


3、var 和 let 的區(qū)別

1) let 和 const 不存在變量提升機(jī)制

? ? 創(chuàng)建變量的六種方式中:var / function 有變量提升, 而 let / const / class / import 都不存在這個(gè)機(jī)制

2)var 允許重復(fù)聲明,而 let 不允許重復(fù)聲明

? ? 在相同的作用域 ( 或執(zhí)行上下文中)

? ? —— 如果使用 var / function 關(guān)鍵字聲明變量并且重復(fù)聲明, 是不會(huì)有影響的 (聲明第一次之后,之后再遇到就不會(huì)再重復(fù)聲明了)

? ? —— 但使用 let / const 就不行, 瀏覽器會(huì)校驗(yàn)當(dāng)前作用域中是否已經(jīng)存在這個(gè)變量了,如果存在了,則再次基于 let 等重新聲明就會(huì)報(bào)錯(cuò)

3)let 會(huì)產(chǎn)生塊級(jí)作用域

4、重復(fù)定義變量的問(wèn)題

用 var在同一個(gè)作用域重復(fù)定義變量,后者將會(huì)覆蓋前者聲明的變量的值,如下:

var a = 0 ;?

var a = 1 ;

alert ( a ) ; // 1

function myFunction ( ) {

? ? ? ? var b = 2;?

? ? ? ? var b = 3;

? ? ? ? alert ( b ); // 3;

? ? }

? ? myFunction ( );

使用 let 在同一作用域下重復(fù)定義變量,將會(huì)產(chǎn)生 Syntaxerror 的錯(cuò)誤,如下:

let a = 0;

let a = 1; // SyntaxError

function myFunction ( ) {

? ? ? ? let b = 2;

? ? ? ? let b = 3 ; // SyntaxError

? ? ? ? if ( true ) {

? ? ? ? ? ? let c = 4;?

? ? ? ? ? ? let c = 5 ; // SyntaxError

? ? ? ? ? ? }

? ? }

myFunction();

如果你在嵌套作用域里進(jìn)行重新定義變量 , 雖然變量名相同 , 但是不是同一變量,如下:

var a = 1;

var b = 2;?

function myFunction ( ) {

? ? ? ? var a = 3; // different variable

? ? ? ? let b? = 4 ; //different variable

? ? ? ? if ( true ) {

? ? ? ? ? ? var a = 5 ; // overwritten

? ? ? ? ? ? let b = 6 ; //different variable

? ? ? ? ? ? console.log (a ); //5

? ? ? ? ? ? console.log ( b ); //6

? ? ? ? }

? ? ? ? console.log ( a ) ; //5?

? ? ? ? console.log ( b ) ; // 4

? ? }

? ? myFunction ( );

console.log ( a );

console.log( b );

5、提升概念的問(wèn)題

直覺(jué)上會(huì)認(rèn)為編譯器會(huì)由上到下一行行的執(zhí)行,起始并不正確,函數(shù)聲明和變量聲明都會(huì)被提升 ( 使用 var 聲明變量 , let 聲明變量將不會(huì)被提升 )。函數(shù)首先會(huì)被提升 , 然后才是變量提升。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容