工具: PlayGround
源碼: GitHub TypeScript
變量聲明
typeScript
中變量聲明注意:
- 開頭不能以數字開頭
- 變量名稱可以包含數字和字母
- 除了下劃線
_
和美元$
符號外,不能包含其他任意特殊字符
聲明的結構: let 變量名: 類型 = 值
如果沒有聲明類型,則變量為any
類型, 如果沒有賦值,則數值為undefined
let name: string = "name";// 沒有聲明類型,在賦值以后,編譯器會對類型進行推導
// 如果不能推導出類型,則被默認為any類型
let value = 10;// 沒有賦值表示為undefined
let data;
針對于沒有聲明的類型,TypeScritp
會靜態編譯,注意警告:
let num = 2;
console.log("num type:", typeof(num)); // "num type:", "number"
console.log("num 變量的值為 "+num); // "num 變量的值為 2"// Type 'string' is not assignable to type 'number'
// 沒有報錯,但會有警告
num = "12"; console.log("num type:", typeof(num)); // "num type:", "string"
console.log(num); // "12"
基礎類型
在TypeScript
中,內置的數據類型也被稱為原始數據類型,主要有:
number
雙精度64位浮點數,注意 TypeScript和JavaScript沒有整數string
存儲UTF-16的字符串序列, 可以使用單引號(‘’)或雙引號(“”)來包含字符串,使用反引號(`)來格式化文本或內嵌表達式等boolean
布爾類型, 使用true
和false
進行判定void
表示不返回任意類型的函數返回類型undefined
表示一個沒有設置數據的變量null
表示一個空對象的引用
let data: number = null;// number
let value: number = 0.1;
let decLiteral: number = 6; // 十進制
let binaryLiteral: number = 0b1010; // 二進制
let octalLiteral: number = 0o744; // 八進制
let hexLiteral: number = 0xf00d; // 十六進制// string
let name: string = "TypeScript";
let years: number = 5;
let words: string = `您好,今年是${name}發布${years + 1}周年`;// boolean
let flag: boolean = true;// void
function Debug(index: number): void {}
在編寫程序的時候,可以通過console.log
輸出日志,使用工具推薦: PlayGround
let dataList = [1, 2, 3];
console.log(dataList); // [1, 2, 3] let value = 10;
console.log("value: ", value); // "value: ", 10 let name: string = "TypeScript";
let years: number = 5;
let words: string = `您好,今年是${name}發布${years + 1}周年`;
console.log("Content:" + words); // "Content:您好,今年是TypeScript發布6周年"
console.log
的不僅支持基礎數據,也支持數組,Map相關; 不需要考慮是否存在Lua中的dump相關
// 數組
const numList = [1, 2, 3];
console.log(numList);
// 輸出: [1, 2, 3] // Map列表
let myMap = new Map([["key1", "value1"],["key2", "value2"]
]);
console.log(myMap);
// 輸出: Map (2) {"key1" => "value1", "key2" => "value2"} // String對象
console.log(String);
// 輸出: function String() { [native code] }
其他類型
const
常量相關
const value = 10;
value = 11; // Error: Assignment to constant variable
any
表示類型不明確,可以通過賦值改變為不同的類型:
// any類型,表示類型不明確; 可以賦值為不同的類型
let data: any = null;
data = "hello";
data = false;
- 數組相關, 類型后面有個
[]
// 有類型的數組
let numList: number[] = [1, 2];
let strList: string[] = ["heloo", "typeScript"];
// 任意類型數據
let dataList: any[] = [1, false, "hello", 4];
// 泛型數組
let dataList: Array<number> = [1,2,3];
enum
枚舉相關
enum kColor {RED,GREEN,BLUE,
}
let color: kColor = kColor.RED;
never
類型, 相當于其他類型包含null
和undefined
的子類型,代表不會出現的值
let x: never;// 運行錯誤,數字類型不能轉為 never 類型
// Type 'number' is not assignable to type 'never'
x = 123;// 運行正確,never 類型可以賦值給 never類型
x = (()=>{ throw new Error('exception')})();
- 注意,可以通過
|
支持不同的數據類型,比如:
let value: number | string = null;
let value: string | string[];
類型判定typeof
使用typeof
可以對數據進行類型判定顯示,比如:
console.log(typeof(false)); // "boolean"
console.log(typeof(1.0)); // "number"
console.log(typeof(0XFFFF)); // "number"
console.log(typeof("script")); // "string"
其他一些有意思的特性:
// "object"
console.log(typeof(null));
console.log(typeof {});
console.log(typeof []); // "undefined"
console.log(typeof(undefined)); // "undefined"
console.log(typeof(any)); // "undefined"
let data;
console.log(typeof(data)); // "undefined"// 函數相關
function getValue(): number {return 0;
}
console.log(typeof(function)); // "function"
console.log(typeof(getValue)); // "function"
console.log(typeof(getValue())); // "number"// NaN相關
console.log(typeof(NaN)); // "number"
console.log(typeof(Number.NaN)); // "number"
我們需要注意下:
- NaN的類型雖然是
number
數字類型, 但它真正代表的 非數字數特殊值,用于表示非法的數值? 如果兩個NaN比較,他們并不相等, 數學運算中較為常見:
console.log(0/0); // NaN
console.log(Math.sqrt(-1)); // NaN
console.log(Math.log(-1)); // NaN
- null和undefined 前者表示一個空的引用, 后者表示一個沒有設置數據的變量,因此他們的類型并不相同
console.log(typeof(null)); // "object"
console.log(typeof(undefined)); // "undefined"
- object 它表示一個非原始類型(數字,字符串,布爾)的值,主要作用于數組,對象和函數等,它是一種泛指的類型,可以包括任意類型值。
const numObj = new Number(10);
const strObj = new String("");
console.log(typeof(numObj)); // "object"
console.log(typeof(strObj)); // "object"
在TypeScript
的語言中,如果我們單純的使用value === null
或者!value
這種方式來判定數據的合法性,可能會存在不嚴謹性。
考慮到數字0、空字符串、false、null、undefined、NaN的情況存在, 我們可以使用Boolean()
函數將值轉換為布爾值, 然后再進行判定。
const value_1 = Boolean(0);
const value_2 = Boolean("");
const value_3 = Boolean(null);
const value_4 = Boolean(undefined);
const value_5 = Boolean(NaN);
// 輸出均為false
console.log(value_1, value_2, value_3, value_4, value_5);
boxing和unboxing
前面說到了一個Boolean
類型的轉換,既然支持Boolean
類型對象的轉換,當然也提供了Number
和String
類型的轉換。
他們支持數字或字符串調用相關的方法接口,以實現一些復雜的邏輯處理。
const numObj = new Number(10);
const strObj = new String("");
但在熟悉JavaScript/typeScript
后,會發現類似這樣的一個情況:
const str = "hello TypeScript";
console.log(str.toUpperCase()); // "HELLO TYPESCRIPT" const strObj = new String(str);
console.log(strObj.toUpperCase()); // "HELLO TYPESCRIPT"
string基礎數據和String對象可以調用相同的函數來實現邏輯, 這個原因在于:
JavaScript/TypeScript
允許將數字,字符串等值類型轉換為對應的封裝對象, 這個轉換的過程被稱為boxing裝箱, 而對應的將一個引用對象類型轉換為值類型則被稱為unboxing拆箱。
在這里簡要的說明下,有助于對后面的文章理解。
關鍵字
最后說下關鍵字相關,算是對typeScript
有個大概的了解:
關鍵字 | 描述 |
---|---|
break/continue | 跳出循環, break 用于跳出當前循環, continue 用于跳出當前循環的剩余代碼 |
as | 類型斷言,用于將一個實體斷言為特定的類型 |
try/catch/finally | 用于捕獲和處理異常 |
switch/case/default | 條件語句相關,可使用break 進行截止 |
if/else if / else | 條件語句相關 |
var/let | 聲明變量的關鍵字 |
throw | |
number/ string/enum | 基礎數據類型: 浮點數,字符串,枚舉 |
true/false | boolean 類型值 |
void/null/any/return/function | – |
static/const | 靜態和常量,靜態類成員,可以直接訪問; 常量必須在聲明后初始化 |
for/do while | 循環語句 |
get/set | 用于對對象屬性變量的獲取或設置 |
module/namespace | module 用于定義一個模塊,用于組織和封裝相關代碼, 自TypeScript 2.7版本起,逐漸被namespace 代替 |
type/typeof | type 用來做類型別名, typeof 用來獲取數據類型 |
instanceof | JavaScript的運算符,用于檢查對象是否是指定類的實例 |
public/private | 可用于聲明類方法類型是公有還是私有 |
export | export 用于將模塊中的變量,函數,類等導出,使其可以被其他模塊使用 |
import | 用于導入變量,函數,類相關,與export 配對使用 |
super | 用于派生類調用基類的構造函數,方法和屬性相關 |
this | 在類中使用,用于引用當前對象 |
extends | 用于類繼承相關 |
implements/interface | interface 用于定義一個接口,通過implements 來實現接口 |
yield | 用于定義**生成器(特殊函數,可以在執行過程中暫停和恢復)**函數的暫停點,可以將值返回給調用者 |
一些簡單的實例:
var/let
聲明變量的關鍵字
/*
var是ES5及之前的JavaScript的關鍵字,特點:
* 函數作用域,聲明的變量在整個函數體內, 而不僅是在塊作用域內
* 變量會提升,聲明的變量會提升到函數的頂部, 即可在聲明之前使用
* 允許重復聲明
*/
function example() {var x = 10;if (true) {var x = 20; // 在同一函數作用域內重復聲明變量xconsole.log(x); // 輸出:20}console.log(x); // 輸出:20
}
example();/*
let是ES6及之后的JavaScript和TypeScript引入的關鍵子,特點:
* 塊作用域, 比如if語句,循環語句,并不是整個函數體內
* 不存在變量提升,必須聲明之后才能使用
* 不允許崇明聲明,否則會報錯
*/
function example2() {let y = 10;if (true) {let y = 20; // 在塊級作用域內聲明變量yconsole.log(y); // 輸出:20}console.log(y); // 輸出:10
}
example2();
as
用于將一個實體斷言為特定的類型
let someValue: any = "hello";
let strLength: number = (someValue as string).length;
console.log(strLength); // 5
try/catch
捕獲異常
try {// 可能引發異常的代碼throw new Error("Something went wrong!");
} catch (error) {// 異常處理邏輯console.log(error.message);
} finally {// 總是執行的代碼塊
}
// 輸出:Something went wrong!
- 條件語句相關
// switch/case相關
let fruit = "apple";
switch (fruit) {case "apple":console.log("It's an apple.");break;case "banana":console.log("It's a banana.");break;default:console.log("It's something else.");
}// if/ else if / else相關
let num = 10;
if (num > 0) {console.log("Positive number");
} else if (num < 0) {console.log("Negative number");
} else {console.log("Zero");
}
// 輸出:Positive number
instanceof
用于檢查實例對象是否是特定類的實例
class Animal {// class implementation
}class Dog extends Animal {//
}const animal = new Animal;
const myDog = new Dog();
console.log(animal instanceof Animal); // true
console.log(myDog instanceof Animal); // true
export/import
// 模塊導出
export const myVariable = 123;
export function myFunction() {// 函數實現
}
export class MyClass {// 類實現
}// 模塊導入
import { myVariable, myFunction, MyClass } from './myModule';
super
用于子類調用基類的構造函數和方法等
class Parent {private _value: number = 0;constructor(value: number) {// this用作類中對象的引用this._value = value;console.log("Parent constructor:", this._value);}parentMethod() {console.log("Parent parentMethod");}
}// extends 繼承
class Child extends Parent {constructor() {super(10); // 調用父類構造函數}childMethod() {super.parentMethod(); // 調用父類方法}
}const child = new Child();
child.childMethod();/*
Parent constructor: 10
Parent parentMethod
*/
get/set
用于對對象屬性變量的獲取或設置
class MyClass {private _myProperty: string;get myProperty(): string {return this._myProperty;}set myProperty(value: string) {this._myProperty = value;}
}const myObj = new MyClass();
// 設置對象屬性值
myObj.myProperty = "Hello";
// 獲取對象屬性值
console.log(myObj.myProperty); // 輸出 "Hello"
interface/implements
定義并實現接口
// 定義接口
interface MyInterface {myMethod(): void;
}// 實現接口
class MyClass implements MyInterface {myMethod() {console.log("Implementing MyInterface");}
}const myObj = new MyClass();
myObj.myMethod(); // 輸出 "Implementing MyInterface"
yield
生成器函數暫停
function* myGenerator() {yield 1;yield 2;yield 3;
}const generator = myGenerator();
console.log(generator.next().value); // 輸出 1
console.log(generator.next().value); // 輸出 2
console.log(generator.next().value); // 輸出 3
編寫可能有誤,請您不吝指導。