ES6-let const


1.JS中的塊級做用域

在ES6以前,JS是沒有塊級做用域這個概念的,只有全局做用域和函數內的局部做用域bash

咱們都是知道在 ES6 之前,var 關鍵字聲明變量。不管聲明在何處,都會被視爲聲明在函數的最頂部(不在函數內即在全局做用域的最頂部)。這就是變量提高例如:閉包

function fn() {
    		if(false) {
    			var aa = "hello"
    		}else {
    			console.log(aa)
    		}
    	}
    	fn()//undefined複製代碼

以上的代碼其實是:函數

function fn() {
    		var aa //變量提高
    		if(false) {
    			aa = "hello"
    		}else {
    			//此處訪問aa的值爲undefined
    			console.log(aa)
    		}
    	}
    	fn()//undefined

複製代碼

因此不管如何 aa 都會被建立聲明ui

2.let命令

與var命令的對比,以及let的一些特性:spa


1.let命令聲明一個塊級做用域內的變量語句或表達式,並可選地爲其初始化一個值。指針

如下方式都是合法的:code

let a
let b = 666
let c = 1, d = 'string', e = {}
let f = function () {}
let g = true ? 'true' : 'false'複製代碼

2.let命令只在塊級做用域有效,在代碼塊以外引用會報錯,同時不能重複聲明。對象

{
		    let a = 1
		}
		console.log(a) // ReferenceError a is not defined複製代碼

function foo () {
    		    const a = 4
		    let a = 1
		}
		foo() //SyntaxError: Identifier 'a' has already been declared複製代碼

for(var i = 0; i < 5; i++){
	}
	console.log(i) // 5

        for(let i = 0; i < 5; i++){  
	}
	console.log(i) //ReferenceError: i is not defined
複製代碼

3.let不存在變量提高內存

console.log(a)   // undefined
console.log(b)   // ReferenceError: b is not defined
var a = 1
let b = 1
複製代碼

4作用域

由於let不存在變量提高所以ES6中的let聲明變量時,會在此區域內造成暫時性死區(暫時性死區就是在這個區塊中的變量未聲明以前,對該區塊中的變量的一切調用都會報錯),在該區域內不容許有任何形勢聲明出來的相同變量,因此,let聲明的變量只能在該區域中只出現一次,不能有重複的

a = 1
	let a = 2 
        //ReferenceError: a is not defined
複製代碼
a = 1
	{let a = 2}
	// 以上代碼不會報錯,由於聲明變量的區塊不一複製代碼

let的使用實例

由於let命令的出現,因此JS有了塊級做用域,本來由於做用域問題致使的閉包問題也能夠使用let嗎,清零進行解決,好比如下經典閉包代碼會一次性輸出5個5,但需求是輸出01234

for(var i = 0; i < 5; i++){
  setTimeout(function(){
      console.log(i)
  }, 1000)
}
複製代碼

1.ES6以前的解決辦法,使用一個變量對 i 的值進行暫存

for(var i = 0; i < 5; i++){
  (function(e){
      setTimeout(function(){
          console.log(e)
      }, 1000)        
  })(i)
}
複製代碼

2.出現let後的解決辦法

for(let i = 0; i < 5; i++){
  setTimeout(function(){
      console.log(i)
  }, 1000)
}複製代碼

關於for循環做用域的問題
在for循環中其實是有兩個做用域的,條件設置的圓括號()內是一個父做用域,而代碼塊大括號{}中是一個子做用域,好比下面代碼能夠進行區分

for(let i = 0; i < 5; i++){
  let i = 8
  console.log(i)
}
// 輸出結果是5個8複製代碼

3.const命令

與let命令的用法相似,const命令也是用來聲明一個變量,同時也只能在聲明的塊級做用域中進行使用,它與C#中的const做用相同,只能賦一次值,不能夠修改, 初始化時必須賦值

const命令的特性
1.聲明的時候就必須立刻初始化,不然報錯
以下代碼:

const a;   //SyntaxError: Missing initializer in const declaration

複製代碼

2.聲明的值不能改變,不能從新進行賦值

const a = 10;
const a = 12 //SyntaxError: Identifier 'a' has already been declared
複製代碼

3.與let同樣不存在變量提高

console.log(a) //ReferenceError: a is not defined
const a = 12
複製代碼

4.與let同樣不可重複進行聲明

const a = 1
var a = 1  // SyntaxError: Identifier 'a' has already been declared複製代碼

注意點
1.const聲明的變量的值不能改變實質上是變量指向的內存地址不能改變,所以會有如下兩種狀況


值爲簡單類型:
值保存在變量指向的內存地址上。


值爲複雜類型:
例如對象:值也保存在變量指向的內存地址上,可是不一樣的是,這個內存地址其實是一個指針,指向這個對象,那麼在其實是能夠對這個對象內的屬性進行賦值的,以下代碼:
const a = {b:1}
console.log(a.b)  // 1
a.b = 2
console.log(a.b)  // 2
複製代碼
2.針對上面的問題,若是想讓對象的屬性和值絕對不變,能夠使用Object.freeze方法
const a = Object.freeze({b:1})
console.log(a.b)  // 1
a.b = 2
console.log(a.b)  // 1複製代碼
相關文章
相關標籤/搜索