成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

es6塊級(jí)作用域

cnTomato / 628人閱讀

摘要:塊級(jí)作用域存在于兩個(gè)地方函數(shù)內(nèi)部。如下例應(yīng)該返回創(chuàng)建數(shù)組的構(gòu)造函數(shù)即這是數(shù)組返回這是數(shù)組從上例,我們可以知道即使全局作用域中已經(jīng)定義了變量或者已經(jīng)存在了屬性,但我們之后定義的變量則會(huì)覆蓋之前已經(jīng)定義好的或者已經(jīng)存在的變量屬性。

一.var 聲明與變量提升機(jī)制

JavaScript中使用var定義一個(gè)變量,無論是定義在全局作用域函數(shù)函數(shù)的局部作用域中,都會(huì)被提升到其作用域的頂部,這也是JavaScript定義變量的一個(gè)令人困惑的地方。由于es5沒有像其它類C語言一樣的塊級(jí)作用域,因此es6增加了let定義變量,用來創(chuàng)建塊級(jí)作用域。

我們來看一個(gè)var定義變量的示例:

function   setName(){
    if(condition){
       var name = "loho";
       console.log(name);
    }else{
       console.log(name);
    }
}

var student = "eveningwater";
setName();

以上代碼可以理解成如下:

var student;
function setName(){
   var name;
   if(condition){
       name = "loho";
       console.log(name);//loho
   }else{
      console.log(name);//undefined
   }
}
student = "eveningwater";
setName();
二.塊級(jí)聲明

塊級(jí)聲明意在指定一個(gè)塊級(jí)作用域,使得塊級(jí)作用域中所定義的變量無法再全局被訪問到,塊級(jí)作用域也被稱為詞法作用域。

塊級(jí)作用域存在于兩個(gè)地方:

函數(shù)內(nèi)部。

指定代碼塊中。(即"{"和"}"之間的區(qū)域)

1.let 聲明

let聲明同var聲明用法一致,唯一的區(qū)別在于,let聲明將變量限制在一個(gè)塊內(nèi),這樣就形成了一個(gè)塊級(jí)作用域,因此也就不會(huì)存在變量的提升了。

例如前面的示例,我們可以寫成如下:

let stundent = "eveningwater";
function setName(){
    if(condition){
        let name = "loho";
       console.log(name);//loho
    }else{
       //如果條件為false執(zhí)行到這里
       console.log(name);//不返回值
    }
}
setName();

2.禁止重聲明

在使用let定義變量之前如果已經(jīng)聲明了相同的變量,就會(huì)報(bào)錯(cuò)。因此不能重復(fù)聲明變量。如以下示例:

var name = "eveningwater";
//報(bào)錯(cuò),重復(fù)聲明
let name = "loho";

當(dāng)然這兩個(gè)變量必須是在同一個(gè)作用域中,如果是不同作用域中,則不會(huì)報(bào)錯(cuò)。但有可能會(huì)遮蔽第一次聲明的變量。如以下示例:

var name = "eveningwater";
if(condition){
   //不會(huì)報(bào)錯(cuò)
   let name = "loho";
}
3.const聲明

使用const標(biāo)識(shí)符所聲明的變量必須要初始化,因此這個(gè)聲明的就是一個(gè)常量。如下例:

const name="eveningwater";//正確
const name;//錯(cuò)誤,未初始化

const聲明同let聲明一樣,也是創(chuàng)建了一個(gè)塊級(jí)作用域,在這個(gè)塊級(jí)作用域之外是無法訪問到所聲明的變量的。換句話說,就是const所聲明的變量不會(huì)有變量提升機(jī)制。如下例:

if(condition){
        const name = "eveningwater";
        console.log(name);//"eveningwater"
}
//錯(cuò)誤
console.log(name);

同樣的const也不能重復(fù)聲明,如下例:

var name = "eveningwater";
//錯(cuò)誤,不能重復(fù)聲明
const name = "loho";

但也可以在不同作用域中重復(fù)聲明,如下例:

var name = "eveningwater";
if(condition){
    const name = "loho";
   console.log(name);//loho,屏蔽全局定義的變量
}

盡管const聲明與let聲明有太多相似的地方,但const聲明也有一處與let聲明不同,那就是const聲明的變量不能被賦值,無論是在非嚴(yán)格模式下還是在嚴(yán)格模式下,都不能對(duì)const聲明的變量進(jìn)行賦值。如下例:

const name = "eveningwater";
//錯(cuò)誤
name = "loho";

不過,如果定義的是一個(gè)對(duì)象,可以對(duì)對(duì)象的值進(jìn)行修改,如下例:

const student = {
    name:"eveningwater"
}
student.name = "loho";//沒問題
//錯(cuò)誤,相當(dāng)于賦值修改對(duì)象
student = {
   name:"loho"
}
4.臨時(shí)死區(qū)

前面提到letconst聲明的變量都不會(huì)提升到作用域的頂部,因此在使用這兩個(gè)標(biāo)識(shí)符聲明之前訪問會(huì)報(bào)錯(cuò),即使是typeof操作符也會(huì)觸發(fā)引用錯(cuò)誤。如下例:

console.log(typeof name);//報(bào)錯(cuò)
const name = "eveningwater";

由于第一行代碼就報(bào)錯(cuò)了,因此后續(xù)的聲明變量語句不會(huì)執(zhí)行,此時(shí)就出現(xiàn)了JavaScript社區(qū)所謂的"臨時(shí)死區(qū)"(temporal dead zone).雖然這里示例是const聲明,但let聲明也是一樣的。

但如果在constlet聲明的變量的作用域之外使用typeof操作符監(jiān)測(cè)卻不會(huì)報(bào)錯(cuò),只不過會(huì)返回undefined。如下例:

console.log(typeof name);//undefined
if(condition){
   let name = "eveningwater";
}
5.循環(huán)中的塊級(jí)作用域綁定

我們?cè)谑褂?b>var聲明變量的時(shí)候,總會(huì)遇到這樣的情況,如下:

for(var i = 0;i < 100;i++){
    //執(zhí)行某些操作
}
//這里也能訪問到變量i
console.log(i);//100

我們可以使用let聲明將變量i限制在循環(huán)中,此時(shí)再在循環(huán)作用域之外訪問變量i就會(huì)報(bào)錯(cuò)了,因?yàn)?b>let聲明已經(jīng)為循環(huán)創(chuàng)建了一個(gè)塊級(jí)作用域。如下:

for(let i = 0;i < 100;i++){
    //執(zhí)行某些操作
}
//報(bào)錯(cuò)
console.log(i);
6.循環(huán)中的創(chuàng)建函數(shù)

在使用var聲明變量的循環(huán)中,創(chuàng)建一個(gè)函數(shù)非常的困難,如下例:

var func = [];
for(var i = 0;i < 5;i++){
    func.push(function(){
        console.log(i);
    })
}
func.forEach(function(func){
    func();
});

你可能預(yù)期想的是打印從0到5之間,即0,1,2,3,4的數(shù)字,但實(shí)際上答案并不是如此。由于函數(shù)有自己的作用域,因此在向數(shù)組中添加函數(shù)的時(shí)候,實(shí)際上循環(huán)已經(jīng)運(yùn)行完成,因此每次打印變量i的值都相當(dāng)于是在全局中訪問變量i的值,即i = 5這個(gè)值,因此實(shí)際上答案最終會(huì)返回5次5.

es5中,我們可以使用函數(shù)表達(dá)式(IIFE)來解決這個(gè)問題,因?yàn)楹瘮?shù)表達(dá)式會(huì)創(chuàng)建一個(gè)自己的塊級(jí)作用域。如下:

var func = [];
for(var i = 0;i < 5;i++){
    (function(i){
       func.push(function(){
           console.log(i);
       })
    })(i)
}
func.forEach(function(func){
    func();//這就是你想要的答案,輸出0,1,2,3,4
})

;

但事實(shí)上有了es6let聲明,我們不必如此麻煩,只需要將var變成let聲明就可以了,如下:

var func = [];
for(let i = 0;i < 5;i++){
    func.push(function(){
        console.log(i);
    })
}
func.forEach(function(func){
    func();//輸出0,1,2,3,4
})

但是這里不能使用const聲明,因?yàn)榍懊嫣岬竭^,const聲明并初始化了一個(gè)常量之后是不能被修改的,只能在對(duì)象中被修改值。如以下示例就會(huì)報(bào)錯(cuò):

//在執(zhí)行循環(huán)i++條件的時(shí)候就會(huì)報(bào)錯(cuò)
for(const i = 0;i < len;i++){
    console.log(i);
}

因?yàn)?b>i++這個(gè)語句就是在嘗試修改常量i的值,因此不能將const聲明用在for循環(huán)中,但可以將const聲明用在for-in或者for-of循環(huán)中。如下:

var func = [];
var obj = {
    name:"eveningwater",
    age:22
}
for(let key in obj){
  func.push(function(){
      console.log(key)
  })
}
func.forEach(function(func){
    func();//name,age
});
//以下也沒問題
var func = [];
var obj = {
    name:"eveningwater",
    age:22
}
for(const key in obj){
    func.push(function(){
       console.log(key)
    })
}
func.forEach(function(func){
  func();//name,age
});

這里并沒有修改key的值,因此使用constlet聲明都可以,同理for-of循環(huán)也是一樣的道理。for-of循環(huán)是es6的新增的循壞。。

7.全局作用域綁定

let,const聲明與var聲明還有一個(gè)區(qū)別就是三者在全局作用域中的行為。當(dāng)使用var聲明一個(gè)變量時(shí),會(huì)在全局作用域(通常情況下是瀏覽器window對(duì)象)中創(chuàng)建一個(gè)全局屬性,這也就意味著可能會(huì)覆蓋window對(duì)象中已經(jīng)存在的一個(gè)全局變量。如下例:

console.log(window.Array);//應(yīng)該返回創(chuàng)建數(shù)組的構(gòu)造函數(shù),即f Array(){}
var Array = "這是數(shù)組";
console.log(window.Array);//返回"這是數(shù)組";

從上例,我們可以知道即使全局作用域中已經(jīng)定義了Array變量或者已經(jīng)存在了Array屬性,但我們之后定義的Array變量則會(huì)覆蓋之前已經(jīng)定義好的或者已經(jīng)存在的Array變量(屬性)。

但是es6letconst聲明則不會(huì)出現(xiàn)這種情況,letconst聲明會(huì)創(chuàng)建一個(gè)新的綁定,也就是說不會(huì)成為window對(duì)象的屬性。換句話說,就是所聲明的變量不會(huì)覆蓋全局變量,而只會(huì)遮蔽它。如下例:

let Array = "這是數(shù)組";
console.log(Array);//"這是數(shù)組‘;
console.log(window.Array);//應(yīng)該返回創(chuàng)建數(shù)組的構(gòu)造函數(shù),即f Array(){}

這也就是說window.Array !== Array這個(gè)等式返回布爾值true。

8.塊級(jí)綁定的最佳實(shí)踐

在使用es6塊級(jí)聲明變量中,最佳實(shí)踐是如果確定后續(xù)不會(huì)改變這個(gè)變量的值,用const聲明,如果確定要改變這個(gè)變量的值,則用let聲明。因?yàn)轭A(yù)料外的變量值的改變時(shí)很多bug出現(xiàn)的源頭。如下示例:

function  eveningWater(){};
eveningWater.prototype.name = "eveningwater";
let ew = new eveningWater();
//定義不能被修改的變量,也就是用于判斷實(shí)例類型的屬性
const _constructor = ew.constructor;
//可以改變自定義的名字屬性
let  name = ew.name;
if(_constructor ===  eveningWater || _constuctor === Object){
  console.log(_constructor);
}else{
   name = "loho";
   console.log(name)
}

鄙人創(chuàng)建了一個(gè)QQ群,供大家學(xué)習(xí)交流,希望和大家合作愉快,互相幫助,交流學(xué)習(xí),以下為群二維碼:

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/102907.html

相關(guān)文章

  • ES6學(xué)習(xí) 第一章 let 和 const 命令

    摘要:外層作用域不報(bào)錯(cuò)正常輸出塊級(jí)作用域與函數(shù)聲明規(guī)定,函數(shù)只能在頂層作用域和函數(shù)作用域之中聲明,不能在塊級(jí)作用域聲明。規(guī)定,塊級(jí)作用域之中,函數(shù)聲明語句的行為類似于,在塊級(jí)作用域之外不可引用。同時(shí),函數(shù)聲明還會(huì)提升到所在的塊級(jí)作用域的頭部。 前言:最近開始看阮一峰老師的《ECMAScript 6 入門》(以下簡(jiǎn)稱原...

    番茄西紅柿 評(píng)論0 收藏2637
  • es6 - 塊級(jí)作用

    摘要:和塊級(jí)作用域在高程中,作者強(qiáng)調(diào)說沒有塊級(jí)作用域。然而,這種情況在中發(fā)生了改變,通過在代碼塊中使用引入了塊級(jí)作用域的特性。在塊級(jí)作用域內(nèi)部使用聲明的變量,在塊作用域外部是不可見的。 let const和塊級(jí)作用域 在js高程中,作者強(qiáng)調(diào)說js沒有塊級(jí)作用域。然而,這種情況在es6中發(fā)生了改變,es6通過在代碼塊中使用let, const引入了塊級(jí)作用域的特性。下面是對(duì)此特性的介紹。 語法...

    wuaiqiu 評(píng)論0 收藏0
  • ES6學(xué)習(xí)摘要(01)(新人學(xué)習(xí))

    摘要:入門一前言由于最近本人在學(xué)習(xí),做一些筆記能夠更好的熟悉,就趁此機(jī)會(huì)來寫一篇關(guān)于的新人學(xué)習(xí)摘要吧。的作用域與命令相同只在聲明所在的塊級(jí)作用域內(nèi)有效。塊級(jí)作用域新增方式和實(shí)際上為新增了塊級(jí)作用域。同時(shí),函數(shù)聲明還會(huì)提升到所在的塊級(jí)作用域的頭部。 ECMAScript6/ES6 入門 一、前言 由于最近本人在學(xué)習(xí)ES6,做一些筆記能夠更好的熟悉,就趁此機(jī)會(huì)來寫一篇關(guān)于ES6的新人學(xué)習(xí)摘要吧。...

    dmlllll 評(píng)論0 收藏0
  • es6學(xué)習(xí)之let和const命令

    摘要:和命令命令是在它所在的代碼塊有效,它屬于塊級(jí)作用域,新增。只有全局作用域和函數(shù)作用域。 let和const命令 let命令是在它所在的代碼塊有效,它屬于塊級(jí)作用域,es6新增。es5只有全局作用域和函數(shù)作用域。let命令存在暫時(shí)性死區(qū)(TDZ),即在申明前使用就會(huì)報(bào)錯(cuò),不存在變量提升 console.log(a); // 報(bào)錯(cuò) let a = 111; ==let不允許在相同作用域中,...

    DrizzleX 評(píng)論0 收藏0
  • ES5和ES6作用詳解

    摘要:允許在塊級(jí)作用域內(nèi)聲明函數(shù)。上面代碼中,存在全局變量,但是塊級(jí)作用域內(nèi)又聲明了一個(gè)局部變量,導(dǎo)致后者綁定這個(gè)塊級(jí)作用域,所以在聲明變量前,對(duì)賦值會(huì)報(bào)錯(cuò)。 ES5的作用域 變量起作用的范圍,js中能創(chuàng)建作用域的只能是函數(shù) { let a = 1; var b = 2; } console.log(a); // a is not defined console.log(b); //...

    Dr_Noooo 評(píng)論0 收藏0
  • ES6精解:let、const、塊級(jí)作用

    摘要:命令新增了命令,跟類似,都是用來聲明變量的不允許重復(fù)聲明報(bào)錯(cuò)不存在變量提升報(bào)錯(cuò)正確寫法為既要先定義,后面才能有這個(gè)值,否則會(huì)報(bào)錯(cuò),如果改成會(huì)提示未定義,但是就直接報(bào)錯(cuò)了暫時(shí)性死區(qū)只要在塊級(jí)作用域里面存在則它所聲明的變量就綁定在這個(gè)塊級(jí)作用域 let命令 ES6新增了let命令,跟var類似,都是用來聲明變量的 1.不允許重復(fù)聲明 { let a = 1; let a =...

    BWrong 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<