var和let
var和let都是用於聲明變量的,但兩者有區別
什麼是變量作用域
變量作用域指的是變量在什麼範圍內是可使用的
var存在的問題
以下面一個實例來展示。在這個示例中有五個button,我們希望點擊任何一個button就會在控制檯打印出我們點擊的是第幾個button。
<body>
<button>按鈕一</button>
<button>按鈕二</button>
<button>按鈕三</button>
<button>按鈕四</button>
<button>按鈕五</button>
<script>
var btns = document.getElementsByTagName("button");
for(var i=0; i<btns.length; i++){
btns[i].addEventListener('click',function(){
console.log("我是第" + i + "個按鈕");
})
}
</script>
</body>
我們發現無論點擊第幾個按鈕,控制檯打印出的都是第五個按鈕。這是因爲 va r在 if 語句和 for 語句中 沒有塊級作用域 引起的問題, var只有全局作用域和函數作用域。
在這個例子中可以看成是for語句執行了五次後(即 i = 5 時退出循環,i 相當於是一個全局變量),纔會進行監聽事件,所以控制檯打印出的都是第五個按鈕
用閉包解決var沒有塊級作用域的問題
函數有自己的作用域,閉包可以立即調用。在閉包中 i 相當於實參,index 相當於形參,形參和實參是互不影響的。
<body>
<button>按鈕一</button>
<button>按鈕二</button>
<button>按鈕三</button>
<button>按鈕四</button>
<button>按鈕五</button>
<script>
//閉包可以解決問題(立即調用),因爲函數有自己的作用域
for(var i=0; i<btns.length; i++){
(function(index){
btns[index].addEventListener('click',function(){
console.log("我是第" + (index+1) + "個按鈕");
})
})(i)
}
</script>
</body>
用let解決var沒有塊級作用域的問題
ES6中的 let 是有 if 和 for 的塊級作用域,效果等同於用閉包解決問題
<body>
<button>按鈕一</button>
<button>按鈕二</button>
<button>按鈕三</button>
<button>按鈕四</button>
<button>按鈕五</button>
<script>
var btns = document.getElementsByTagName("button");
for(let i=0; i<btns.length; i++){
btns[i].addEventListener('click',function(){
console.log("我是第" + (i+1) + "個按鈕"); //注意是i + 1
})
}
</script>
</body>
var和let的區別總結
(1)ES5中var是沒有塊級作用域的,ES6中的let是有塊級作用域的
(2)ES5之前因爲 if 和 for 都沒有塊級作用域的概念,所以在很多時候,我們必須藉助於function的作用域(閉包)來解決應用外面變量的問題
(3)ES6中的 let 是有 if 和 for 的塊級作用域
const
const修飾的標識符爲常量,不可以再次賦值,保證數據的安全性
使用const建議和注意事項
建議: 在開發中,優先使用const,只有需要改變某一個標識符時才使用 let
注意:
(1)使用const修飾的標識符被賦值後不可以修改
//錯誤
const a = 20;
a = 10;
(2)定義時必須初始化賦值
//錯誤,沒有賦值
const a;
(3)常量的含義是指向的對象不能修改,但是可以改變對象內部的屬性
const obj = {
name:'yoyou',
age:18
}
obj = {} //錯誤, 指向新的對象
obj.age = 20; //正確