5.TypeScript变量

变量声明

变量是一种占位符,用于引用计算机内存地址,在程序中需要把数据放在该地址上。这里可以把变量看做存储数据的容器。
变量的命名需要遵循一些标准/规则:

  • 除了下划线 _ 和美元 $ 符号外,不能包含其他特殊字符,包括空格
  • 不能以数字开头
  • 大多数情况下都是字母组成的

在TS中声明变量的语法为:

类型关键字 变量名 : 变量类型关键字[可选];

在TS中,可以通过var、let、const关键字来声明变量,如:

let myName : string;

声明变量的目的是存储值来使用,如果变量没有值就没有任何意义。
这个过程叫赋值,TS中给变量赋值的语法为:

变量名 = 值;

注意变量必须先声明才能赋值。
变量的声明和赋值可以一起,如:

let myName  =  “小明”;

变量的声明书写方式有四种,可以根据习惯或实际情况进行选择。

  1. 声明变量的类型及初始值:
    声明关键字 [变量名] : [类型] = 值;
    如:
    let myName : string = "小明";
    
  2. 声明变量的类型,但没有初始值,变量值会设置为 undefined:
    声明关键字 [变量名] : [类型];
    如:
    let myName : string;
    
  3. 声明变量并初始值,但不设置类型,该变量会被推断为值的类型:
    声明关键字 [变量名] = 值;
    如:
    let myName = “小明”;
    
    值“小明”是字符串类型,在编译时变量myName会被推断为字符串类型。
  4. 声明变量没有设置类型和初始值,类型可以是任意类型,默认初始值为 undefined:
    声明关键字 [变量名] ;
    如:
    let myName;
    
    变量myName可以是任意类型,默认初始值是undefined。

var 、let 和 const

在ES5及之前,JS都是用var关键字来声明变量。
var对作用域的限制相当错乱,这里指的错乱不是var本身,而是编写层次上的。举个例子,变量的作用域限制在声明的函数内部,如果在函数外部访问,将会报错,这个归类于函数作用域。然而变量声明如果被提升到作用域的顶部,无论声明语句在哪里,都会被视为在作用域的开始处声明的,如果代码量过大,这很考验开发者的能力(对于个人来说是记忆和逻辑上的折磨)。更不用说在同一个作用域内,可以多次使用var声明同一个变量,后面的声明会覆盖前面的。这些var的特性常常导致意外的bug。为了解决这些问题,ES6引入了let和const关键字,作为块级作用域的变量声明方式。

  • let关键字
    • 1.let声明的变量仅在其作用域内有效,如果在外部访问会报错。这种特性使得代码更容易维护。
    • 2.同一个作用域内不可以多次使用let声明同一个变量,否则会报错。
    • 3.let只有在声明语句之后才能使用。
      这种特性使开发者可以更好地控制变量的作用范围,逻辑更清晰,可读性更好,定位错误也会比较容易。
  • const关键字
    使用const声明的变量是常量,意味着一旦被赋值后,就不能再修改。常量的命名通常使用全大写字母,并采用下划线分隔单词(这个是默认书写习惯,不是标准)。其他特性和let 一样。
    常量的不可修改性可以避免错误的赋值操作,提高代码的可靠性。

总结:
let和const声明变量已经足够应付大大部分场景,而且它们更安全、更易于维护。只有在特殊情况下(例如需要在函数作用域内声明变量),才使用var。

类型推断

当类型没有给出时,TypeScript 编译器利用类型推断来推断类型。
如果由于缺乏声明而不能推断出类型,那么它的类型被视作默认的动态 any 类型。
举个例子:

let num = 2;    // 类型推断为 number
console.log("num 变量的值为 "+num); 
num = "12";    // 编译错误
console.log(num);

第一行代码声明了变量 num 并=设置初始值为 2。 注意变量声明没有指定类型。因此,程序使用类型推断来确定变量的数据类型,第一次赋值为 2,num 设置为 number 类型。
第三行代码,当再次为变量设置字符串类型的值时,这时编译会错误。因为变量已经设置为了 number 类型。

类型断言

类型断言可以通过语法手动指定一个值的类型,即允许变量从一种类型更改为另一种类型。
语法:

<类型>值; 或者 值 as 类型

举个例子:

let str = '100' ;
let str2:number = <number> str;
let str3 = str2 as string;
console.log(str);
console.log(str2)
console.log(str3)

类型断言是一个编译时语法,在进行类型断言时需要保证其安全性(有根据的进行),例如当 S 类型是 T 类型的子集,或者 T 类型是 S 类型的子集时,S 能被成功断言成 T。如果进行类型断言时不能保证其安全性,运行时可能会出现无法预知的问题。
为什么不叫类型转换?类型转换通常意味着某种运行时的支持。类型断言纯粹是一个编译时语法。

变量作用域

TS中有三种作用域,在不同作用域中声明的变量用法和作用各不相同。

  • 全局作用域
    变量定义在程序结构的外部,可以在代码的任何位置访问。这种又叫全局变量。
  • 类作用域
    在类中(不在方法中)声明的变量,又叫字段。可以在类的内部访问,不能直接在类外访问,可以变量通过类的对象来访问。字段也可以是静态的(static关键字修饰),静态的变量可以通过类名直接访问
  • 局部作用域
    在一个代码块中声明的变量(比如在方法中声明的变量),只能在该代码块中使用,又叫局部变量。
    举个例子:
let global_num = 12          // 全局变量
class Numbers { 
   num_val = 13;             // 字段
   static sval = 10;         // 静态变量
   
   storeNum():void { 
      let local_num = 14;    // 局部变量
   } 
} 
console.log("全局变量为: "+global_num)  
console.log(Numbers.sval)   // 静态变量
let obj = new Numbers(); 
console.log("实例变量: "+obj.num_val)

如上如果在方法外部调用局部变量 local_num,会报错

posted @ 2024-11-06 18:57  EricShx  阅读(105)  评论(0)    收藏  举报