你們好,我是一隻流浪的kk,當你看到這邊博客的時候,說明你已經進入了ES6學習的領域了,從本篇博客開始,我將會將本身學習到ES6的相關知識進行整理,方便你們參考和學習,那麼我將帶你進入第一節的內容學習let和const命令,本篇博客從三個方面進行全方位解析。javascript
首先咱們須要學習的是let命令的使用,這個使用很是簡單,它其實也是聲明變量的一種方式,和var相比我把它的特色總結了以下四點,一塊兒來看看吧!css
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>let命令的基本用法</title> </head> <body> <script type="text/javascript"> let a=10; var b=20; console.log(a);//10 console.log(b);//20 </script> </body> </html>
咱們看到咱們如今是使用let關鍵字定義變量的,好處的話咱們一步一步進行講解html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>不具有變量提高的能力</title> </head> <body> <script type="text/javascript"> console.log(a);//報錯 let a=10; console.log(b);//undefined var b=20; </script> </body> </html>
在這個案例中,咱們看到使用let關鍵字定義的變量會報錯,而使用var關鍵字定義的變量不會報錯,這一進一步說明let關鍵字定義的變量不具有變量提高的能力,從而也時刻提醒咱們養成良好的編程習慣,任何變量都應該遵循先定義後使用的原則。java
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>let暫時性死區</title> </head> <body> <script type="text/javascript"> if(true){ tep='abc'; console.log(tep);//ReferenceErro let tep; console.log(tep);//undefined tep=123; console.log(tep);//123 } </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>不容許重複聲明</title> </head> <body> <script type="text/javascript"> function bar(){ var a=10 let a=20; let b=10; let b=20; } bar();//報錯 function foo(args){ { let args; } } foo();//不報錯 </script> </body> </html>
在ES5中,咱們只有函數級做用域和全局做用域,這對咱們的開發帶來很大的不方便,例如同事之間的開發,變量的定義可能會相同,這就有可能會形成代碼發生錯誤,我先用一個例子來解釋一下吧!編程
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>塊級做用域</title> </head> <body> <script type="text/javascript"> let arr=[]; for(var i=0;i<10;i++){ arr[i]=function(){ console.log(i); } } arr[6](); </script> </body> </html>
在這裏咱們但願提到當前i,而最終結果是10,變量i
是var
命令聲明的,在全局範圍內都有效,因此全局只有一個變量i,每一次循環,變量i
的值都會發生改變,而循環內被賦給數組a
的函數內部的console.log(i)
,裏面的i
指向的就是全局的i
。也就是說,全部數組a
的成員裏面的i
,指向的都是同一個i
,致使運行時輸出的是最後一輪的i
的值,也就是 10。那麼如何解決呢?數組
咱們再來看另外一個示例閉包
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>塊級做用域</title> <style type="text/css"> div { width: 100px; height: 100px; background: lightgreen; float: left; margin: 20px; font: 30px/100px "microsoft yahei"; text-align: center; } </style> </head> <body> <div>a</div> <div>b</div> <div>c</div> <div>d</div> <div>e</div> <div>f</div> <div>g</div> <div>h</div> <div>i</div> <div>j</div> <script type="text/javascript"> var divs=document.getElementsByTagName("div"); for (var i=0;i<divs.length;i++) { divs[i].onclick=function(){ alert(i); } } </script> </body> </html>
假定頁面中有10個div,咱們每點擊一個div,咱們想要彈出當前div的下標,可是都是彈出10,這就是和咱們前面提到的狀況同樣,函數
解決方案一:使用閉包學習
在沒有ES6以前,咱們解決這類問題一般使用閉包,那麼什麼是閉包呢?之後的章節我會拿出來單獨講,這裏講一下淺顯的字面意思:當一個內部函數被調用,就會造成閉包,閉包就是可以讀取其餘函數內部變量的
spa
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>塊級做用域</title> <style type="text/css"> div { width: 100px; height: 100px; background: lightgreen; float: left; margin: 20px; font: 30px/100px "microsoft yahei"; text-align: center; } </style> </head> <body> <div>a</div> <div>b</div> <div>c</div> <div>d</div> <div>e</div> <div>f</div> <div>g</div> <div>h</div> <div>i</div> <div>j</div> <script type="text/javascript"> var divs=document.getElementsByTagName("div"); for (var i=0;i<divs.length;i++) { divs[i].onclick=(function(n){ return function(){ alert(n); } })(i); } </script> </body> </html>
如今的話,咱們每點擊div一次均可以獲得當前下標(索引)
解決方案二:使用塊級做用域
使用塊級做用能夠快速解決這個問題
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>塊級做用域</title> </head> <body> <script type="text/javascript"> let arr=[]; for(let i=0;i<10;i++){ arr[i]=function(){ console.log(i); } } arr[6](); </script> </body> </html>
在這裏,let聲明的變量僅在塊級做用域內有效,變量i
是let
聲明的,當前的i
只在本輪循環有效,因此每一次循環的i
其實都是一個新的變量,因此最後輸出的是6
。你可能會問,若是每一輪循環的變量i
都是從新聲明的,那它怎麼知道上一輪循環的值,從而計算出本輪循環的值?這是由於 JavaScript 引擎內部會記住上一輪循環的值,初始化本輪的變量i
時,就在上一輪循環的基礎上進行計算
const聲明一個只讀的常量,一旦聲明,常量的值就不能改變,而且用const聲明的常量必須所有大寫,例如PI,MAX,MIN等等
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>const基本用法</title> </head> <body> <script type="text/javascript"> const PI=3.14; console.log(PI); PI=2 </script> </body> </html>
一樣,使用const聲明的變量不得改變值,因此說const一旦聲明變量,就必須馬上初始化,不得留到之後賦值
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>const暫時性死區</title> </head> <body> <script type="text/javascript"> if(true){ const MIN=10 } console.log(MIN); if(true){ console.log(MAX); const MAX=10; } </script> </body> </html>
一樣,使用const聲明的變量也不具有變量提高的能力
一樣const命令也不容許重複聲明,咱們來看下面的例子
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>const不可重複聲明變量</title> </head> <body> <script type="text/javascript"> var message='hello world'; let age=18; const message='你好';//報錯 const age=20;//報錯 </script> </body> </html>
在這裏咱們用const重複聲明變量,控制檯輸出Uncaught SyntaxError: Identifier 'message' has already been declared,因此const也不容許重複聲明變量
在ES5中咱們只有var,function兩種聲明變量的方法,可是在ES6中新增了let,const,import,class等四種聲明變量的方法,因此如今咱們一共有六種聲明變量的方法,在以後的博客中咱們回對import,class進行講解。
本篇博客咱們一共學習了三個知識點,let命令,塊級做用域,const命令,以及總結了let命令和const命令的類似之處,這只是簡單的ES6入門,下一篇博客是講解變量的解構賦值。