/**
* typeScript 学习1 数据类型
* number 数字类型
* string 字符串类型
* boolean 布尔类型
* Array 数组
* Tuple 元组
* enum 枚举
* Any 任意类型
* void 无任何类型
* null 空类型
* undefined 未定义类型
* never 永远不存在值的类型
* `unknown 未知类型
* Symbols 符号
* object 非原始类型 (非 number,string,boolean,symbol,null,undefined)
*
* 请将 strictNullChecks 设置成立 false
*/
/**
* 数字类型 number
* 0x 十六进制
* 0o 八进制
* 0b 二进制
*/
let decLiteral:Number = 10;
let hexLiteral: number = 0xf00d; // 十六
let binaryLiteral: number = 0b1010;// 二
let octalLiteral: number = 0o744; // 八
/**
* 布尔类型 boolean
* 布尔类型值 只能是 false || true
*/
let isBoolen:boolean = false; // 布尔类型
/**
* 字符串类型 string
* '' 单引号 let str_1: string = "单引号,定义字符串";
* "" 双引号 let str_1: string = "双引号,定义字符串";
* `` 反引号 let str_3: string = `反引号, 定义模板字符串,里面可以 ${0-0} 引用变量或进行运算`;
*/
let str:string = '字符串'
/**
* 数组类型 Array
* 名称: 数据类型[] 元素类型后接[]
* 名称: Array<数据类型> 泛型数组 let arr_2: Array<number> = []
* 名称:readonlyArray<数据类型> 只读数组
*/
let num_arr1: number[] = [];
let num_arr2: Array<number> = []; // 泛型数组\
/**
* 元组类型 Tuple
* 名称: [类型1,类型2,...] = [对应类型1的值,对应类型2的值]
* 元组类型的变量,在创建的时候,就确定了,有多少个元素和每个元素的元素类型。
* ts 官方文档说 越界添加元素 会使用联合类型(number | string)代替,但是在 vscode 实验的时候会直接报错
*/
let tuple: [number, string, boolean?] = [0, '元组'];// 元组
/**
* 枚举类型 enum
* 数字枚举 enum enum_1{a, b=2, c, d=a,e = getValue()} 数字枚举,如果第一位没有赋值 则以0为初始值,后续未赋值元素以前一位元素的值自增1
* 字符枚举 enum enum_2{a="a", b=a} 字符枚举, 每个属性都需要初始化
* 异构枚举 enum enum_3{a,b=2} 异构枚举, 同时使用字符枚举和数字枚举,不推荐使用,字符串枚举后的一个成字段必须赋值
* 常量枚举 const enum enum_5{} 常量枚举,编译后不会产生对象
*
* 枚举中的每个字段都有一个值,这个值可以是常量、计算出的结果(只有数字枚举可用)、另一个枚举成员(字符串枚举中,这个枚举成员指的是同一个枚举中不同的成员)
* 数字枚举,中的某个字段使用了计算值或常量,那么紧接其后的那个字段必须设置初始值
* 字符枚举,中不能使用常量、计算值作为字段的值
* 枚举成员类型,如果枚举中所有成员都是字面量类型的值(字面量类型是js提供的一个准确变量: let a:"hello" = "hello"),那么枚举成员和枚举值本身就可以作为类型来使用
* * 没有初始值的枚举成员
* * 值为字符串字面量
* * 值为数值字面量,或者带有-符号的数值字面量
* 联合枚举类型,当枚举值符合条件时,这个枚举值就可以看做是一个包含所有成员的联合类型
*
* 反向映射,枚举中存在反向映射,即 可用通过枚举成员查找枚举值,也可以使用枚举值查找枚举成员
* 枚举合并:枚举的成员可用分开声明
*
* 枚举在js中的实现:
* let Enum;
* (function(Enum) {
* Enum[Enum['A'] = 0] = "A";
* })(Enum || (Emum = {}));
*/
enum Color {Red, Green, Blue}; // 枚举类型
let c:Color = Color.Red;
/**
* Any 类型
* 无法确认变量是什么类型的时候可以设置成any类型
* ts中对 any 类型没有进行类型检查,所以 any 可以赋值为任意类型,且可以访问任意属性和方法
* 定义变量时未指定类型会被编译成any类型
*/
let notSure:any = 4; // any 允许 编译时可选择地包含或移除类型检查。与 Object有相似 但是可以调用方法
notSure.toFixed()
let anyList: any[] = [1,'1',Color.Red]
/**
* void 类型
* void 类型与 any 类型,刚好相反 void 类型表示没有任何类型, 一般用于没有返回值的函数
* void 类型的变量 只能赋值 undefined 和 null
*/
const returnVoid = ():void => {}
let unusable: void = null || undefined;
/**
* Null类型 和 Undefined类型
* undefined和null的类型分别叫做undefined和null和void相似,它们的本身的类型用处不是很大
* undefined 类型,表示 此处应当有值,但是现在没有
* 默认下null和undefined是所有类型的子类型
*/
let u: undefined = undefined;
let n: null = null;
/**
* never 类型
* never 类型,表示永不存在的值类型
* never类型是任何类型的子类型,也可以赋值给任何类型
* 除了never本身之外,没有类型是never的子类型或可以赋值给never类型
* 返回never的函数必须存在无法达到的终点(可以是 死循环,错误处理...)
*/
// 返回never的函数必须存在无法达到的终点
const error = (message: string) => { throw new Error(message) };
/**
* unknown 类型
* unknown 类型,表示未知类型,可以被任何类型分配,不能分配给任何类型
*/
let unknownValue: unknown = '可以被任何类型分配,不能分配给任何类型';
/**
* Object 类型
* 除number,string,boolean,symbol,null或undefined之外的类型
*/
declare function create(o: object | null): void;
// create({prop: 0})
/**
* Symbols 类型
* symbol类型的值是通过Symbol构造函数创建的
* symbol类型创建的变量具有唯一性,且不可以改变
*/
let symbol_0: symbol = Symbol("key");
let symbol_1: symbol = Symbol("key");
let str_4: string = "key"
let str_5: string = "key"
console.log(symbol_0 === symbol_1, str_4 === str_5); // -> false true
/**
* 类型断言
* as 关键字 let as_1: string = 1 as string;
* <> 尖括号 let as_2: string = <string>1;
*/
// let as_1:string = 1 as string; //
// let as_2: string = <string>1;
/**
* let、var、const 的区别
* var 无 块级作用域,同一作用域下变量可重复定义,且只得到一个,而且存在变量提升
* let 有 块级作用域,同一作用域下变量不可重复定义
* const 用来声明 初始化后 值不会被修改的变量
* const 对于 对象 只检查这个对象的地址不会检查对象内部属性的修改
*
* 在 js 中变量存储主要有 堆内存,栈内存两种方式,栈内存主要存储各种变量和指向对象地址的指针, 堆内存主要负责像Object这种变量类型的存储
*/
for (var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i); // -> 10
}, 100 * i);
}
for (let i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i); // -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
}, 100 * i);
}
const a = {
name: "00"
}
// a = {}; // 会报错 因为 此处的 {} 是一个新的对象(地址变换了)
a.name = "xxx"; // 不会报错,因为 const 只保证 指针指向的地址不会变动,而对于属性的修改 是直接操作了 这个地址块对应的数据块中的数据,而没有修改地址