ES6
let 命令
- ES6新增了 let 命令,用于聲明變量,其用法類似于var
- let 命令聲明的變量僅僅在其所在代碼塊生效
let 聲明的變量只在其所在代碼塊有效
{
let a=1
var b=10
}
console.log(a) // ReferenceError
console.lob(b) // 10
for循環計數器,就很適合用 let 命令
for(let i=0;i<arr.length;i++){
console.log(i)
}
不存在變量提升
變量一定要在聲明后使用
console.log(foo) //ReferenceError
let foo=2
暫時性死區
塊級作用域中,let命令所聲明的變量,從一開始就形成封閉的作用域。
只要在聲明之前使用這些變量,就會報錯
if(true){ //塊級作用域中
tmp='abc' //ReferenceError
console.log(tmp) //ReferenceError
let tmp //暫時性死區結束
console.log(tmp) //undefined
tmp=123
console.log(tmp) //123
}
不允許重復聲明
let不允許在相同作用域內重復聲明同一個變量
塊級作用域
為什么需要塊級作用域
ES5沒有塊級作用域,這帶來很多不合理的場景
- 場景一:內層變量可能會覆蓋外層變量
var tmp = new Date() //外層變量
function f() {
console.log(tmp)
if(false){
//內層變量,若存在塊級作用域,則該tmp=123只在此塊級作用域生效
var tmp = '123'
}
}
f() //undefined
輸出為undefined
說明內層tmp覆蓋了外層tmp變量,這是由于var的變量提升導致的
- 場景二:循環變量泄露,成為全局變量
var s = 'hello'
for (var i = 0; i < s.length; i++) {
console.log(s[i])
}
console.log(i)
變量i用來控制循環,但循環結束之后沒有消失,成為全局變量
ES6的塊級作用域
let為javascript新增了塊級作用域
function f(){
let n=5
if(true){
let n=1 //n=1僅僅在該代碼塊有效
}
console.log(n) //5
}
塊級作用于的出現,使得立即執行匿名函數(IIFE)不再必要了
// IIFE寫法
(function (){
var tmp = ...
...
}())
// 塊級作用域寫法
{
let tmp = ...
...
}
ES6規定:函數本身的作用域在其所在的塊級作用域之內
function f() {
console.log('outside')
}
(function() {
if (false) {
function f() { console.log('inside') }
}
f()
}())
- ES5運行:
理論上
inside
,但在 webstorm 是undefined
。都存在變量提升
- ES6運行:
outside
const 命令
const 用來聲明常量。一旦聲明,其值不能改變
const 聲明的變量,在聲明時必須初始化
只在聲明的塊級作用域內有效
常量不提升,存在暫時性死區,只能在聲明后使用
不可重復聲明常量
注意:復合類型的變量。const 命令只是保證指向的地址不變,不保證改地址數據不變
const foo = {}
foo.prop = 123
console.log(foo) // Object {prop: 123}
全局變量對象的屬性
瀏覽器:window
Node.js:global
- var function 聲明的全局變量是全局對象的屬性
- let const class 聲明的全局變量不是全局對象的屬性
注意:是全局變量,即在最外層聲明的變量
var a=1
window.a //1
let b=2
window.b //undefined