是的,nextSibling方法可以用來獲取某個元素的下一個兄弟元素,也就是說同層次元素中的下一個元素.注意一定要是兄弟元素.所謂的兄弟元素就是都被包含在同一個父元素中的元素.如果沒有找到下一個兄弟元素,該方法則返回null.
創(chuàng)新互聯(lián)公司專注于企業(yè)成都營銷網(wǎng)站建設、網(wǎng)站重做改版、石棉網(wǎng)站定制設計、自適應品牌網(wǎng)站建設、HTML5建站、商城網(wǎng)站開發(fā)、集團公司官網(wǎng)建設、外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應式網(wǎng)頁設計等建站業(yè)務,價格優(yōu)惠性價比高,為石棉等各大城市提供網(wǎng)站開發(fā)制作服務。
比如有一組div或li元組,我們要獲取某個div后面的那個div,就可以使用nextSibling方法來實現(xiàn).或者獲取某個li元素后面的那個元素.
Typescript 是 javascript 的類型超集,旨在簡化大型 JavaScript 應用程序的開發(fā)。Typescript 加入了常見的概念例如 類(classes),泛型(generics),接口(interfaces)和靜態(tài)類型(static types)并允許開發(fā)人員使用靜態(tài)檢查和代碼重構(gòu)等工具。
為什么在意 Typescript
現(xiàn)在問題仍然是為什么你應該優(yōu)選使用 Typescript。這有一些關于為什么 javascript 開發(fā)者應該考慮學習 Typescript 的原因。
靜態(tài)類型
Javascript 是動態(tài)類型的,這意味著直到在運行時實例化時,它不知道變量的類型,這可能導致項目中的問題和錯誤。Typescript 加入了對 Javascript 靜態(tài)類型支持如果你正確的使用它處理由變量類型的錯誤設定引起的錯誤。您仍然可以完全控制輸入代碼的嚴格程度,或者甚至根本不使用類型。
更好的 IDE 支持
Typescript 相比 Javascript 一個更大的優(yōu)勢是更好的 IED 支持包括了來自 Typescript 編譯器智能,實時的提示,調(diào)試以及更多功能。這里還有一大堆擴展進一步 提升你的 Typescript 開發(fā)體驗。
應用新的 ECMAScript 特性
Typescript 使您可以使用最新的 ECMAScript 功能,并將它們轉(zhuǎn)換到您選擇的 ECMAScript 目標。這意味著您可以使用最新的工具開發(fā)應用程序,而無需擔心瀏覽器支持。
什么時候你該使用它
到目前為止,我們應該知道為什么 Typescript 是有用的以及如何改善我們的開發(fā)體驗。但它并不是解決所有問題的方法,當然也不能阻止你自己編寫可怕的代碼。那么讓我們來看看你應該在哪里使用 Typescript。
當你擁有一個很大的代碼庫時
Typescript 是大型代碼庫的一個很好的補充,因為它可以幫助您防止許多常見錯誤。這尤其適用于多個開發(fā)人員工作在同一項目之中。
當你項目成員早已知道靜態(tài)類型語言時
另一個明顯使用 Typescript 的場景是當你和你的團隊已經(jīng)知道靜態(tài)類型的語言像 Java 和 C# 不想改為編寫 Javascript。
設置/建立
要設置 typescript,我們只需要使用 npm 包管理器安裝它并創(chuàng)建一個新的 Typescript 文件。
安裝完成之后我們可以繼續(xù)探尋 Typescript 提供給我們的語法和功能特性。
類型
現(xiàn)在讓我們來看看 Typescript 所提供的類型:
數(shù)值(Number)
Typescript 所有的值類型都是浮點數(shù)。所有的數(shù)字包括二進制和十六進制都是數(shù)值類型。
字符串(String)
與其他語言一樣,Typescript 使用 String 數(shù)據(jù)類型來保存文本數(shù)據(jù)。
你還可以用反引號來應用多行字符串并嵌入表達式。
布爾類型(Boolean)
Typescript 支持所有的基本數(shù)據(jù)類型,布爾類型,值必須為 true 或者 false。
指定類型
現(xiàn)在我們已經(jīng)有了基本的數(shù)據(jù)類型,我們可以看看你如何在 Typescript 中指定類型?;旧?,您只需要在名稱和冒號后面寫出變量的類型。
單一類型
這里例子為我們?nèi)绾螢樽兞恐付ㄗ址當?shù)據(jù)類型
所有其他數(shù)據(jù)類型也是這樣使用。
多類型
你仍然可以通過 | 操作符為你的變量指定多個數(shù)據(jù)類型:
這里我們使用|為變量分配兩種類型?,F(xiàn)在我們可以在其中存儲字符串和數(shù)值。
類型檢測
現(xiàn)在讓我們看看我們?nèi)绾螜z查我們的變量是否具有正確的類型。我們有多種選擇,但在這里我只展示了兩個最常用的選項。
Typeof
typeof 僅僅知道基本類型。這意味著它只能檢查變量是否是我們上面定義的數(shù)據(jù)類型之一。
在此示例中,我們創(chuàng)建一個字符串類型變量并使用 typeof 命令檢查 str 是否為 Number 類型(始終為 false)。然后我們打印是否是數(shù)值。
Instanceof
instanceof 運算符與 typeof 幾乎相同,只是它還可以檢查 javascript 尚未定義的自定義類型。
在這里,我們創(chuàng)建一個自定義類型,我們稍后將在本文中討論,然后創(chuàng)建它的實例。之后,我們檢查它是否真的是 Human 類型的變量,如果是,則在控制臺中打印。
類型斷言
有時我們還需要將變量轉(zhuǎn)換為特定的數(shù)據(jù)類型。這經(jīng)常發(fā)生在你已經(jīng)指定了一個泛型類型像 any 并且你想使用它具體的類型的方法。
有很多選擇可以解決這個問題,但在這里我只分享其中兩個。
As 關鍵字
通過在變量名之后使用 as 關鍵字跟隨具體的數(shù)據(jù)類型來轉(zhuǎn)換變量的類型。
這里我們將 str 變量轉(zhuǎn)換為字符串,以便我們可以使用 length 屬性(如果您的 TSLINT 設置允許,甚至可以在沒有轉(zhuǎn)換的情況下工作)。
操作符
我們也可以使用 運算符,它與 as 關鍵字具有完全相同的效果,只有語法差異。
此代碼塊與上面的代碼塊具有完全相同的功能。它只是語法不同。
數(shù)組
Typescript 中的數(shù)組是相同對象的集合,可以用兩種不同的方式創(chuàng)建。
創(chuàng)建數(shù)組
使用 []
我們可以通過指定類型后跟 [] 來定義數(shù)組對象,以表示它是一個數(shù)組。
在這個例子中,我們創(chuàng)建一個字符串數(shù)組,它包含三個不同的字符串值。
使用泛型數(shù)組
我們還可用指定 Array 定義泛型數(shù)組
這里我們創(chuàng)建一個數(shù)值數(shù)組,它包含 5 個不同的數(shù)字。
多(混合)類型數(shù)組
此外,我們還可以使用 | 操作符將多個類型分配給單個數(shù)組。
此例中我們創(chuàng)建了一個數(shù)值可以包含字符串和數(shù)值。
多維數(shù)組
Typescript 還允許我們定義多維數(shù)組,這意味著我們可以將數(shù)組保存在另一個數(shù)組中。我們可以通過使用多個[]運算符來創(chuàng)建一個多維數(shù)組。
這里我們創(chuàng)建一個包含另一個數(shù)字數(shù)組的數(shù)組。
元組(Tupels)
元組基本類似數(shù)組但有一點不同。我們可以定義每個位子上儲存數(shù)據(jù)的類型。這意味著我們可以通過方括號內(nèi)的枚舉來限制固定索引位置的類型。
在此列中,我們定義了一個簡單的元組,在索引 0 位置上指定為數(shù)值類型,在索引為 1 位置上指定為字符串類型。這意味著如果我們嘗試在此索引上放置另一種數(shù)據(jù)類型,則會拋出錯誤。
以下是非法元組的示例:
枚舉(Enums)
與大多數(shù)其他面向?qū)ο缶幊陶Z言一樣,Typescript 中的枚舉允許我們定義一組命名常量。 Typescript 還提供基于數(shù)值和基于字符串的枚舉。使用 enum 關鍵字定義 Typescript 中的枚舉。
數(shù)值枚舉
首先,我們將查看數(shù)值枚舉,其中我們將鍵值與索引匹配。
上面,我們定義了數(shù)值枚舉將 Playing 初始化為 0,Paused 為 1 等等。
我們也可以將初始化器留空,而 Typescript 會從零開始自動索引它。
字符串枚舉
定義字符串枚舉也十分簡單,我們只需要在定義的每個枚舉值后初始化字符串值。
這里我們通過使用字符串初始化我們的狀態(tài)來定義字符串枚舉。
對象(Objects)
Typescript 中的對象是包含一組鍵值對的實例。這些值可以是變量,數(shù)組甚至函數(shù)。它也被視為表示非基本類型的數(shù)據(jù)類型。
我們可以使用大括號創(chuàng)建一個對象:
這里我們創(chuàng)建了一個 human 對象包含三個不同的鍵值對。
我們可以為對象加入方法:
自定義類型
Typescript 還允許我們自定義類型,以便于我們后續(xù)重用。要創(chuàng)建自定義類型,我們只需要使用 type 關鍵字并定義我們的類型。
在此示例中,我們定義了一個名為 Human 包含三個屬性的自定義類型。現(xiàn)在讓我們看看如何創(chuàng)建這種類型的對象。
在這里,我們創(chuàng)建自定義類型的實例并設置所需的屬性。
方法參數(shù)和返回類型
Typescript 允許我們?yōu)榉椒▍?shù)和返回值指定數(shù)據(jù)類型。現(xiàn)在讓我們看一下使用 Typescript 定義函數(shù)的語法。
這里我們有兩個示例函數(shù),它們都具有定義類型的參數(shù)。我們還看到在結(jié)束括號后定義返回類型。
現(xiàn)在我們可以像普通的 javascript 一樣調(diào)用我們的函數(shù),但編譯器會檢查我們是否為函數(shù)提供了正確的參數(shù)。
可選屬性
Typescript 允許我們?yōu)榉椒?注:接口等同樣可以定義可選屬性)定義可選屬性。我們通過 ? 操作符定義。
在這個例子中,lastName 是一個可選參數(shù),這意味著當我們不提供調(diào)用函數(shù)時,我們不會從編譯器中獲得錯誤。
這表示 2 個示例都被視為正確的。
默認值
我們使用可選屬性的第二種方法是為它指定一個默認值。我們可以通過直接在函數(shù)頭部賦值來實現(xiàn)。
在此例我中我們 lastName 賦予了默認值這意味著我們不必每次調(diào)用方法時提供它。
接口(Interfaces)
讓我們看個例子讓定義更加清晰:
可選屬性
在 Typescript 中,有時并不是所有接口屬性都是必需的??梢允褂? ? 運算符在屬性后面將其設置為可選。
在這里,我們創(chuàng)建一個具有一個普通和一個可選屬性的接口,該屬性是使用 ? 運算符。這就是我們兩個人初始化都有效的原因。
只讀屬性
我們的接口中一些屬性也應該只在首次創(chuàng)建對象時修改賦值。我們可以通過將 readonly 關鍵字放在我們的屬性名稱之前來指定此功能。
在此示例中,id 屬性是只讀的,在創(chuàng)建對象后無法更改。
模塊(Barrels Modules)
Barrels 允許我們在一個更方便的模塊中匯總多個導出模塊。
我們僅需要創(chuàng)建一個新文件,它將導出我們項目中的多個模塊 (譯者注:根據(jù) ECMAScript 定義一個文件定義一個模塊,此處可能表示模塊聚合(類似庫等的入口文件))。
之后我們可以通過這個便利的單一導入語句引入這些模塊。
泛型(Generics)
泛型允許我們創(chuàng)建兼容廣泛類型而不是單一類型的組件。這使得我們的組件“ 開放”和復用。
現(xiàn)在您可能想知道為什么我們不只是使用任何( any )類型來使組件接受多種類型而不是單一類型。讓我們看一個例子更好地了解。
我們想要一個簡單的假函數(shù)(dummy function),它返回傳入的參數(shù):
然而 any 是通用的,某種程度它能接受所有類型參數(shù)但有一個很大的區(qū)別。我們丟失了我們傳入的參數(shù)是什么類型以及返回值是什么類型。
所以讓我們來看看,我們?nèi)绾谓邮芩蓄愋筒⒅浪祷刂档念愋汀?/p>
這里我們使用泛型參數(shù) T,因此我們可以捕獲變量類型并在以后使用它。我們還使用它作為返回參數(shù)類型,它允許我們在檢查代碼時看到相應的類型。
更多詳細介紹你可以查看Charly Poly關于Generics and overloads的文章
訪問修飾符(Access Modifiers)
訪問修飾符控制我們類成員的可訪問性。 Typescript 支持三種訪問修飾符 - 公共的(public),私有的(private)和受保護的(protected)。
公共的
公共成員可以在任何地方訪問,沒有任何限制 這也是標準修飾符,這意味著您不需要使用 public 關鍵字為變量添加前綴。
私有的
私有成員只能在其定義的類中能訪問。
受保護的
保護成員只能在其定義的類及其子類中訪問。
TSLINT
TSLINT 是 Typescript 的標準 linter,可以幫助我們編寫干凈,可維護和可讀的代碼。它可以使用我們自己的 lint 規(guī)則,配置和格式化程序進行自定義。
設置
首先我們需要安裝 Typescript 和 tslint,我們可以全局安裝和局部安裝:
之后,我們可以使用 TSLINT CLI 在我們的項目中初始化 TSLINT。
現(xiàn)在我們有了 tslint.json 文件,我們可以開始配置我們的規(guī)則了。
配置
TSLINT 允許使用配置我們自己的規(guī)則并自定義代碼的外觀。默認情況下,tslint.json 文件看起來像這樣,只使用默認規(guī)則。
我們可以通過將它們放在 rules 對象中來添加其他規(guī)則。
有關所有可用規(guī)則的 概述,您可以查看官方文檔。
結(jié)論
恭喜您一路走到最后!希望此篇文章幫助您理解 Typescript 的基礎知識以及如何在項目中使用。
如果您發(fā)現(xiàn)這個有用,請考慮推薦并與其他開發(fā)人員共享。也可以訪問我的網(wǎng)站學習更多。
如果您有任何問題和反饋,在以下評論中讓我知道。
新系列 深入淺出TypeScript 來了,本系列至少20+篇。本文為第一篇,來介紹一下TypeScript 以及常見的類型。
TypeScript是一門由微軟推出的開源的、跨平臺的編程語言。它是JavaScript的超集,擴展了 JavaScript 的語法,最終會被編譯為JavaScript代碼。
TypeScript的主要特性:
TypeScript 主要是為了實現(xiàn)以下兩個目標:
下面就來看看這兩個目標是如何實現(xiàn)的。
為什么要給JavaScript加上類型呢?
我們知道,JavaScript是一種輕量級的解釋性腳本語言。也是弱類型、動態(tài)類型語言,允許隱式轉(zhuǎn)換,只有運行時才能確定變量的類型。正是因為在運行時才能確定變量的類型,JavaScript代碼很多錯誤在運行時才能發(fā)現(xiàn)。TypeScript在JavaScript的基礎上,包裝了類型機制,使其變身成為 靜態(tài)類型 語言。在 TypeScript 中,不僅可以輕易復用 JavaScript 的代碼、最新特性,還能使用可選的靜態(tài)類型進行檢查報錯,使得編寫的代碼更健壯、更易于維護。
下面是 JavaScript 項目中最常見的十大錯誤,如果使用 TypeScript,那么在 編寫階段 就可以發(fā)現(xiàn)并解決很多 JavaScript 錯誤了:
類型系統(tǒng)能夠提高代碼的質(zhì)量和可維護性,經(jīng)過不斷的實踐,以下兩點尤其需要注意:
可以認為,在所有操作符之前,TypeScript 都能檢測到接收的類型(在代碼運行時,操作符接收的是實際數(shù)據(jù);在靜態(tài)檢測時,操作符接收的則是類型)是否被當前操作符所支持。當 TypeScript 類型檢測能力覆蓋到所有代碼后,任意破壞約定的改動都能被自動檢測出來,并提出類型錯誤。因此,可以放心地修改、重構(gòu)業(yè)務邏輯,而不用擔憂因為考慮不周而犯下低級錯誤。
在一些語言中,類型總是有一些不必要的復雜的存在方式,而 TypeScript 盡可能地降低了使用門檻,它是通過如下方式來實現(xiàn)的。
TypeScript 與 JavaScript 本質(zhì)并無區(qū)別,我們可以將 TypeScipt 理解為是一個添加了類型注解的 JavaScript,為JavaScript代碼提供了編譯時的類型安全。
實際上,TypeScript 是一門“ 中間語言 ”,因為它最終會轉(zhuǎn)化為JavaScript,再交給瀏覽器解釋、執(zhí)行。不過 TypeScript 并不會破壞 JavaScript 原有的體系,只是在 JavaScript 的基礎上進行了擴展。
準確的說,TypeScript 只是將JavaScript中的方法進行了標準化處理:
這段代碼在TypeScript中就會報錯,因為TS會知道a是一個數(shù)字類型,不能將其他類型的值賦值給a,這種類型的推斷是很有必要的。
上面說了,TypeScript會盡可能安全的推斷類型。我們也可以使用類型注釋,以實現(xiàn)以下兩件事:
在一些語言中,類型總是有一些不必要的復雜的存在方式,而 TypeScript 的類型是結(jié)構(gòu)化的。比如下面的例子中,函數(shù)會接受它所期望的參數(shù):
為了便于把 JavaScript 代碼遷移至 TypeScript,即使存在編譯錯誤,在默認的情況下,TypeScript 也會盡可能的被編譯為 JavaScript 代碼。因此,我們可以將JavaScript代碼逐步遷移至 TypeScript。
雖然 TypeScript 是 JavaScript 的超集,但它始終緊跟ECMAScript標準,所以是支持ES6/7/8/9 等新語法標準的。并且,在語法層面上對一些語法進行了擴展。TypeScript 團隊也正在積極的添加新功能的支持,這些功能會隨著時間的推移而越來越多,越來越全面。
雖然 TypeScript 比較嚴謹,但是它并沒有讓 JavaScript 失去其靈活性。TypeScript 由于兼容 JavaScript 所以靈活度可以媲美 JavaScript,比如可以在任何地方將類型定義為 any(當然,并不推薦這樣使用),畢竟 TypeScript 對類型的檢查嚴格程度是可以通過 tsconfig.json 來配置的。
在搭建TypeScript環(huán)境之前,先來看看適合TypeScript的IDE,這里主要介紹Visual Studio Code,筆者就一直使用這款編輯器。
VS Code可以說是微軟的親兒子了,其具有以下優(yōu)勢:
因為 VS Code 中內(nèi)置了特定版本的 TypeScript 語言服務,所以它天然支持 TypeScript 語法解析和類型檢測,且這個內(nèi)置的服務與手動安裝的 TypeScript 完全隔離。因此, VS Code 支持在內(nèi)置和手動安裝版本之間動態(tài)切換語言服務,從而實現(xiàn)對不同版本的 TypeScript 的支持。
如果當前應用目錄中安裝了與內(nèi)置服務不同版本的 TypeScript,我們就可以點擊 VS Code 底部工具欄的版本號信息,從而實現(xiàn) “use VS Code's Version” 和 “use Workspace's Version” 兩者之間的隨意切換。
除此之外,VS Code 也基于 TypeScript 語言服務提供了準確的代碼自動補全功能,并顯示詳細的類型定義信息,大大的提升了我們的開發(fā)效率。
1)全局安裝TypeScript:
2)初始化配置文件:
執(zhí)行之后,項目根目錄會出現(xiàn)一個 tsconfig.json 文件,里面包含ts的配置項(可能因為版本不同而配置略有不同)。
可以在 package.json 中加入script命令:
3)編譯ts代碼:
TSLint 是一個通過 tslint.json 進行配置的插件,在編寫TypeScript代碼時,可以對代碼風格進行檢查和提示。如果對代碼風格有要求,就需要用到TSLint了。其使用步驟如下: (1)在全局安裝TSLint:
(2)使用TSLint初始化配置文件:
執(zhí)行之后,項目根目錄下多了一個 tslint.json 文件,這就是TSLint的配置文件了,它會根據(jù)這個文件對代碼進行檢查,生成的 tslint.json 文件有下面幾個字段:
這些字段的含義如下;
在說TypeScript數(shù)據(jù)類型之前,先來看看在TypeScript中定義數(shù)據(jù)類型的基本語法。
在語法層面,缺省類型注解的 TypeScript 與 JavaScript 完全一致。因此,可以把 TypeScript 代碼的編寫看作是為 JavaScript 代碼添加類型注解。
在 TypeScript 語法中,類型的標注主要通過類型后置語法來實現(xiàn):“ 變量: 類型 ”
在 JavaScript 中,原始類型指的是 非對象且沒有方法 的數(shù)據(jù)類型,包括:number、boolean、string、null、undefined、symbol、bigInt。
它們對應的 TypeScript 類型如下:
JavaScript原始基礎類型TypeScript類型 numbernumber booleanboolean stringstring nullnull undefinedundefined symbolsymbol bigIntbigInt
需要注意 number 和 Number 的區(qū)別:TypeScript中指定類型的時候要用 number ,這是TypeScript的類型關鍵字。而 Number 是 JavaScript 的原生構(gòu)造函數(shù),用它來創(chuàng)建數(shù)值類型的值,這兩個是不一樣的。包括 string 、 boolean 等都是TypeScript的類型關鍵字,而不是JavaScript語法。
TypeScript 和 JavaScript 一樣,所有數(shù)字都是 浮點數(shù) ,所以只有一個 number 類型。
TypeScript 還支持 ES6 中新增的二進制和八進制字面量,所以 TypeScript 中共支持 2、8、10和16 這四種進制的數(shù)值:
字符串類型可以使用單引號和雙引號來包裹內(nèi)容,但是如果使用 Tslint 規(guī)則,會對引號進行檢測,使用單引號還是雙引號可以在 Tslint 規(guī)則中進行配置。除此之外,還可以使用 ES6 中的模板字符串來拼接變量和字符串會更為方便。
類型為布爾值類型的變量的值只能是true或者false。除此之外,賦值給布爾值的值也可以是一個計算之后結(jié)果為布爾值的表達式:
在 JavaScript 中,undefined和 null 是兩個基本數(shù)據(jù)類型。在 TypeScript 中,這兩者都有各自的類型,即 undefined 和 null,也就是說它們既是實際的值,也是類型。這兩種類型的實際用處不是很大。
注意,第一行代碼可能會報一個tslint的錯誤: Unnecessary initialization to 'undefined' ,就是不能給一個變量賦值為undefined。但實際上給變量賦值為undefined是完全可以的,所以如果想讓代碼合理化,可以配置tslint,將" no-unnecessary-initializer "設置為 false 即可。
默認情況下,undefined 和 null 是所有類型的子類型,可以賦值給任意類型的值,也就是說可以把 undefined 賦值給 void 類型,也可以賦值給 number 類型。當在 tsconfig.json 的"compilerOptions"里設置為 "strictNullChecks": true 時,就必須嚴格對待了。這時 undefined 和 null 將只能賦值給它們自身或者 void 類型。這樣也可以規(guī)避一些錯誤。
BigInt是ES6中新引入的數(shù)據(jù)類型,它是一種內(nèi)置對象,它提供了一種方法來表示大于 2- 1 的整數(shù),BigInt可以表示任意大的整數(shù)。
使用 BigInt 可以安全地存儲和操作大整數(shù),即使這個數(shù)已經(jīng)超出了JavaScript構(gòu)造函數(shù) Number 能夠表示的安全整數(shù)范圍。
我們知道,在 JavaScript 中采用雙精度浮點數(shù),這導致精度有限,比如 Number.MAX_SAFE_INTEGER 給出了可以安全遞增的最大可能整數(shù),即 2- 1 ,來看一個例子:
可以看到,最終返回了true,這就是超過精讀范圍造成的問題,而 BigInt 正是解決這類問題而生的:
這里需要用 BigInt(number) 把 Number 轉(zhuǎn)化為 BigInt ,同時如果類型是 BigInt ,那么數(shù)字后面需要加 n 。
在TypeScript中, number 類型雖然和 BigInt 都表示數(shù)字,但是實際上兩者類型是完全不同的:
symbol我們平時用的比較少,所以可能了解也不是很多,這里就詳細來說說symbol。
symbol 是 ES6 新增的一種基本數(shù)據(jù)類型,它用來表示獨一無二的值,可以通過 Symbol 構(gòu)造函數(shù)生成。
注意:Symbol 前面不能加 new關鍵字,直接調(diào)用即可創(chuàng)建一個獨一無二的 symbol 類型的值。
可以在使用 Symbol 方法創(chuàng)建 symbol 類型值的時候傳入一個參數(shù),這個參數(shù)需要是一個字符串。如果傳入的參數(shù)不是字符串,會先自動調(diào)用傳入?yún)?shù)的 toString 方法轉(zhuǎn)為字符串:
上面代碼的第三行可能會報一個錯誤:This condition will always return 'false' since the types 'unique symbol' and 'unique symbol' have no overlap. 這是因為編譯器檢測到這里的 s1 === s2 始終是false,所以編譯器提醒這代碼寫的多余,建議進行優(yōu)化。
上面使用Symbol創(chuàng)建了兩個symbol對象,方法中都傳入了相同的字符串,但是兩個symbol值仍然是false,這就說明了 Symbol 方法會返回一個獨一無二的值。Symbol 方法傳入的這個字符串,就是方便我們區(qū)分 symbol 值的。可以調(diào)用 symbol 值的 toString 方法將它轉(zhuǎn)為字符串:
在TypeScript中使用symbol就是指定一個值的類型為symbol類型:
在ES6中,對象的屬性是支持表達式的,可以使用于一個變量來作為屬性名,這對于代碼的簡化有很多用處,表達式必須放在大括號內(nèi):
symbol 也可以作為屬性名,因為symbol的值是獨一無二的,所以當它作為屬性名時,不會與其他任何屬性名重復。當需要訪問這個屬性時,只能使用這個symbol值來訪問(必須使用方括號形式來訪問):
在使用obj.name訪問時,實際上是字符串name,這和訪問普通字符串類型的屬性名是一樣的,要想訪問屬性名為symbol類型的屬性時,必須使用方括號。方括號中的name才是我們定義的symbol類型的變量name。
使用 Symbol 類型值作為屬性名,這個屬性是不會被 for…in遍歷到的,也不會被 Object.keys() 、 Object.getOwnPropertyNames() 、 JSON.stringify() 等方法獲取到:
雖然這些方法都不能訪問到Symbol類型的屬性名,但是Symbol類型的屬性并不是私有屬性,可以使用 Object.getOwnPropertySymbols 方法獲取對象的所有symbol類型的屬性名:
除了這個方法,還可以使用ES6提供的 Reflect 對象的靜態(tài)方法 Reflect.ownKeys ,它可以返回所有類型的屬性名,Symbol 類型的也會返回:
Symbol 包含兩個靜態(tài)方法, for 和 keyFor 。 1)Symbol.for()
用Symbol創(chuàng)建的symbol類型的值都是獨一無二的。使用 Symbol.for 方法傳入字符串,會先檢查有沒有使用該字符串調(diào)用 Symbol.for 方法創(chuàng)建的 symbol 值。如果有,返回該值;如果沒有,則使用該字符串新創(chuàng)建一個。使用該方法創(chuàng)建 symbol 值后會在全局范圍進行注冊。
上面代碼中,創(chuàng)建了一個iframe節(jié)點并把它放在body中,通過這個 iframe 對象的 contentWindow 拿到這個 iframe 的 window 對象,在 iframe.contentWindow上添加一個值就相當于在當前頁面定義一個全局變量一樣??梢钥吹剑?iframe 中定義的鍵為 TypeScript 的 symbol 值在和在當前頁面定義的鍵為'TypeScript'的symbol 值相等,說明它們是同一個值。
2)Symbol.keyFor() 該方法傳入一個 symbol 值,返回該值在全局注冊的鍵名:
看完簡單的數(shù)據(jù)類型,下面就來看看比較復雜的數(shù)據(jù)類型,包括JavaScript中的數(shù)組和對象,以及TypeScript中新增的元組、枚舉、Any、void、never、unknown。
在 TypeScript 中有兩種定義數(shù)組的方式:
以上兩種定義數(shù)組類型的方式雖然本質(zhì)上沒有任何區(qū)別,但是更推薦使用第一種形式來定義。一方面可以避免與 JSX 語法沖突,另一方面可以減少代碼量。
注意,這兩種寫法中的 number 指定的是數(shù)組元素的類型,也可以在這里將數(shù)組的元素指定為其他任意類型。如果要指定一個數(shù)組里的元素既可以是數(shù)值也可以是字符串,那么可以使用這種方式: number|string[] 。
在JavaScript中,object是引用類型,它存儲的是值的引用。在TypeScript中,當想讓一個變量或者函數(shù)的參數(shù)的類型是一個對象的形式時,可以使用這個類型:
可以看到,當給一個對象類型的變量賦值一個對象時,就會報錯。對象類型更適合以下場景:
在 JavaScript 中并沒有元組的概念,作為一門動態(tài)類型語言,它的優(yōu)勢是支持多類型元素數(shù)組。但是出于較好的擴展性、可讀性和穩(wěn)定性考慮,我們通常會把不同類型的值通過鍵值對的形式塞到一個對象中,再返回這個對象,而不是使用沒有任何限制的數(shù)組。TypeScript 的元組類型正好彌補了這個不足,使得定義包含固定個數(shù)元素、每個元素類型未必相同的數(shù)組成為可能。
元組可以看做是數(shù)組的擴展,它表示已知元素數(shù)量和類型的數(shù)組,它特別適合用來實現(xiàn)多值返回。確切的說,就是已知數(shù)組中每一個位置上的元素的類型,可以通過元組的索引為元素賦值::
可以看到,定義的arr元組中,元素個數(shù)和元素類型都是確定的,當為arr賦值時,各個位置上的元素類型都要對應,元素個數(shù)也要一致。
當訪問元組元素時,TypeScript也會對元素做類型檢查,如果元素是一個字符串,那么它只能使用字符串方法,如果使用別的類型的方法,就會報錯。
在TypeScript 新的版本中,TypeScript會對元組做越界判斷。超出規(guī)定個數(shù)的元素稱作越界元素,元素賦值必須類型和個數(shù)都對應,不能超出定義的元素個數(shù)。
這里定義了接口 Tuple ,它繼承數(shù)組類型,并且數(shù)組元素的類型是 number 和 string 構(gòu)成的聯(lián)合類型,這樣接口 Tuple 就擁有了數(shù)組類型所有的特性。并且指定索引為0的值為 string 類型,索引為1的值為 number 類型,同時指定 length 屬性的類型字面量為 2,這樣在指定一個類型為這個接口 Tuple 時,這個值必須是數(shù)組,而且如果元素個數(shù)超過2個時,它的length就不是2是大于2的數(shù)了,就不滿足這個接口定義了,所以就會報錯;當然,如果元素個數(shù)不夠2個也會報錯,因為索引為0或1的值缺失。
TypeScript 在 ES 原有類型基礎上加入枚舉類型,使得在 TypeScript 中也可以給一組數(shù)值賦予名字,這樣對開發(fā)者比較友好。枚舉類型使用enum來定義:
上面定義的枚舉類型的Roles,它有三個值,TypeScript會為它們每個值分配編號,默認從0開始,在使用時,就可以使用名字而不需要記數(shù)字和名稱的對應關系了:
除此之外,還可以修改這個數(shù)值,讓SUPER_ADMIN = 1,這樣后面的值就分別是2和3。當然還可以給每個值賦予不同的、不按順序排列的值:
我們可以將一個值定義為any類型,也可以在定義數(shù)組類型時使用any來指定數(shù)組中的元素類型為任意類型:
any 類型會在對象的調(diào)用鏈中進行傳導,即any 類型對象的任意屬性的類型都是 any,如下代碼所示:
需要注意:不要濫用any類型,如果代碼中充滿了any,那TypeScript和JavaScript就毫無區(qū)別了,所以除非有充足的理由,否則應該盡量避免使用 any ,并且開啟禁用隱式 any 的設置。
void 和 any 相反,any 是表示任意類型,而 void 是表示沒有類型,就是什么類型都不是。這在 定義函數(shù),并且函數(shù)沒有返回值時會用到 :
需要注意: void 類型的變量只能賦值為 undefined 和 null ,其他類型不能賦值給 void 類型的變量。
never 類型指永遠不存在值的類型,它是那些 總會拋出異常 或 根本不會有返回值的函數(shù)表達式的返回值 類型,當變量被永不為真的類型保護所約束時,該變量也是 never 類型。
下面的函數(shù),總是會拋出異常,所以它的返回值類型是never,用來表明它的返回值是不存在的:
never 類型是任何類型的子類型,所以它可以賦值給任何類型;而沒有類型是 never 的子類型,所以除了它自身以外,其他類型(包括 any 類型)都不能為 never 類型賦值。
上面代碼定義了一個立即執(zhí)行函數(shù),函數(shù)體是一個死循環(huán),這個函數(shù)調(diào)用后的返回值類型為 never,所以賦值之后 neverVariable 的類型是 never 類型,當給neverVariable 賦值 123 時,就會報錯,因為除它自身外任何類型都不能賦值給 never 類型。
基于 never 的特性,我們可以把 never 作為接口類型下的屬性類型,用來禁止操作接口下特定的屬性:
可以看到,無論給 props.name 賦什么類型的值,它都會提示類型錯誤,這就相當于將 name 屬性設置為了只讀 。
unknown 是TypeScript在3.0版本新增的類型,主要用來描述類型并不確定的變量。它看起來和any很像,但是還是有區(qū)別的,unknown相對于any更安全。
對于any,來看一個例子:
上面這些語句都不會報錯,因為value是any類型,所以后面三個操作都有合法的情況,當value是一個對象時,訪問name屬性是沒問題的;當value是數(shù)值類型的時候,調(diào)用它的toFixed方法沒問題;當value是字符串或數(shù)組時獲取它的length屬性是沒問題的。
當指定值為unknown類型的時候,如果沒有 縮小類型范圍 的話,是不能對它進行任何操作的??傊?,unknown類型的值不能隨便操作。那什么是類型范圍縮小呢?下面來看一個例子:
這里由于把value的類型縮小為Date實例的范圍內(nèi),所以進行了value.toISOString(),也就是使用ISO標準將 Date 對象轉(zhuǎn)換為字符串。
使用以下方式也可以縮小類型范圍:
關于 unknown 類型,在使用時需要注意以下幾點:
在實際使用中,如果有類型無法確定的情況,要盡量避免使用 any,因為 any 會丟失類型信息,一旦一個類型被指定為 any,那么在它上面進行任何操作都是合法的,所以會有意想不到的情況發(fā)生。因此如果遇到無法確定類型的情況,要先考慮使用 unknown。
1.什么是JavaScript?
JavaScript是一種直譯式腳本語言,是一種動態(tài)類型、弱類型、基于原型的語言,內(nèi)置支持類型。通俗的講JavaScript通常用來做網(wǎng)頁的交互以及同動態(tài)效果。它是一種非常流行的腳本語言,是一種運行在瀏覽器中的解釋型編程語言。
2.同源的定義:
如果兩個頁面的協(xié)議/端口和主機都相同,那么這兩個頁面具有相同的源。我們也可以把它稱為“協(xié)議/主機/端口 tuple”,或簡單地叫做“tuple". ("tuple" ,“元”,“元組”是指一些事物組合在一起形成一個整體,比如(1,2)叫二元,(1,2,3)叫三元)。下表給出了相對同源檢測的示例:
(只是路徑不同而已,同源。)
(只是路徑不同,同源)
(協(xié)議不同,http≠https,不同源)
(端口不同,http://80是默認值,不同源)
(域名不同,news/store,不同源)
3.JavaScript可以對文本web文檔內(nèi)容進行操作,對文檔隨意操作是互聯(lián)網(wǎng)世界大忌,因此要對其進行限制。針對代碼可以限定對哪些特定的web文本進行操作,這就叫同源策略。
同源策略的含義:腳本只能讀取和所屬文檔來源相同的窗口和文檔的屬性。
以上就是JavaScript同源策略的大致概念,若要深究同源的驗證過程以及原理,可以自行系統(tǒng)完整的學習此概念,對自己大有裨益。