let命令:
基本用法:
-
let定義:
用來聲明變量。它的用法類似于var,但是所聲明的變量,只在let命令所在的代碼塊內有效。
<script> //let代碼塊內部定義的變量,與var進行對比 { var a =12; let b =10 console.log(a) //-----12 console.log(b) //-----10 } console.log(a) //-----12 console.log(b) //----- not undefined </script> -
for循環(huán)很合適使用let命令。在for循環(huán)體內有效,在循環(huán)體外引用就會報錯。//let 使用在for循環(huán)里面使用不能在外面調用 for(let i=0;i<=5;i++){ console.log(i); //------1,2,3,4,5 } console.log(i); //----- not undefined -
let在for循環(huán)添加事件中最典型的使用方式
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <button>1</button> <button>2</button> <button>3</button> <button>4</button> /*創(chuàng)建六個按鈕*/ <button>5</button> <button>6</button> <script type="text/javascript"> // let局部引用 var btns = document.getElementsByTagName('button'); for(let i=0;i<btns.length;i++){ //--- 在本行中如果將let更改為var 則點擊所有的按鈕都會打印數字六,如果使用let,則會根據點擊的數字的順序一次打印,起始數字為0 btns[i].onclick =function(){ console.log(i) } } </script> </body> </html> -
/ let在for循環(huán)作為循環(huán)參數的時候其實是兩個作用域大括號里面是一個子作用域如果里面再次定義余循環(huán)參數相同的變量,則不會產生相互影響
for(let i=0;i<=3;i++){ let i ="a"; console.log(i); //----4個a }
不存在變量提升:
-
let命令改變了語法行為,它所聲明的變量一定要在聲明后使用,否則報錯。
console.log(a) // ----not defined let a = 12;
暫時性死區(qū):
-
ES6 明確規(guī)定,如果區(qū)塊中存在
let和const命令,這個區(qū)塊對這些命令聲明的變量,從一開始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會報錯。總之,在代碼塊內,使用
let命令聲明變量之前,該變量都是不可用的。這在語法上,稱為“暫時性死區(qū)”(temporal dead zone,簡稱 TDZ)。// 暫時性死區(qū) let 不允許重復定義一個變量 // 大括號括起來的稱之為塊作用域 有循環(huán),seitch 結構 if結構 for(let i =0 ;i<3;i++){ console.log(i) let i = '123'; } // 暫時性死區(qū) function bar (x=y,y=2){ return[x,y]; } ba=[];
不允許重復定義:
-
暫時性死區(qū) let 不允許重復定義一個變量
for(let i =0 ;i<3;i++){ console.log(i) let i = '123'; }
塊級作用域:
-
ES5 只有全局作用域和函數作用域,沒有塊級作用域,這帶來很多不合理的場景。
第一種場景,內層變量可能會覆蓋外層變量。
if(true){ function say(){ console.log(1) } } say(); -
ES6 引入了塊級作用域,明確允許在塊級作用域之中聲明函數。ES6 規(guī)定,塊級作用域之中,函數聲明語句的行為類似于let,在塊級作用域之外不可引用。
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> // Your ES6 code if(true){ function say(){ console.log(1) } } say(); </script>在這里插入圖片描述
注意:為了減輕因此產生的不兼容問題,ES6 在附錄 B里面規(guī)定,瀏覽器的實現可以不遵守上面的規(guī)定,有自己的行為方式。
- 允許在塊級作用域內聲明函數。
- 函數聲明類似于var,即會提升到全局作用域或函數作用域的頭部。
- 同時,函數聲明還會提升到所在的塊級作用域的頭部
瀏覽器環(huán)境:
? Babel 也可以用于瀏覽器環(huán)境,使用@babel/standalone模塊提供的瀏覽器版本,將其插入網頁。
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
// Your ES6 code
</script>
const命令:
基本用法:
-
const定義:
聲明一個只讀的常量。一旦聲明,常量的值就不能改變。const一旦聲明變量,就必須立即初始化,不能留到以后賦值
const PI = 3.1415; console.log( PI ) // ---3.1415 PI = 3; // --- TypeError: Assignment to constant variable.const foo; //--- SyntaxError: Missing initializer in const declaration //表示,對于const來說,只聲明不賦值,就會報錯。 const的作用域與let命令相同:只在聲明所在的塊級作用域內有效。實例與上let例子相似const命令聲明的常量也是不提升,同樣存在暫時性死區(qū),只能在聲明的位置后面使用。-
本質:
const實際上保證的,并不是變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。對于簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,因此等同于常量。但對于復合類型的數據(主要是對象和數組),變量指向的內存地址,保存的只是一個指向實際數據的指針,const只能保證這個指針是固定的(即總是指向另一個固定的地址),至于它指向的數據結構是不是可變的,就完全不能控制了。因此,將一個對象聲明為常量必須非常小心。
const foo = {}; // 為 foo 添加一個屬性,可以成功 foo.prop = 123; foo.prop // 123 // 將 foo 指向另一個對象,就會報錯 foo = {}; // TypeError: "foo" is read-only
? 注:常量foo儲存的是一個地址,這個地址指向一個對象。不可變的只是這個地址,即不能把foo指向另一個地址,但對象本身是可變的,所以依然可以為其添加新屬性。