第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

TypeScript 變量聲明

本節(jié)介紹 var let const 這三種變量的聲明方式,重點討論作用域與變量提升的相關知識點,這部分往往也是面試??疾糠?,需要多加注意。

說明: 在使用 TypeScript 進行變量聲明時,一般建議添加對應的變量類型,由于本節(jié)是整個系列教程的第一節(jié),還未介紹 TypeScript 的類型系統(tǒng),所以本節(jié)的例子仍采用 JavaScript 的變量聲明方式。雖然在變量聲明時沒有添加變量類型,但是 TypeScript 會自動進行類型推導,得到正確的變量類型,這個在后續(xù)章節(jié)也會專門介紹。

1. 慕課解釋

TypeScript 是 JavaScript 的超集,同 JavaScript 一樣,聲明變量可以采用下面三個關鍵字:

  • var
  • let
  • const

2. var 聲明

通過 var 關鍵字來定義 JavaScript 變量,這個大家都能理解:

var num = 10

2.1 作用域

下面我們來討論一個為什么盡量避免使用 var。

快速的猜一下下面的代碼會返回什么:

實例演示
預覽 復制
復制成功!
for (var i = 0; i < 10; i++) {
  setTimeout(function () {
    console.log(i)
  }, 100 * i)
}
運行案例 點擊 "運行案例" 可查看在線運行效果

相信很多人都踩過這個坑,這幾乎是作用域的必考題目,但如果你不了解,不要擔心,你并不是一個人。大多數(shù)人期望輸出的結果是這樣的:

0
1
2
3
4
5
6
7
8
9

然而,實際結果是這樣的:

10
10
10
10
10
10
10
10
10
10

解釋:這里的 i 是在全局作用域中的,只存在一個值。 setTimeout 這個異步函數(shù)在若干毫秒后執(zhí)行,并且它是在 for 循環(huán)結束后的。在 for 循環(huán)結束后, i 的值為 10,所以當函數(shù)被調用的時候,它會打印出 10。

下面介紹幾種可以實現(xiàn)我們預期輸出結果的方法:

  1. 通過調用函數(shù),創(chuàng)建函數(shù)作用域
實例演示
預覽 復制
復制成功!
for (var i = 0; i < 10; i++) {
  f(i)
}

function f (i) {
  setTimeout(function () {
    console.log(i)
  }, 100)
}
運行案例 點擊 "運行案例" 可查看在線運行效果
  1. 立即執(zhí)行函數(shù),創(chuàng)建函數(shù)作用域
實例演示
預覽 復制
復制成功!
for (var i = 0; i < 10; i++) {
  (function (i) {
    setTimeout(function () {
      console.log(i)
    }, 100 * i)
  })(i)
}
運行案例 點擊 "運行案例" 可查看在線運行效果
  1. 通過 let 關鍵字創(chuàng)建塊級作用域
實例演示
預覽 復制
復制成功!
for (let i = 0; i < 10; i++) {
  setTimeout(function () {
    console.log(i)
  }, 100 * i)
}
運行案例 點擊 "運行案例" 可查看在線運行效果

2.2 變量提升

看下面的例子:

console.log(a) // undefined
var a = 1 

它等價于:

var a
console.log(a) // undefined
a = 1

從上面的例子中可以看出,關鍵詞 var 會進行變量提升。

如果把上面的 var 換成 let 呢?

console.log(a) // ReferenceError: a is not defined
let a = 1 

會報錯 a is not defined 未定義,這里也可以看出 varlet 在變量提升的不同:

  • var 會將變量的創(chuàng)建初始化都進行提升
  • let 只會將創(chuàng)建提升,而初始化未被提升,稱之為暫時性死區(qū)

3. let 聲明

現(xiàn)在你已經(jīng)知道了 var 存在全局作用域和變量提升的問題,這恰好說明了為什么用 let 語句來聲明變量。

let num = 10

下面介紹 let 的一些特點:

3.1 塊作用域

在 ES6 之前,ECMAScript 的作用域只有兩種:

  • 全局作用域
  • 函數(shù)作用域

現(xiàn)在通過命令 let 和 const 新增了“塊級作用域”,定義在代碼塊中的變量在代碼塊被執(zhí)行結束后會被釋放掉:

實例演示
預覽 復制
復制成功!
function block() {
  if (true) {
    let a = 10
    console.log(a) // 10
  }

  console.log(a) // Cannot find name 'a'.ts(2304)
}
運行案例 點擊 "運行案例" 可查看在線運行效果

代碼解釋:

第 3 - 4 行,a 變量在 if{} 代碼塊中是有效的,正常輸出 10。

第7行,在 if{} 代碼塊外就被釋放掉了,所以會報錯誤。

包括在一對花括號中的一組語句稱之為”代碼塊“,它可以替換掉上面介紹 var 時使用的立即執(zhí)行函數(shù):

// 立即執(zhí)行函數(shù)
(function(){
  var a = 10
}())

// 代碼塊
{
  let a = 10
}

3.2 重定義

在使用 var 聲明時,不論聲明幾次,最終只會得到一個:

var x
var x
var x

這是一個完全有效的代碼,所有 x 的聲明其實都指向了同一個引用,但這也是很多 bug 產生的原因。 let 的聲明就嚴格了許多:

let x
let x // Cannot redeclare block-scoped variable 'x'

代碼解釋: 第 2 行,重新聲明了塊作用域的變量 x 。

4. const 聲明

關鍵字 const 聲明變量,它被賦值后不能再改變。 換句話說,它擁有與 let 相同的作用域規(guī)則,但是不能重新賦值。

用 const 聲明變量,并不是變量的值不得改動,而是變量指向的那個內存地址不得改動。用 const 聲明初始數(shù)據(jù)類型如布爾值、數(shù)字、字符串,可以理解為聲明常量,因為這些初始類型的值就保存在變量所指向的那個內存地址。

const num = 10
const brand = 'imooc'
const registered = true

num = 20 // Cannot assign to 'num' because it is a constant.ts(2588)

代碼解釋: 第 5 行,在給 num 第二次賦值時會報錯。

對于復合類型的數(shù)據(jù)來說,變量所指向的內存地址保存的只是一個指針,const 能夠保證其指針不變,但屬性值是可變的:

const person = {
  name: 'Tom',
  address: 'Baker Street 221b'
}

// error
person = {
  name: 'Sherlock',
  address: 'Baker Street 221b'
}

// ok
person.name = 'Sherlock'

代碼解釋: 第 7 行,對已經(jīng)使用 const 聲明的變量重新賦值報錯,但是在第 13 行,只是對這個對象的屬性賦值是可以的。

5. 小結

閱讀本小節(jié)中三種不同的變量聲明,我們知道了:

  • letcount 實現(xiàn)了塊級作用域。
  • 所有變量除了你計劃去修改的都應該使用 const。
  • 盡量使用 letconst 來聲明變量,減少 var 的使用。