ES6學(xué)習(xí)教程之塊級作用域詳解
前言
眾所周知ES5之前javascript語言只有函數(shù)作用域和全局作用域,使用var來聲明變量,var聲明的變量還存在變量提升使人困惑不已。我們先來復(fù)習(xí)一下ES5的var聲明,再對比學(xué)習(xí)let和const 。
var
var聲明之函數(shù)作用域和全局作用域。
來段代碼體會一下:
function getName() { if (1 + 1 === 2) { var name = 'xixi'; } console.log(name); } getName();//xixi
在c或java語言中name本應(yīng)該只在if塊中使用的,但是在if的外面也可以訪問到,這個(gè)就是 js沒有塊級作用域的一種體現(xiàn)。這個(gè)弊端在for循環(huán)中體現(xiàn)的十分明顯:
for (var i = 0; i < 10; i ++) { // ... } console.log(i);// 10
var i的本意是聲明個(gè)臨時(shí)變量i,用來遍歷數(shù)組等,本不應(yīng)該在for循環(huán)的外部訪問到,但現(xiàn)在卻可以被訪問到你說鬧不鬧心?好一點(diǎn)的程序員會用立即執(zhí)行函數(shù)來模擬塊級作用域,原來的我會注意一下盡量不使用相同的變量名😎。
(function() { for (var i = 0; i < 10; i ++) { // ... } })(); console.log(i);// undefined
以上:大家知道了 js 沒有塊級作用域。
變量可以重復(fù)聲明
var name = 'xixi'; console.log(name);// xixi var name= '一步'; console.log(name);// 一步
不報(bào)錯(cuò),困惑不困惑,這個(gè)就是變量可以重復(fù)聲明。
變量提升
function getName() { console.log(name); var name = 'xixi'; // ... } getName();// undefined
console.log
打印name為undefined。為啥不報(bào)錯(cuò)呢,對于一直使用js語言的人來說這個(gè)現(xiàn)象還好理解,如果是后臺轉(zhuǎn)前端的人來說估計(jì)得罵人了。這就是所謂的變量提升。簡單的向大家解釋一下吧。
var name = 'xixi';
這是一條被我們寫爛了的語句,包含兩個(gè)過程:var name; name = 'xixi';
分別為變量聲明和變量初始化。
變量提升: 無論變量聲明var name;處于什么位置,都會被提到作用域的頂部進(jìn)行。
let
ES6為讓變量生命周期更加可控,引入兩個(gè)非常好的特性let、const。塊級作用域、不能重復(fù)聲明、臨時(shí)性死區(qū)等特性用來解決 var 變量存在的種種問題。
塊級作用域
function getName4ES6() { if (1 + 1 === 2) { let name = 'xixi'; } console.log(name); } getName4ES6(); // undefined
終于在{}外面訪問不到name了。for循環(huán)也變的簡單了,大家試一下將for循環(huán)的var換成 let.
同一塊級作用域內(nèi)不能重復(fù)聲明變量
function redefineValue() { let name = 'xixi'; let name = '一步'; } redefineValue();// Uncaught SyntaxError: Identifier 'name' has already been declared
重復(fù)聲明會報(bào)錯(cuò)
{ let name = 'xixi'; console.log(name);// xixi { let name = 'yibu'; console.log(name); // yibu } }
注意: 在 ES6中,{}就是一個(gè)塊級作用域。
臨時(shí)性死區(qū)
function getName4ES6() { console.log(name); for (let i = 0; i < 10; i ++) { } let name = 'xixi'; // ... } getName4ES6();// Uncaught ReferenceError: name is not defined
在上文ES5中,name還會存在變量提升,值為undefined。ES6中又報(bào)錯(cuò)了。怎么解釋呢?。。。。這個(gè)就是臨時(shí)性死區(qū)的概念,在作用域塊中不可以在變量聲明前就使用變量,若使用是會出錯(cuò)的。
javascript引擎在發(fā)現(xiàn)變量聲明時(shí),要么將變量聲明提升到作用域的頂部(var聲明變量時(shí)),要么將變量放在臨時(shí)性死區(qū)中(let、const聲明變量時(shí)),訪問臨時(shí)性死區(qū)中的變量會觸發(fā)運(yùn)行時(shí)錯(cuò)誤。
const
const和let同樣具有塊級作用域,不能重復(fù)聲明,臨時(shí)性死區(qū)的概念。它還具有兩個(gè)特有的特性:聲明的同時(shí)必須初始化、變量引用不可以改變。
聲明的同時(shí)必須初始化
const name;//Uncaught SyntaxError: Missing initializer in const declaration
不賦值,就報(bào)錯(cuò)。這個(gè)也很好理解const的本意就是用來定義常量,不可變的值。若不在聲明時(shí)給出初始值以后就再也沒有機(jī)會了。
值不可變
const name = 'x9x9'; name = 'yyy';// Uncaught SyntaxError: Invalid or unexpected token
那么對象會怎樣呢?
const person = { name: 'lala', age: 40 }; person = {};// VM1042:6 Uncaught TypeError: Assignment to constant variable. at <anonymous>:6:8
引用是不可變的,那我們在看看對象的屬性值是什么情況吧~
person.name = 'yoyo'; console.log(person);// {name: "yoyo", age: 40}
沒有報(bào)錯(cuò),對象引用不可改變,對象屬性可以變更。
let vs const
大家可能會困惑,什么時(shí)候使用let,什么時(shí)候使用const。let能做的const好像都可以。網(wǎng)上有一種流行做法:能用const就絕不用let,簡單粗暴,不過很好用。
個(gè)人看法:若變量在后續(xù)方法中會被改變,就使用let。一些常量聲明使用const, const聲明的變量名全部大寫。代碼中的變量,如果是let聲明的就代表其可變,若是const聲明的,不論是簡單數(shù)據(jù)類型還是引用類型變量就都不要改變它的值。這樣,程序會更加的健壯,大家合作起來也比較方便。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
javascript中數(shù)組的定義及使用實(shí)例
這篇文章主要介紹了javascript中數(shù)組的定義及使用方法,實(shí)例分析了數(shù)組的定義及使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-01-01深入探究JavaScript中for循環(huán)的效率問題及相關(guān)優(yōu)化
這篇文章主要介紹了JavaScript中for循環(huán)的效率問題及相關(guān)優(yōu)化,文中談到了Underscore.js庫及循環(huán)在各個(gè)瀏覽器js解釋器下的表現(xiàn),需要的朋友可以參考下2016-03-03一個(gè)友好的.改善的 Object.prototype.toString的實(shí)現(xiàn)
一個(gè)友好的.改善的 Object.prototype.toString的實(shí)現(xiàn)...2007-04-04js+canvas實(shí)現(xiàn)動態(tài)吃豆人效果
本文主要介紹了js+canvas實(shí)現(xiàn)動態(tài)吃豆人效果的實(shí)例。具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-03-03js實(shí)現(xiàn)按鈕開關(guān)單機(jī)下拉菜單效果
這篇文章主要介紹了js實(shí)現(xiàn)按鈕開關(guān)單機(jī)下拉菜單效果,代碼簡單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-11-11JavaScript中防抖和節(jié)流的實(shí)戰(zhàn)應(yīng)用記錄
防抖與節(jié)流都是用來限制用戶頻發(fā)觸發(fā)事件的機(jī)制,下面這篇文章主要給大家介紹了關(guān)于JavaScript中防抖和節(jié)流的實(shí)戰(zhàn)應(yīng)用,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04uni-app使用uploadFile上傳多張圖片的具體實(shí)現(xiàn)
在微信小程序中不支持多張圖片上傳,需要做循環(huán)實(shí)現(xiàn)多張圖片上傳,下面這篇文章主要給大家介紹了關(guān)于uni-app使用uploadFile上傳多張圖片的具體實(shí)現(xiàn),需要的朋友可以參考下2023-04-04JavaScript設(shè)置彈出式獨(dú)立窗口頁面和window的方法舉例詳解
window.open是網(wǎng)頁中經(jīng)常遇到的彈出窗口代碼,不是網(wǎng)絡(luò)中比較反感的那類彈出代碼,下面這篇文章主要給大家介紹了關(guān)于JavaScript設(shè)置彈出式獨(dú)立窗口頁面和window的方法,需要的朋友可以參考下2024-01-01javascript制作的網(wǎng)頁側(cè)邊彈出框思路及實(shí)現(xiàn)代碼
這篇文章主要介紹了javascript制作的網(wǎng)頁側(cè)邊彈出框思路及實(shí)現(xiàn)代碼,需要的朋友可以參考下2014-05-05JavaScript實(shí)現(xiàn)日期格式化的方法匯總
日期是許多JavaScript應(yīng)用程序的基本組成部分,無論是在網(wǎng)頁上顯示當(dāng)前日期還是處理用戶輸入以安排事件,本文將探討在?JavaScript?中格式化日期的各種技術(shù),希望對大家有所幫助2023-06-06