本节我们讲变量的声明,变量从字面意思来理解,就是可以改变的量。而从编程角度来说,变量就是内存中的命名空间,主要用于存储值,我们可以把它理解为程序中值的容器。
我们知道 Typescript
有一个特定就是变量是强类型的,也就是说在声明变量的时候必须给这个变量指定一个类型。
这与 Javascript
不同, Javascript
是弱类型语言,在 Javascript
中声明变量时不需要指定类型。声明变量的方式在 Javascript
中可以通过关键字 var
、 let
、 const
来声明变量,当然 Typescript 中同样也可以。这三种声明变量的方式各有不同,如下所示:
- 使用
var
关键字声明变量,其作用于为该语句所在的函数内, 且存在变量提升现象。 let
的声明类似于var
,但是它的作用域为该语句所在的代码块内,不存在变量提升。注意它们一个是函数内,一个是代码块内,代码块就是直接使用
{}
括起来的代码。const
是let
的一个扩展,它可以防止重新分配变量,一般用来声明常量,在后面出现的代码中不能再修改常量的值。
Typescript
的变量命名规则,如下所示:- 变量名称可以包含数字、字母、下划线
_
和美元$
符号,其他都不可以,例如a
、abc
、AA
、a_
都符合命名规范。 - 变量名不能以数字作为开头,例如
7a
就不符合变量的命名规范,而a7
是可以的。
Javascript
语言中我们都是使用关键字 var
来声明变量的。那么为什么在
Typescript
中我们更偏向于使用 let
,下面我们会讲到原因。在 Typescript
中声明变量其实就和 Javascript
很类似。但因为一个是强类型语言一个是弱类型语言,所以两者在声明变量的格式上会有一些不同。在 Typescript
中声明变量,一共有四种方式:
- 第一种,声明变量的类型及初始值,需要在变量名后面加上变量
:
和变量类型:
var [变量名] : [类型] = 值;// 例如var a : number = 1;
- 第二种,声明变量的类型,但是不赋初始值。
在这种情况下,该变量的值默认为
undefined
:
var [变量名] : [类型];// 例如var a:number;
- 第三种,声明变量并赋初始值,但不声明类型,此时变量类型将被设置为any(任意类型),这种声明方式和
Javascript
中的类似:
var [变量名] = 值;// 例如 var a = 1;
- 第四种,不声明变量类型,且不赋初始值。在这种情况下,变量的数据类型为
any
,初始化值为undefined
:
var [变量名];// 例如var a;
示例:例如我们用 4 种不同的方式分别声明 4 个不同的变量,并且输出它们的值:// 第一种
var
a
:
number
=
100
;
console
.
log
;
// 第二种
var
b
:
string
;
b
=
'xkd'
;
console
.
log
;
// 第三种
var
c
=
true
;
console
.
log
;
// 第四种
var
d
;
d
=
[
1
,
2
,
3
];
console
.
log
;
使用 tsc test.ts
命令编译后会得到如下 Javascript
代码:// 第一种
var
a
=
100
;
console
.
log
;
// 第二种
var
b
;
b
=
'xkd'
;
console
.
log
;
// 第三种
var
c
=
true
;
console
.
log
;
// 第四种
var
d
;
d
=
[
1
,
2
,
3
];
console
.
log
;
执行代码,输出:100xkdtrue[ 1, 2, 3 ]
需要注意的是,在给变量命名的时候,记得不要使用 name
,否则会和 DOM
中全局 window
对象下的 name
属性出现重名。示例:我们在 VSCode
中编写代码的时候,如果使用 name
作为变量名,VSCode
会直接提示错误,如下图所示:VSCode
中会用红色波浪线提示我们这样做是错误的,将鼠标放到红色波浪线上,会出现错误原因。类型断言Typescript
中允许将变量从一种类型更改为另一种类型。var str1 = '1' var str2 : number = 100 ; console . log ); console . log ); var str2 : number = < number > < any > str1 // 类型断言 console . log ); console . log ); var str1 = '1' ; var str2 = 100 ; console . log ); console . log ); var str2 = str1 ; // 类型断言 console . log ); console . log );Typescript
将此过程称为类型断言(Type Assertion)。实现方法就是将目标类型用 <>
符号包围,并将其放在变量或表达式的前面。语法:<类型> 值
示例:例如下面这段代码:
编译成 Javascript
代码:
输出结果:stringnumberstringstring
类型断言看起来很像类型转换,但是其实并不一样,一般类型转换意味着某种运行时的支持,而类型断言只是一个编译时构造,是一种向编译器提供有关如何分析代码的提示方法。Typescript
会假设你已经进行了必须的检查。
除此之外,类型断言还有另一种语法形式,这两种形式的写法是等价的,至于使用哪个大多数情况下是凭个人喜好。如下所示:值 as 类型
但是如果我们在 Typescript
里使用 JSX
,就只支持此种写法。变量作用域一个变量的作用域指定了这个变量的定义位置,程序中变量的可用性是由它作用域决定的。变量不可以在作用域以外的地方使用。
Typescript
的作用域分为下面三种:
- 全局作用域:全局变量定义在程序结构的外部,可以在代码的任何位置使用。
- 局部作用域:局部变量,只能在声明它们的函数或代码块中访问。
- 类作用域:也可称为字段,类变量声明在一个类里头,但在类的方法外面,该变量可以通过类的对象来访问。
类变量也可以是静态的,静态的变量可以通过类名直接访问。
var
global_a
=
1
;
// 全局变量
class
Person
{
class_a
=
2
;
// 类变量
static
static_a
=
3
;
// 静态变量
show
:
void
{
var
local_a
=
4
;
// 局部变量,只能在定义它的函数中使用
}
}
// 全局变量可以在全局使用
console
.
log
;
// 静态变量可以直接通过类名访问
console
.
log
;
// 实例化类
var
per
=
new
Person
;
// 类变量需要通过实例对象访问
console
.
log
;
使用tsc test.ts
编译后的 Javascript
代码:var
global_a
=
1
;
// 全局变量
var
Person
=
{
function
Person
{
this
.
class_a
=
2
;
// 类变量
}
Person
.
prototype
.
show
=
function
{
var
local_a
=
4
;
// 局部变量,只能在定义它的函数中使用
};
Person
.
static_a
=
3
;
// 静态变量
return
Person
;
});
// 全局变量可以在全局使用
console
.
log
;
// 静态变量可以直接通过类名访问
console
.
log
;
// 实例化类
var
per
=
new
Person
;
// 类变量需要通过实例对象访问
console
.
log
;
执行 Javascript
代码,输出:全局变量:1静态变量:3实例变量:2
首先 global_a
是一个全局变量,可以在全局范围中使用,例如可以在 Person
类外部使用,在 Person
类里面使用,还可以在 show
函数中使用。而 class_a
是类变量,定义在类中的变量叫做类变量,我们可以通过类的实例对象访问类变量,如 per.class_a
。static_a
也是一个类变量,但是这个变量被 static
关键字修饰,所以它也是一个静态变量,静态变量可以直接通过类名来访问,如 Person.static_a
。最后就是局部变量 local_a
,这个变量的作用域仅在它所处的函数内,所以它只能在 show
函数中使用,如果在其他地方使用则会报错。现在你弄清楚了什么是局部变量、全局变量、类变量吗。