工具: PlayGround
变量
变量的声明和其他语言类似,一般采用小驼峰法,函数相关采用大驼峰法,常用的规则:
- 不以数字开头,首字母小写
- 变量不包含初下划线或$以外的特殊字符
- 首字母带有下划线,一般作为类的私有变量
- 变量字母均大写,一般作为常量表示
在TypeScript语言中,注释单行使用 //
,多行使用 /**/
;每行代码的结尾推荐添加;
。
注:测试数据,可以使用
console.log(value)
来检测
// 声明结构:let 变量名: 类型 = 值
let num: number = 0;
let str: string = 0;
let isExist: boolean = false;
// 声明可以忽略类型
let value = 10;
// 声明可以忽略值,没有赋值则默认undefined
let data;
console.log(data); // undefined
变量声明的关键字是: let
, 它的特点是:
- 不允许重复声明
- 变量作用域不能提升
- 块作用域
{
let value = 0;
console.log(value); // 0
}
// Error: value is not defined
console.log(value);
在一些面试中,经常会拿 var
和 let
相比较,两者相比较:
- 作用域不同: var属于函数作用域, let属于块作用域, 也就是var的作用域更大更广
- 重复声明: var允许多次声明,let如果重复声明会报错
- 变量提升: var允许声明之前即可使用, let不允许
// var
function example() {
var x = 10;
if (true) {
var x = 20; // 在同一函数作用域内重复声明变量x
console.log(x); // 输出:20
}
console.log(x); // 输出:20
}
example();
// let
function example2() {
let y = 10;
if (true) {
let y = 20; // 在块级作用域内声明变量y
console.log(y); // 输出:20
}
console.log(y); // 输出:10
}
example2();
注: 从代码安全角度来说,推荐let的使用
变量类型
在TypeScript中,基础的变量类型主要有:
类型 | 说明 |
---|---|
number | 双精度64位浮点数,TypeScript和JavaScript没有整数 |
string | UTF-16格式的字符串序列,可使用单引号或双引号包含字符串 |
boolean | 布尔类型,使用true 和false |
void | 函数返回类型,表示无任何类型 |
array | 数组 |
Enum | 枚举,默认为0,也可设置为字符串类型 |
any | 表示任意类型 |
undefined | 未声明的对象,及变量已定义但尚未赋值 |
null | 空对象 |
在实际的开发应用中,允许对变量类型通过|
进行多个声明:
let data_1: number | string = 1;
let data_2: any = null;
let data_3: number | number[] = [];
enum kColor {
RED = 0, // 可以忽略设置数值,默认为0
GREEN,
BLUE,
}
同样的针对于函数的返回类型也允许多个声明:
function getValue(): number | null {
return null;
}
function getData() : number[] | any {
return [];
}
Symbol
symbol
是ES6新增的原始变量类型,表示独一无二的值,可被用于定义对象的唯一属性名:
// lib.es2015.symbol.d.ts
interface SymbolConstructor {
readonly prototype: Symbol;
// 创建symbol对象
(description?: string | number): symbol;
// 全局搜索指定key字符串的symbol对象
for(key: string): symbol;
// 获取symbol对象的key, 如果没有则undefined
keyFor(sym: symbol): string | undefined;
}
declare var Symbol: SymbolConstructor;
主要用法:
- 定义常量,保证不同常量的唯一性
- 作为对象的属性名, 使用
[]
来设定,不要使用.
let sy = Symbol("key1");
let obj = {
[sy]: "kk",
value: 10,
};
// 虽然作为对象的属性名,但其实是不可读的, 结果是:{"value": 10}
console.log(obj);
类型检测:typeof
数值的类型检测,通常使用接口: typeof(value)
let num: number = 0;
console.log(num, typeof(num)); // 0, "number"
let str: string = "";
console.log(str, typeof(str)); // "", "string"
let bool: boolean = false;
console.log(bool, typeof(bool)); // false, "boolean"
let data: any = null;
console.log(data, typeof(data)); // null, "object"
let array: number[] = [];
console.log(array, typeof(array)); // [], "object"
let map = {};
console.log(map, typeof(map)); // {}, "object"
let func = function() {};
console.log(func, typeof(func)); // function () { }, "function"
object
可以理解为非原始数据类型之外的对象类型。有意思的一点是: null的类型是object 。
在JavaScript或TypeScript中有着很多的不合理数值,在后续的文章中会一一了解,在这里简要说明下主要有:
数值 | 说明 |
---|---|
0 | 数字0 |
false | 布尔类型,假 |
null | 空对象, 使用typeof判定为: “object” |
undefined | 未定义的对象,使用typeof判定为: “undefined” |
NaN | 数字类型,但代表非数字特殊值,非法的数值 |
[] | 空数组 |
{} | 空对象 |
注: 两个NaN比较,它们并不相等
一般情况下都会通过运算符 !
或 !=
运算符进行非法数据的判定, 但针对于 object 对象需要注意:
// 检测非法数值,如果是,则返回true
console.log(!0); // true
console.log(!false); // true
console.log(!null); // true
console.log(!undefined); // true
console.log(!NaN); // true
console.log(![]); // false
console.log(!{}); // false
针对于非法object对象的的数组和对象是无法进行判定的,这一点需要注意。 推荐解决方式:
// 数组对象
let array: any[] = [];
if (!array || array.length <= 0) {
console.error("array is null"); // "array is null"
}
// map对象,示例1
let map = {};
if (!map || Object.keys(map).length <= 0) {
console.error("map is null"); // "map is null"
}
// map对象,示例2:
let dataMap = new Map();
if (!dataMap || dataMap.size <= 0) {
console.error("dataMap is null"); // "dataMap is null"
}
装箱和拆箱
在后续的文章中,针对于数字,布尔和字符串这些原始数据类型,我们会相对应的使用Number、Boolean和String对象。
原始数据类型 | 对象类型 | 说明 |
---|---|---|
number | Number | 数字类型 |
boolean | Boolean | 布尔类型 |
string | String | 字符串类型 |
[] | Array | 数组 |
{} | Map | Key-value对象 |
在开发中, 原始数据可以调用对应对象的属性和函数来实现一些效果。
let str = "hello TypeScript";
console.log(str.toUpperCase()); // "HELLO TYPESCRIPT"
const strObj = new String(str);
console.log(strObj.toUpperCase()); // "HELLO 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 | 用于对对象属性变量的获取或设置,多用于class属性值对象的获取和设置 |
module/namespace | module 用于定义一个模块,用于组织和封装相关代码, 自TypeScript 2.7版本起,逐渐被namespace 代替 |
type/typeof | type 用来做类型别名, typeof 用来获取数据类型 |
instanceof | JavaScript的运算符,用于检查对象是否是指定类的实例 |
public/private/protected | 可用于声明类方法类型是公有还是私有 |
export | 用于将模块中的变量,函数,类等导出,可以被其他模块使用 |
import | 用于导入变量,函数,类相关,与export 配对使用 |
super | 用于派生类调用基类的构造函数,方法和属性相关 |
this | 在类中使用,用于引用当前对象 |
extends | 用于类继承相关 |
implements/interface | interface 用于定义一个接口,通过implements 来实现接口 |
yield | 用于定义**生成器(特殊函数,可以在执行过程中暂停和恢复)**函数的暂停点,可以将值返回给调用者,异步编程 |
一些简单的实例:
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
注:
switch
注意break的调用
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';
注:针对于export的常量、枚举等声明推荐使用大写
interface/implements
定义并实现接口
// 声明接口
interface MyInterface {
myMethod(): void;
}
// 实现接口
class MyClass implements MyInterface {
myMethod() {
console.log("Implementing MyInterface");
}
}
const myObj = new MyClass();
myObj.myMethod(); // 输出 "Implementing MyInterface"
// interface 也可以用来定义数据结构
interface Data {
index: number,
name: string,
dataList: any[],
map: {},
}
let data:Data;
data = {
index: 1,
name : "typeScript",
dataList: [1, "2", true],
map: {a: 1, b:2},
};
console.log(data);
编写可能有误,请您不吝指导。