第二章 let和const

1.let和const

1.let

let用于聲明變量,類似于var,但是所聲明的變量只在let命令所在的代碼塊內(nèi)有效。

for循環(huán)中的計數(shù)器非常適合使用let命令。
for(let i=0;i<10;i++){
.......
}
如果在外面打印i的haul,會報錯的,上面的代碼只在for循環(huán)內(nèi)有效,在循環(huán)體外就會報錯

var a=[];
for(var  i=0;i<1o;i++){
a[i]=function(){
alert(i)
 }
}

a[6]()=10;
變量i是var聲明的,在全局范圍內(nèi)都有效,所以全局只有一個變量i。每一次循環(huán),數(shù)組a的成員中的i指向的都是同一個i,導(dǎo)致運行時輸出的是最后一輪的i值,也就是10;

如果使用let,聲明變量僅僅在作用域內(nèi)有效,最后將輸出6

1..1.1.2不存在變量提升

var聲明可以有變量提升,即變量可以在聲明之前使用,打印的是undefined,let不存在這種變量提升,會直接報錯。

1.1.3

暫時性死區(qū)3
只要塊級作用域內(nèi)存在let命令,他所聲明的變量就綁定這個區(qū)域,不在受外部影響,代碼中存在全局變量,但是又在塊級作用域內(nèi)let聲明了一個局部變量,相同的變量名,導(dǎo)致后者綁定的這個塊級作用域,所以在let變量聲明前,會報錯
ES6明確規(guī)定,如果區(qū)塊中存在let和const命令,則這個區(qū)塊對這些命令聲明的變量一開始就形成封閉作用域,只要在變量之前使用這些變量,就會報錯。
總之,在代碼塊,使用let命令聲明變量之前,改變量都是不可用的,屬于“暫時性死區(qū)”。
暫時性死區(qū)的本質(zhì)就是只要進入當(dāng)前作用域,所要使用的變量就已經(jīng)存在,但是不可獲取,只有等到變量聲明的那一刻,才可以使用和獲取變量

1.1.4不允許重復(fù)聲明

let不允許在相同的作用域內(nèi)重復(fù)聲明同一個變量

2.2塊級作用域

2.1為什么需要塊級作用域

ES5只有全局作用于域和函數(shù)作用域

第一種場景:內(nèi)層變量可能會覆蓋外層變量。

var temp=new Date();
function f(){
   alert(temp)
   if(false){
 var temp ="hello"  
 }
}
f()//undefined
以上代碼的愿意是,if代碼塊的外部使用外層的temp變量,內(nèi)部的使用內(nèi)部的temp變量,但是在函數(shù)f執(zhí)行的后,輸出的設(shè)計undefined,原因在于變量提升覆蓋了外層的temp變量。

第二種場景:用來技術(shù)的循環(huán)變量泄露為全局變量
var s="hello";
for (var i=0;i<s.length;i++){
   alert(s[i])   
}
 console.log(i);
上面的代碼中,變量i只用來控制循環(huán),但是循環(huán)結(jié)束后,他沒有消失。而是泄露成了全局變量

2..2.2ES6的塊級作用域

let實際上為javaScript新增了塊級作用域
ES6允許塊級作用域的任意嵌套

{{{{{let  a="kk}}}}}
上面一共有五層作用域,外層的作用域無法讀取內(nèi)層的作用域的變量
{{
{let k="ggg"}
  console.log(k)會報錯,因為不在同一個作用域內(nèi)
}}

{{{
{let  m="hello"}
{let m="hello"}
內(nèi)層作用域可以定義外層作用域的同名變量
}}}

2.2.3塊級作用域與函數(shù)聲明

Es5規(guī)定,函數(shù)只能在頂層作用域和函數(shù)作用域之中聲明,不能在塊級作用域聲明
ES6引入了塊級作用域,明確允許在塊級作用域之中聲明函數(shù)。ES6規(guī)定,在塊級作用域之中,函數(shù)聲明語句的行為類似于let,在塊級作用域之外不可引用。

ES6規(guī)定:

  1. 允許在會計作用與內(nèi)聲明函數(shù)
    2.函數(shù)聲明類似于var,即會提升到全局作用域或者函數(shù)作用域的頂部
    3.同時。函數(shù)聲明還會提升到所在的塊級作用域的頭部。
    考慮到環(huán)境導(dǎo)致的行為差異太大,應(yīng)該避免在塊級作用域內(nèi)聲明函數(shù),如果確實需要,也應(yīng)該寫成函數(shù)表達式的形式,而不是函數(shù)聲明的形式,
    函數(shù)表達式:let f=function(){
    ....
    }
    函數(shù)聲明:function f(){
    ....
    }

另外:Es6的塊級作用域允許聲明函數(shù)的規(guī)則只在使用大括號的情況下成立,如果沒有使用大括號,就會報錯。必須將函數(shù)聲明放在大括號內(nèi)

if(true){
   function f(){
    ....
   }
}

應(yīng)該是這種寫法

2.2.4do表達式

本質(zhì)上,塊級作用域是一個語句,將多個封裝在一起,沒有返回值。

{
let  t= f();
t=t*t+1;
}
  上面,塊級作用域?qū)蓚€語句封裝在一起,但是,在塊級作用域之外,沒有辦法得到t的值,因為塊級作用域不返回值,除非t是全局變量。
現(xiàn)在使用do表達式,在塊級作用域上之前加上do
let x={
    let t=f();
   t*t+1;
}
上面的代碼中,變量x會得到整個塊級作用域的返回值

2.3const命令

2.3.1

const聲明了一個只讀的變量,一旦聲明,常量的值就不能更改。
對于const來說,只聲明不賦值就會報錯
const命令聲明的變量也不會提升,同樣存在暫時性死區(qū),只能在聲明后使用。
使用const聲明常量也與let一樣,不可重復(fù)聲明。

2.3.2

const實際上就是變量指向的那個內(nèi)存地址不得改動。對于簡單類型的數(shù)據(jù)(數(shù)值、字符串、布爾值),值就保存在變量指向的內(nèi)存地址中,因為等同于常量,對于復(fù)合類型的數(shù)據(jù)(對象和數(shù)組)來說,變量指向的內(nèi)存地址只是一個指針,const能保證這個指針是固定的,至于他的數(shù)據(jù)結(jié)構(gòu)是不是可變的。這是不能控制的,因此,將一個對象聲明為常量時必須小心。

2.3.3ES6聲明變量的6種方法

ES5只有兩種聲明變量的方法,使用Var和function;
ES6除了使用let和const,還會使用import和class命令,所以,es6一共有6個聲明變量的方法。

2.4頂層對象的屬性

頂層對象在瀏覽器環(huán)境中指的是window對象,在Node環(huán)境中指的是global對象,在es5中,頂層對象的屬性與全局變量是等價的。
es6規(guī)定var和function聲明的變量依舊是頂層對象的屬性,但是另一方面,let、const、calss、聲明的全局的變量不屬于頂層的屬性,也就是說,從es6開始,全局變量 將逐步與頂層對象的屬性隔離。

var  a=1;
如果在Node的環(huán)境中,可寫成global.a
或者采用通用方法,this.a
window.a//1
let b=1;
window.b//undeifined;
上面,全局變量a由var命令聲明,所以他是頂層對象的屬性;全局變量b是由let聲明,所以他不是頂層對象的屬性,返回的是undefine

2.5global對象

在瀏覽器中,頂層對象是window,但在Node和web和web worker是沒有window
在node中,頂層對象是global,但其他的環(huán)境都不支持
。。。同一段代碼為了能夠在各種環(huán)境中都有取到的頂層對象,一般使用this變量,但是也有局限性。
1.在全局環(huán)境中,this會返回頂層對象,但是,在node模塊和Es6模塊中,this返回的是當(dāng)前模塊。
2.對于函數(shù)中this,如果函數(shù)不是作為對象對的方法運行,而是單純的作為函數(shù)運行,this會指向頂層對象,但是,在嚴格模式下,this會返回undefined。
3.不管是嚴格模式,還是普通模式,New Function(“return this”)() 總會返回全局對象。但是,如果瀏覽器用了CSP,那么eval 、New Function這些方法都無法使用。
綜上所述,很難找到一種方法可以在所有情況下都取到頂層對象。以下兩種勉強可以使用的方法。

方法一:
( typeof  window !==="undefined"?window:(typeof self !=='undefined'))

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容