摘要:聲明的變量聲明可以在包含它的函數,模塊,命名空間或全局作用域內部任何位置被訪問。但是塊級作用域變量需要在明顯不同的塊里聲明。會輸出與預料一致的結果聲明聲明是聲明變量的另一種方式。
從var聲明說起
一直以來我們都是通過var關鍵字定義JavaScript變量。
var a = 10;
var聲明的變量var聲明可以在包含它的函數,模塊,命名空間或全局作用域內部任何位置被訪問。
比如在其它函數內部訪問相同的變量:
function f() { var a = 10; return function g() { var b = a + 1; return b; } } var g = f(); g(); // returns 11;
這些作用域規則可能會引發一些錯誤。
第1個問題就是多次聲明同一個變量并不會報錯。比如下面這個例子:
function sumMatrix(matrix: number[][]) { var sum = 0; for (var i = 0; i < matrix.length; i++) { var currentRow = matrix[i]; for (var i = 0; i < currentRow.length; i++) { sum += currentRow[i]; } } return sum; } sumMatrix([[1,2],[3,4]])
一般認為,運行的結果應該為10。但結果并非如此,因為所有i都引用相同的函數作用域內的變量,里層的for循環會覆蓋變量i,所以現在的結果是3而不是10。所以使用var聲明時,它不在乎你聲明多少次你只會得到1個。
setTimeout中的異常
看下面這段代碼:
for (var i = 0; i < 10; i++) { setTimeout(function() { console.log(i); }, 100 * i); }
我們期望的結果是:每隔100*i毫秒打印出1個數字,順序為1-10,但實際打印出的全部都是10。這是因為setTimeout在若干毫秒后執行一個函數,并且是在for循環結束后。 for循環結束后,i的值為10。 所以當函數被調用的時候,它會打印出 10!我們不得不利用一個立即執行函數解決這個問題:
for(var i = 0; i < 10; i++){ (function(i){setTimeout(()=>console.log(i), i * 100);})(i) }
var聲明的變量帶給我們這么多困擾,所以在typescript中加入了let對變量進行聲明。
let聲明let與var的寫法一致:
let hello = "Hello!";
let聲明的變量和var聲明的變量有很多不同之處,let解決了var變量帶來的困擾。
塊作用域
當用let聲明一個變量,它使用的是塊作用域。 不同于使用 var聲明的變量那樣可以在包含它們的函數外訪問,塊作用域變量在包含它們的塊或for循環之外是不能訪問的。
function f(input: boolean) { let a = 100; if (input) { let b = a + 1; return b; } return b; }
在上面代碼中,a可以在if語句中被訪問,因為a在函數語句中聲明,在if語句之外,而b就不能在if語句塊之外被訪問,因為b是在if語句塊中被聲明的。
在catch語句里聲明的變量也具有同樣的作用域規則。
try { throw "oh no!"; } catch (e) { console.log("Oh well."); } console.log(e); //error
在catch語句塊外,e是不能被訪問的。
在let語句聲明之前訪問let聲明的變量,結果為undefined。
function foo() { // okay to capture "a" return a; } console.log(foo()); // let a = 10;
重定義及屏蔽
var聲明時,不論你聲明多少次,你只會得到1個。
var x = 10; console.log(x); //10 var x = 20; console.log(x); //20
let聲明,需要遵循塊作用域規則,在一個塊作用域中重復聲明變量會產生錯誤提示,另一個用var聲明也不允許。
function g() { let x = 100; var x = 100; // error: can"t have both declarations of "x" }
塊級作用域變量可以用函數作用域變量來聲明。 但是塊級作用域變量需要在明顯不同的塊里聲明。
function f(condition, x){ if(condition){ let x = 100; return x; } return x; } console.log(f(true, 0)); //100 console.log(f(false, 0)); //0
在一個嵌套作用域里引入一個新名字的行為稱做屏蔽。 它是一把雙刃劍,它可能會不小心地引入新問題,同時也可能會解決一些錯誤。 例如,假設我們現在用 let重寫之前的sumMatrix函數。
function sumMatrix(matrix: number[][]){ let sum = 0; for(let i = 0; i < matrix.length; i++){ let current = matrix[i]; for(let i = 0; i < current.length; i++){ sum += current[i]; } } return sum; } console.log(sumMatrix([[1,2],[3,4]])); //10
這次可以得到正確的結果10,因為內層循環中的i屏蔽了外層循環中的i。但這種寫法是不推薦的。
塊級作用域變量的獲取
function theCityThatAlwaysSleeps() { let getCity; if (true) { let city = "Seattle"; getCity = function() { return city; } } return getCity(); }
上面這段代碼可以正常執行。因為我們已經在city的環境里獲取到了city,所以就算if語句執行結束后我們仍然可以訪問它。
當let聲明出現在循環體里時擁有完全不同的行為,針對每次迭代都會創建一個新作用域。所以在 setTimeout例子里我們僅使用let聲明就可以了。
for(let i = 0; i < 10; i ++){ setTimeout(()=>console.log(i), i*100); }
會輸出與預料一致的結果:1 2 3 4 5 6 7 8 9
const 聲明const 聲明是聲明變量的另一種方式。它們與let聲明相似,但是就像它的名字所表達的,它們被賦值后不能再改變。
const numLivesForCat = 9;
它們擁有與 let相同的作用域規則,但是不能對它們重新賦值。
const kitty = { name: "Aurora", numLives: numLivesForCat, } // Error kitty = { name: "Danielle", numLives: numLivesForCat };
但const變量內部的狀態還是可以改變的。
const kitty = { name: "Aurora", numLives: numLivesForCat, } // all "okay" kitty.name = "Rory"; kitty.name = "Kitty"; kitty.name = "Cat"; kitty.numLives--;let與const的區別
最后,說說let與const的區別,引用官網的建議:
使用最小特權原則,所有變量除了你計劃去修改的都應該使用const。 基本原則就是如果一個變量不需要對它寫入,那么其它使用這些代碼的人也不能夠寫入它們,并且要思考為什么會需要對這些變量重新賦值。 使用 const也可以讓我們更容易的推測數據的流動。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93494.html
摘要:聯合類型,指賦值的時候可以是聯合類型中的某一個。任意屬性允許創建對象的時候,定義接口中沒有的屬性。常見的類型推論,還提現在函數表達式中。 typeScript是什么? TypeScript 是 JavaScript 的一個超集,主要提供了類型系統和對 ES6 的支持 安裝typeScript npm install -g typeScript 安裝完成查看版本: tsc -v typ...
摘要:聲明和結構在中,支持和這樣的聲明方式。解構就是將聲明的一組變量與相同結構的數組或者對象的元素數值一一對應,并將變量相對應元素進行賦值。 學習Angular 2 , 《揭秘Angular 2》讀書筆記。Angular2 選擇 TypeScript 作為其官方最主要的構建語音,這意味著掌握 TypeScript 語音將更有利于高效地開發 Angular 應用。 聲明和結構 在TypeScr...
摘要:弄了一個持續更新的筆記,可以去看看,鏈接地址此篇文章的地址使用兩年后值得嗎基礎筆記的地址可以也可以。使用,你可以使用抽象類等功能。有關抽象類的更多信息支持,和方法,只讀屬性。 弄了一個持續更新的github筆記,可以去看看,鏈接地址:Front-End-Basics 此篇文章的地址:使用TypeScript兩年后-值得嗎? 基礎筆記的github地址:https://githu...
摘要:注意變量聲明沒有指定類型。因此,程序使用類型推斷來確定變量的數據類型,第一次賦值為,設置為類型。 typescript 的基本類型1.number 數字類型 example: let val: Number = 22.string 字符串 example: let val: String = 23.Boolean 布爾類型 example: let val: Boolean = fal...
閱讀 733·2021-11-23 09:51
閱讀 2430·2021-10-11 11:10
閱讀 1299·2021-09-23 11:21
閱讀 1091·2021-09-10 10:50
閱讀 882·2019-08-30 15:54
閱讀 3326·2019-08-30 15:53
閱讀 3287·2019-08-30 15:53
閱讀 3186·2019-08-29 17:23