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

資訊專欄INFORMATION COLUMN

ES6走走看看—由塊級(jí)作用域引出的一場(chǎng)變革

荊兆峰 / 3408人閱讀

摘要:塊級(jí)聲明塊級(jí)聲明是用于聲明在指定塊的作用域之外無(wú)法訪問(wèn)的變量。美元符號(hào)可以放到任何一個(gè)位置,甚至多帶帶一個(gè)美元符號(hào)。塊級(jí)函數(shù)從開(kāi)始,在嚴(yán)格模式下,塊里的函數(shù)作用域?yàn)檫@個(gè)塊。

持續(xù)更新的github筆記,鏈接地址:Front-End-Basics

此篇文章的筆記地址:字符到底發(fā)生了什么變化

ES6走走看看系列,特別鳴謝奇舞讀書(shū)會(huì)~

塊級(jí)作用域又稱詞法作用域,存在于:

函數(shù)內(nèi)部(函數(shù)作用域)

塊中(字符 { 和 } 之間的區(qū)域)

注意:ES6允許塊級(jí)作用域任意嵌套

{{{{{{let text = "Hello World!"}}}}}}

因?yàn)橛辛藟K級(jí)作用域,然后我們才有繼續(xù)往下聊的可能。

1、 塊級(jí)聲明

塊級(jí)聲明是用于聲明在指定塊的作用域之外無(wú)法訪問(wèn)的變量。

2、 let聲明:用來(lái)聲明一個(gè)塊級(jí)作用域變量

1、 聲明的變量具有塊級(jí)作用域的特性

// 例子
function getValue (condition) {
    if (condition) {
        let value = "blue";
        return value;
    }
    console.log(value)
    // 報(bào)錯(cuò) value is not defined
}
getValue()

2、 在同一個(gè)作用域內(nèi)不能使用let聲明同名的變量

// 不管是var,const或者let,新的let聲明之前同名的變量,都會(huì)報(bào)錯(cuò)
var count = 30;
let count = 40;
// 報(bào)錯(cuò) Identifier "count" has already been declared

// 函數(shù)形參和函數(shù)內(nèi)部的let聲明變量重名,報(bào)錯(cuò)
function test(value) {
    let value = 3;
}
test()
// 報(bào)錯(cuò) Identifier "value" has already been declared

// 在不同的作用域聲明的變量重名是沒(méi)問(wèn)題的
let count = 30;
if(true) {
  let count = 40;
  // 不同的作用域,不會(huì)報(bào)錯(cuò)
}

3、 聲明沒(méi)有預(yù)解析,不存在變量提升,有“臨時(shí)死區(qū)”(TDZ)

從塊的開(kāi)始到變量聲明這段的區(qū)域被稱為臨時(shí)死區(qū),ES6明確規(guī)定,如果區(qū)塊中存在let和const命令,則這個(gè)區(qū)塊對(duì)這些命令聲明的變量從一開(kāi)始就形成封閉作用域,只要在聲明之前就使用這些變量(賦值,引用等等),就會(huì)報(bào)錯(cuò)。

if(true) {
    console.log(typeof value);
    // 報(bào)錯(cuò) value is not defined

    let value = "blue";
}

注意:TDZ是區(qū)域是“塊開(kāi)始”到“變量聲明”,下面的例子不報(bào)錯(cuò)

// typeof 說(shuō)是相對(duì)安全,確實(shí)是,永遠(yuǎn)拿不到想要的結(jié)果
console.log(typeof value); // 打印 undefined,沒(méi)有報(bào)錯(cuò)
if(true) {
    let value = "red";
}
3、 const聲明:聲明常量(如PI),值一旦被設(shè)定后不可更改

1、 常量聲明的值是不可變的

注意:const聲明的對(duì)象不允許修改綁定,但可以修改該對(duì)象的屬性值。

const number = 6;
number = 5;
// 報(bào)錯(cuò) Assignment to constant variable

const obj = {number: 1};
obj.number = 2; // 不報(bào)錯(cuò)

obj = {number: 3};
// 報(bào)錯(cuò) Assignment to constant variable

2、 因?yàn)槌A柯暶骱笾稻筒豢筛牧?,所以聲明時(shí)必須賦值

// 有效的常量
const count = 30;

// 報(bào)錯(cuò) Missing initializer in const declaration
const name;

3、 聲明的常量具有塊級(jí)作用域的特性

if(true) {
    const number = 5;
}
console.log(number)
// 報(bào)錯(cuò) number is not defined

4、 在同一個(gè)作用域內(nèi)不能使用const聲明同名的變量

var message = "Hello";
let age = 25;

// 這兩條語(yǔ)句都會(huì)報(bào)錯(cuò)
const message = "Good";
const age = 30;

5、 聲明沒(méi)有預(yù)解析,不存在變量提升,有“臨時(shí)死區(qū)”(TDZ)


總結(jié):一張表格

聲明方式 變量提升 作用域 是否需要初始值 重復(fù)定義
var 函數(shù)級(jí) 不需要 允許
let 塊級(jí) 不需要 不允許
const 塊級(jí) 需要 不允許

擴(kuò)展:再提一下變量命名,不管是var、let、const聲明的變量名,可以由數(shù)字,字母,下劃線及美元符號(hào)組成,但是不能以數(shù)字開(kāi)頭。美元符號(hào)可以放到任何一個(gè)位置,甚至多帶帶一個(gè)美元符號(hào)。

4、 循環(huán)中的塊作用域綁定
循環(huán)中的let聲明
// 第一個(gè)對(duì)比
// before
for(var i = 0; i < 5; i++) {
    // ... 省略一些代碼
}
console.log(i)  // 5

//after
for(let i = 0; i < 5; i++) {
    // ... 省略一些代碼
}
console.log(i) // 報(bào)錯(cuò) i is not defined


// 第二個(gè)對(duì)比
// before
var funcs = [];
for(var i = 0; i < 10; i++) {
    funcs.push(() => {console.log(i)})
}
funcs.forEach((ele) => {
    ele()
})
// 打印 10次 10

// after
var funcs = [];
for(let i = 0; i < 10; i++) {
    funcs.push(() => {console.log(i)})
}
funcs.forEach((ele) => {
    ele()
})
// 打印 0 1 2 3 4 5 6 7 8 9

注意:有一點(diǎn)很重要,let 聲明在循環(huán)內(nèi)部的行為是標(biāo)準(zhǔn)中專門(mén)定義的,它不一定與 let 不提升特性有關(guān)。

循環(huán)中的const聲明
// for 循環(huán)會(huì)報(bào)錯(cuò)
for (const i = 0; i < 1; i++) {
    console.log(i)
}
// 打印 0 ,然后報(bào)錯(cuò) Assignment to constant variable.

// for-in 和 for-of 不會(huì)報(bào)錯(cuò)
var object = {
    a: true,
    b: true,
    c: true
};
for (const key in object) {
    // 不要在循環(huán)體內(nèi)更改key的值,會(huì)報(bào)錯(cuò)
    console.log(key)
}
// 打印 a b c

注意:const可以應(yīng)用在 for-in 和 for-of 循環(huán)中,是因?yàn)槊看蔚粫?huì)修改已有綁定,而是會(huì)創(chuàng)建一個(gè)新綁定。

5、 塊級(jí)綁定最佳實(shí)踐的進(jìn)化
ES6 早期

普遍認(rèn)為默認(rèn)使用let來(lái)替代var,對(duì)于寫(xiě)保護(hù)的變量使用const

ES6 使用中

普遍默認(rèn)使用const,只有確實(shí)需要改變變量的值時(shí)使用let。因?yàn)榇蟛糠肿兞康闹翟诔跏蓟蟛粦?yīng)再改變,而預(yù)料之外的變量值的改變是許多bug的源頭。這樣就可以在某種程度上實(shí)現(xiàn)代碼的不可變,從而防止某些錯(cuò)誤的發(fā)生。

6、 全局變量將逐步與頂層對(duì)象的屬性脫鉤

頂層對(duì)象,在瀏覽器環(huán)境指的是window對(duì)象,在Node指的是global對(duì)象。

為了保持兼容性,var命令和function命令聲明的全局變量,依舊是頂層對(duì)象的屬性;

var a = 1;
window.a // 1

另一方面規(guī)定,let命令、const命令、class命令聲明的全局變量,不屬于頂層對(duì)象的屬性。

上圖可見(jiàn)let 聲明的變量,并沒(méi)有在Window對(duì)象里,而是一個(gè)新的Script對(duì)象。

擴(kuò)展:如果需要在瀏覽器中跨frame或window訪問(wèn)代碼,仍然可以用var在全局對(duì)象下定義變量。

7、 塊級(jí)函數(shù)

從ECMAScript 6開(kāi)始,在嚴(yán)格模式下,塊里的函數(shù)作用域?yàn)檫@個(gè)塊。ECMAScript 6之前不建議塊級(jí)函數(shù)在嚴(yán)格模式下使用。

"use strict";

function f() {
  return 1;
}

{
  function f() {
    return 2;
  }
}

f() === 1; // true

// f() === 2 在非嚴(yán)格模式下相等

注意:在非嚴(yán)格模式下不要用塊級(jí)函數(shù),因?yàn)樵诜菄?yán)格模式下,塊中函數(shù)的聲明表現(xiàn)奇怪,有兼容性風(fēng)險(xiǎn)

if (shouldDefineZero) {
   function zero() {     // DANGER: 兼容性風(fēng)險(xiǎn)
      console.log("This is zero.");
   }
}

ECMAScript 6中,如果shouldDefineZero是false,則永遠(yuǎn)不會(huì)定義zero,因?yàn)檫@個(gè)塊不執(zhí)行。這是新標(biāo)準(zhǔn)定義的。然而,這里存在歷史遺留問(wèn)題,無(wú)論這個(gè)塊是否執(zhí)行,一些瀏覽器會(huì)定義zero。

在嚴(yán)格模式下,所有支持ECMAScript 6的瀏覽器以相同的方式處理:只有在shouldDefineZero為true的情況下定義zero,并且作用域只是這個(gè)塊內(nèi)。

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

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

相關(guān)文章

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

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

    番茄西紅柿 評(píng)論0 收藏2637
  • ES6系列文章 塊級(jí)作用

    摘要:聲明之函數(shù)作用域和全局作用域。塊級(jí)作用域不能重復(fù)聲明臨時(shí)性死區(qū)等特性用來(lái)解決變量存在的種種問(wèn)題。塊級(jí)作用域終于在外面訪問(wèn)不到了。一些常量聲明使用聲明的變量名全部大寫(xiě)。 ES5之前javascript語(yǔ)言只有函數(shù)作用域和全局作用域,使用var來(lái)聲明變量,var聲明的變量還存在變量提升使人困惑不已。我們先來(lái)復(fù)習(xí)一下ES5的var聲明,再對(duì)比學(xué)習(xí)let和const 。 var var聲明之函...

    趙連江 評(píng)論0 收藏0
  • ES6基礎(chǔ)

    一、塊級(jí)作用域 1. var 首先看看ES5中得變量聲明方式 if (true) { var a = 2 } console.log(a) // 2 以上代碼等同于 var a if (true) { a = 2 } console.log(a) 以上可知 : 在塊內(nèi)部定義變量 變量提升,到函數(shù)最頂部 通過(guò)var聲明的變量,無(wú)論在何處聲明,均為全局作用域 2.let 和 ...

    BigTomato 評(píng)論0 收藏0
  • javascript---閉包

    摘要:要理解閉包,首先必須理解特殊的變量作用域。使用閉包有一個(gè)優(yōu)點(diǎn),也是它的缺點(diǎn)就是可以把局部變量駐留在內(nèi)存中,可以避免使用全局變量。 js閉包 閉包是指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包的常見(jiàn)的方式,就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù),通過(guò)另一個(gè)函數(shù)訪問(wèn)這個(gè)函數(shù)的局部變量。要理解閉包,首先必須理解Javascript特殊的變量作用域。變量的作用域無(wú)非就是兩種:全局變量和局部變量...

    stormgens 評(píng)論0 收藏0
  • 大白話解釋作用域和閉包是個(gè)啥 作用域的分類 常見(jiàn)的變量作用域就是 靜態(tài)作用域(詞法作用域) 與 動(dòng)態(tài)作用域 。詞法作用域注重的是 write-time ,即 編程時(shí)的上下文 ,而 動(dòng)態(tài)作用域 則注重的是 run-time ,即 運(yùn)行時(shí)上下文 。詞法作用域中我們需要知道一個(gè)函數(shù) 在什么地方被定義 ,而動(dòng)態(tài)作用域中我們需要關(guān)心的是函數(shù) 在什么地方被調(diào)用 而 javascript 使用的則是詞法作用域 ...

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

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

0條評(píng)論

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