operator.md 30.7 KB
Newer Older
D
DCloud_LXH 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
# 操作符@operator

## 赋值运算符(Assignment operators)@Assignment-operators

| 名字                                              | 简写的操作符 | 含义        |
| ------------------------------------------------- | ------------ | ----------- |
| 赋值(Assignment)                                  | x = y        | x = y       |
| 加法赋值(Addition assignment)                     | x += y       | x = x + y   |
| 减法赋值(Subtraction assignment)                  | x -= y       | x = x - y   |
| 乘法赋值(Multiplication assignment)               | x \*= y      | x = x \* y  |
| 除法赋值(Division assignment)                     | x /= y       | x = x / y   |
| 求余赋值(Remainder assignment)                    | x %= y       | x = x % y   |
| 左移位赋值(Left shift assignment)                 | x <<= y      | x = x << y  |
| 右移位赋值(Right shift assignment)                | x >>= y      | x = x >> y  |
| 无符号右移位赋值(Unsigned right shift assignment) | x >>>= y     | x = x >>> y |
| 按位与赋值(Bitwise AND assignment)                | x &= y       | x = x & y   |
| 按位异或赋值(Bitwise XOR assignment)              | x ^= y       | x = x ^ y   |
| 按位或赋值(Bitwise OR assignment)                 | x \|= y      | x = x \| y    |

## 比较运算符(comparison operators)@Comparison-operators

| 运算符                              | 描述                                        | 返回 true 的示例 |
| ----------------------------------- | ------------------------------------------- | ---------------- |
| 等于 Equal (==)                     | 如果两边操作数相等时返回 true。             | var1==var2       |
| 不等于 Not equal (!=)               | 如果两边操作数不相等时返回 true             | var1!=var2       |
DCloud-yyl's avatar
DCloud-yyl 已提交
26 27
| 引用相等 Reference equal (===)      | 比较对象类型时,两边操作数指向同一个对象返回 true。比较基础类型时各平台有差异,[详情](#completeComparison)。 | var1===var2      |
| 引用不等 Reference not equal (!==)  | 比较对象类型时,两边操作数不指向同一个对象时返回 true。比较基础类型时各平台有差异,[详情](#completeComparison)。 | var1!==var2      |
D
DCloud_LXH 已提交
28 29 30 31 32 33 34 35 36 37 38
| 大于 Greater than (>)               | 左边的操作数大于右边的操作数返回 true       | var1>var2        |
| 大于等于 Greater than or equal (>=) | 左边的操作数大于或等于右边的操作数返回 true | var1>=var2       |
| 小于 Less than (<)                  | 左边的操作数小于右边的操作数返回 true       | var1<var2        |
| 小于等于 Less than or equal (<=)    | 左边的操作数小于或等于右边的操作数返回 true | var1<=var2       |

## 算数运算符(Arithmetic operators)@Arithmetic-operators

| 运算符   | 范例 | 描述                                                                                                                                     |
| -------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| 求余(%)  |      | 二元运算符. 返回相除之后的余数.                                                                                                          |
| 自增(++) |      | 一元运算符. 将操作数的值加一. 如果放在操作数前面 (++x), 则返回加一后的值; 如果放在操作数后面 (x++), 则返回操作数原值,然后再将操作数加一. |
D
DCloud_LXH 已提交
39
| 自减(--) |      | 一元运算符. 将操作数的值减一. 前后缀两种用法的返回值类似自增运算符.
D
DCloud_LXH 已提交
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| 加(+)  |      | 二元运算符. 将两个数相加.                                                                                                          |
| 减(-) |      | 二元运算符. 将两个数相减. |
| 乘(*) |      | 二元运算符. 将两个数相乘.                                                                    |
| 除(/) |      | 二元运算符. 将两个数相除.                                                                    |

## 位运算符(Bitwise operators)@Bitwise-operators

| Operator                        | Usage   | Description                                                                                                      |
| ------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
| 按位与 AND                      | a & b   | 在 a,b 的位表示中,每一个对应的位都为 1 则返回 1, 否则返回 0.                                                   |
| 按位或 OR                       | a \| b  | 在 a,b 的位表示中,每一个对应的位,只要有一个为 1 则返回 1, 否则返回 0.                                         |
| 按位异或 XOR                    | a ^ b   | 在 a,b 的位表示中,每一个对应的位,两个不相同则返回 1,相同则返回 0.                                             |
| 按位非 NOT                      | ~ a     | 反转被操作数的位。                                                                                               |
| 左移 shift                      | a << b  | 将 a 的二进制串向左移动 b 位,右边移入 0.                                                                         |
| 算术右移                        | a >> b  | 把 a 的二进制表示向右移动 b 位,丢弃被移出的所有位.(译注:算术右移左边空出的位是根据最高位是 0 和 1 来进行填充的) |
| 无符号右移(左边空出位用 0 填充) | a >>> b | 把 a 的二进制表示向右移动 b 位,丢弃被移出的所有位,并把左边空出的位都填充为 0                                   |

**bug&tips**

位运算符 暂时不支持 小括号运算提级


```uts

let a = 64|(1<<8)

```

期望的是先进行小括号内的左移操作


类似场景,需要拆分一个中间变量来处理

```uts
let temp = 1 << 8
let a = 64 | temp

```

这个问题后续会修复


## 逻辑运算符(Logical operators)@Logical-operators

| 运算符       | 范例             | 描述     |
| ------------ | ---------------- | -------- |
fxy060608's avatar
fxy060608 已提交
86 87 88 89 90
| 逻辑与(&&)   | condition1 && condition2   | (逻辑与) |
| 逻辑或(\|\|) | condition1 \|\| condition2 | (逻辑或) |
| 逻辑非(!)    | !condition1            | (逻辑非) |

**注意**
fxy060608's avatar
fxy060608 已提交
91 92

逻辑运算符操作数的类型必须是 boolean
D
DCloud_LXH 已提交
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181

## 字符串运算符(String operators)@String-operators

除了比较操作符,它可以在字符串值中使用,连接操作符(+)连接两个字符串值相连接,返回另一个字符串,它是两个操作数串的结合。

```ts
console.log("my " + "string"); // console logs the string "my string".
```
**注意**

在iOS平台,连接操作符(+)目前仅支持字符串的连接,即+操作符前后都必须是字符串类型。

## 条件(三元)运算符(Conditional operator) @Conditional-operator

条件运算符是 uts 中唯一需要三个操作数的运算符。运算的结果根据给定条件在两个值中取其一。语法为:

`条件 ? 值1 : 值2`

```ts
const status = age >= 18 ? "adult" : "minor";
```

## 操作符列表

- `+`
    * 相加运算符 (+) 用于对两个操作数进行相加运算。
- `+=`
    * 加法赋值操作符 (+=) 将右操作数的值添加到变量,并将结果分配给该变量。两个操作数的类型确定加法赋值运算符的行为。
- `=`
    * 简单赋值操作符 (=) 用于为变量赋值。赋值表达式本身的值为要赋值的值。
- `&`
    * 按位与运算符 (&) 在两个操作数对应的二进位都为 1 时,该位的结果值才为 1,否则为 0。
- `&=`
    * 按位与赋值运算符(&=)表示两个操作数的二进制,对它们进行按位 AND 运算并将结果分配给变量。
- `~`
    * 按位非运算符(~),反转操作数的位。
- `|`
    * 按位或运算符(|),如果两位之一为 1 则设置每位为 1。
- `|=`
    * 按位或赋值操作符 (|=) 使用二进制表示操作数,进行一次按位或操作并赋值。
- `^`
    * 按位异或运算符(^),如果两位只有一位为 1 则设置每位为 1。
- `^=`
    * 按位异或赋值操作符 (^=) 使用二进制表示操作数,进行一次按位异或操作并赋值。
- `?`
- `--`
    * 自减运算符 (--) 将它的操作数减一,然后返回操作数。
- `/`
    * 除法运算符 (/) 计算了两个操作数的商,左边的数是被除数,右边的是除数。
- `/=`
- `==`
- `>`
    * 当左边操作数大于右边的时候,大于 (>) 运算符返回true,否则返回false。
- `>=`
    * 当左边操作数大于等于右边的时候,大于等于 (>=) 运算符返回true,否则返回false。
- `++`
    * 自增运算符 (++) 将其操作数递增(加 1)并返回一个值。
- `!=`
- `<<`
    * 左移操作符 (<<) 将第一个操作数向左移动指定位数,左边超出的位数将会被清除,右边将会补零。
- `<<=`
    * 左移赋值运算符 (<<=) 将变量向左移动指定数量的位,并将结果赋值给变量。
- `<`
    * 当左边操作数小于右边的时候,小于 (<) 运算符返回true,否则返回false。
- `<=`
    * 当左边操作数小于等于右边的时候,小于等于 (>=) 运算符返回true,否则返回false。
- `&&`
    * 逻辑与
- `&&=`
- `!`
- `??=`
- `||`
    * 逻辑或。
- `||=`
    * 逻辑或赋值(x ||= y)运算仅在 x 为虚值时赋值。
- `*`
    * 乘法运算符 (*) 计算操作数的乘积。
- `*=`
- `??`
- `?.`
    * 可选链运算符(?.)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 运算符的功能类似于 . 链式运算符,不同之处在于,在引用为空 (nullish ) (null) 的情况下不会引起错误。
- `%`
    * 当一个操作数除以第二个操作数时,取余运算符(%)返回剩余的余数。它与被除数的符号保持一致。
- `%=`
- `>>`
    * 右移操作符 (>>) 是将一个操作数按指定移动的位数向右移动,右边移出位被丢弃,左边移出的空位补符号位(最左边那位)。
- `>>=`
    * 右移赋值运算符 (>>=) 将变量向右移动指定数量的位,并将结果赋值给变量。
- `===`
W
wanganxp 已提交
182
    * 当两边操作数指向同一个对象时,引用相等 (===) 运算符返回true。不同平台有差距,[见下](#completeComparison) 
D
DCloud_LXH 已提交
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
- `!==`
    * 当两边操作数不指向同一个对象时,引用不等 (!==) 运算符返回true。
- `-`
- `-=`
- `>>>`
    * 无符号右移运算符(>>>)(零填充右移)将第一个操作数向右移动指定(二进制)位数。
- `>>>=`


## 算数运算符的跨数字类型注意@arithmeticdifftype

uts 中算数运算符在大部分场景下和 ts 中的行为一致,但是在有字面量或者是平台专有数字类型参与运算时,不同平台可能会有不同的表现。
算数运算符 + - * / % 行为一致,下表以 + 和 / 为例列出了各种场景下的详细差异。

- 其中 number 是指 number 类型的变量,字面量是指数字字面量,变量是指平台专有数字类型的变量
- 运算符 / 在 字面量 / 字面量场景下, 结果为 number.

| 场景                                 | 示例                                           | Kottlin 结果                   |  Swift 结果 							  |
| ----------------------------------- | -------------------------------------------   | ------------------------------ |------------------------------------------|
lizhongyi_'s avatar
lizhongyi_ 已提交
202 203
| number + - * / % number                      | number + number            				  | 结果为 number                   |结果为 number				              |
| number + - * / % 字面量 #{rowspan=2}| number + 1                                   | 结果为 number                   |结果为 number 						 	  |
D
DCloud_LXH 已提交
204
| number + 3.14      						  | 结果为 number                   |结果为 number 							  |
lizhongyi_'s avatar
lizhongyi_ 已提交
205
| number + - * / % 变量 #{rowspan=4}| let a: Int = 1; number + a     			  | 结果为 number      			   |结果为 number 						   	  |
D
DCloud_LXH 已提交
206 207 208
| let b: Double = 1;  number + b       		  | 结果为 number        		   |结果为 number 						      |
| let c: Long = 1; number + c 				  | 结果为 number       			   |Swift 中无 Long 							  |
| let d: Int64 = 1; number+ d      			  | kottlin 中无 Int64      		   |结果为 number							  |
lizhongyi_'s avatar
lizhongyi_ 已提交
209
| 字面量 + - * / % number #{rowspan=2}| 1 + number 								  | 结果为 number                   |结果为 number 							  |
D
DCloud_LXH 已提交
210
| 3.14 + number 								  | 结果为 number                   |结果为 number 							  |
lizhongyi_'s avatar
lizhongyi_ 已提交
211
| 变量 + - * / % number #{rowspan=4}| let a: Int = 1; a + number 				  | 结果为 number                   |编译失败,需要用 (a as number) + number 	  |
D
DCloud_LXH 已提交
212 213 214
| let b: Double = 1; b + number 				  | 结果为 number                   |编译失败,需要用 (b as number) + number	  |
| let c: Long = 1;  c + number  				  | 结果为 number                   |Swift 中无 Long 	  						  |
| let d: Int64 = 1; d + number 				  | kottlin 中无 Int64              |编译失败,需要用 (d as number) + number	  |
lizhongyi_'s avatar
lizhongyi_ 已提交
215
| 字面量 + - * % 字面量 #{rowspan=3}| 1 + 1 				  						  | 结果为 2 Int                    |结果为2 Int                          	  |
D
DCloud_LXH 已提交
216 217 218 219 220
| 1 + 3.14 				  					  | 结果为4.14 Double               |结果为4.14 Double	  					  |
| 1.0 + 3.14  				                  | 结果为4.14 Double               |结果为4.14 Double 	 					  |
| 字面量 / 字面量   			           | 1 / 10 				  					  | 无明确类型时为 0.1 number,有类型时遵守类型约定|无明确类型时为 0.1 number,有类型时遵守类型约定|
| 专有类型变量 / 字面量 #{rowspan=2}| let a: Int = 2; a / 10				  		  | 结果为 0 Int                    |结果为0 Int                          	  |
| let a: Int = 2; a / 10.0 				  	  | 结果为 0.2 Double               |编译失败,Int / Double 不合法 需使用 a / Int(10.0)	|
lizhongyi_'s avatar
lizhongyi_ 已提交
221
| 专有类型变量 + - * % 字面量 #{rowspan=2}| let a: Int = 2; a + 10				  		  | 结果为 12 Int                   |结果为12 Int                          	  |
D
DCloud_LXH 已提交
222
| let a: Int = 2; a + 3.14 				  	  | 结果为 5.14 Double              |编译失败, 需要 a + Int(3.14) = 5	          |
lizhongyi_'s avatar
lizhongyi_ 已提交
223
| 相同的专有类型变量 + - * / % 操作 #{rowspan=2}| let a: Int = 1; let b: Int = 2; a + b		  | 结果为 3 Int                    |结果为3 Int                          	  |
D
DCloud_LXH 已提交
224
| let a: Double = 1.0; let b: Double = 2.0; a + b | 结果为 3.0 Double            |结果为 3.0 Double	          			  |
lizhongyi_'s avatar
lizhongyi_ 已提交
225
| 不同的专有类型变量 + - * / % 操作 #{rowspan=2}| let a: Int = 1; let b: Float = 3.14.toFloat(); a + b	  | 结果为4.14, Float   |编译失败,不同类型变量不能操作                 |
D
DCloud_LXH 已提交
226 227
| let a: Float = 1.0.toFloat(); let b: Double = 3.14; a + b| 结果为4.14,Double |编译失败,不同类型变量不能操作          		  |

lizhongyi_'s avatar
lizhongyi_ 已提交
228 229 230 231
number 和平台专有类型的 + - * / % 规则:
- number 在左侧,平台专有类型在右侧,可以进行 + - * / % 操作,其结果是 number. (安卓平台支持所有的专有类型,iOS平台目前支持 Int Double Float Float64 Float32 类型)
- 平台专有类型在左侧,number在右侧,可以进行  + - * / % 操作,其结果是 number. (安卓平台支持所有的专有类型,iOS平台需要将左侧的专有类型变量 as 成 number)

D
DCloud_LXH 已提交
232 233
**已知Bug**
- Android平台 uni-app项目的uts插件中,字面量整数相除时真机运行返回类型为number,云端打包返回类型为Int。如let a = 1/10,真机运行时为值为0.1,云端打包后值为0。此问题在uni-app x项目中不存在。
lizhongyi_'s avatar
lizhongyi_ 已提交
234 235 236
- iOS平台 number 和专有类型的 + - * / 操作目前只支持 Int Double Float Float64 Float32 类型,其余专有类型将在后续版本补齐。
- iOS平台 number 和专有类型的 % 操作目前只支持 Int 类型,其余专有类型的支持将在后续版本补齐。

D
DCloud_LXH 已提交
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260

## 比较运算符的跨数字类型注意@comparisondifftype

uts 中比较运算符在大部分场景下和 ts 中的行为一致,但是在有字面量或者是平台专有数字类型参与比较操作时,不同平台可能会有不同的表现。

### 比较运算符 > >= < <=

比较运算符 > >= < <= 行为一致下表以 > 为例列出了各种场景下的详细差异。

- 其中 number 是指 number 类型的变量,字面量是指数字字面量,变量是指平台专有数字类型的变量

| 场景                                 | 示例                                           | Kottlin 结果                   |  Swift 结果 							  |
| -----------------------------------  | -------------------------------------------   | ------------------------------ |-----------------------------------------|
| number > number                      | number > number            				  | 结果为 true or false            |结果为 true or false  				      |
| number > 字面量                       | number > 1                                   | 结果为 true or false            |结果为 true or false 					  |
| number > 变量                         | let a: Int = 1; number > a     			  | 结果为 true or false      	   |结果为 true or false 					  |
| 字面量 > number				       | 3.14 > number 								  | 结果为 true or false            |结果为 true or false 					  |
| 变量 > number				           | let a: Int = 1; a > number 				  | 结果为 true or false            |结果为 true or false  	  				  |
| 字面量 > 字面量   			           | 3.14 > 1 				  					  | 结果为 true                     |结果为 true                          	  |
| 专有类型变量 > 字面量                   | let a: Int = 2; a > 3.14				  	  | 结果为 false                    |结果为 false                          	  |
| 相同的专有类型变量比较                   | let a: Int = 2; let b: Int = 1; a > b		  | 结果为 true                     |结果为 true                         	      |
| 不同的专有类型变量比较                   | let a: Int = 1; let b: Float = 3.14.toFloat(); a > b	  | 结果为false         |编译失败,不同类型变量不能比较                 |


DCloud-yyl's avatar
DCloud-yyl 已提交
261
### 比较运算符 == != === !==@completeComparison
D
DCloud_LXH 已提交
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283


| 场景                                  | 示例                                           | Kottlin 结果                   |  Swift 结果 							  |
| ------------------------------------ | -------------------------------------------   | ------------------------------ |------------------------------------------|
| number == number (!= === !== 行为相同) | number == number            				  | 值相同就true                     |值相同就true				                  |
| number == 字面量 (!= === !== 行为相同)  | number == 1                                 | 值相同就true                     |值相同就true 						 	  |
| number == 变量 (!= === !== 行为相同)   | let a: Int = 1; number == a     			  | 值相同就true      			   |值相同就true 						   	      |
| 字面量 == number (!= === !== 行为相同) | 1 == number 								  | 值相同就true                     |值相同就true 							  |
| 变量 == number	 (!= === !== 行为相同)  | let a: Int = 1; a == number 				  | 值相同就true                    |值相同就true 	  							  |
| 字面量 == 字面量  (!= 行为相同)		   | 1 == 1 	(相同类型)			  		      | 值相同就true                    |值相同就true                          	  |
|   				      			   | 1 == 3.14 (不同类型)				  			  | 编译失败,不支持比较               |值相同就为true	  					  |
| 字面量 === 字面量  (!== 行为相同)		   | 1 === 1 	(相同类型)			  			  | 值相同就true                     |编译失败,=== 和 !== 只能用于引用类型比较      |
|   				      			   | 1 === 3.14 (不同类型)				  			  | 编译失败,不支持比较               |编译失败,=== 和 !== 只能用于引用类型比较	  |
| 专有类型变量 == 字面量 (!= 行为相同)     | let a: Int = 2; a == 10	 (相同类型)			  | 值相同就true                     |值相同就true                          	  |
|   				      			   | let a: Int = 2; a == 3.14 (不同类型)		  | 编译失败,不支持比较              |值相同就true	                               |
| 专有类型变量 === 字面量 (!== 行为相同)     | let a: Int = 2; a === 10	 (相同类型)		  | 值相同就true                     |编译失败,=== 和 !== 只能用于引用类型比较       |
|   				      			   | let a: Int = 2; a === 3.14 (不同类型)		  | 编译失败,不支持比较              |编译失败,=== 和 !== 只能用于引用类型比较	       |
| String  == String (!= 行为相同)        | "a" == "a"		 							   | 结果为 true                   |结果为 true                          	  |
| String  === String (!=== 行为相同)  	| "a" === "a" 									| 结果为 true                  |编译失败,不能比较	          			  |
| Array  == Array (!= 行为相同)        | [1] == [1]	 							   | 结果为 false                   |结果为 true,数组类型相同,元素相同就为true     |
| Array  === Array (!=== 行为相同)  	| [1] === [1] 									| 结果为 false                  |编译失败,不能比较	          			  |

W
wanganxp 已提交
284 285 286 287 288 289 290 291 292
`===``!==`,本意是内存地址相同,即不仅值相同,并且是同一份对象。

但不同平台的逻辑略有差异:
- js中可以比较基础类型。swift中不可以比较基础类型,只能比较对象类型
- js中比较相同字面量会返回true,比如1===1。但kotlin由于编译优化,可能会把两个字面量映射为同一内存地址,但也可能没有触发编译优化。如果没有优化为同一内存地址,那么kotlin上1===1就会返回false。而swift不允许比较字面量。

对于运行时表示为原生类型的值(例如 Int),引用相等 (===)等价于相等(==)。
<!-- TODO @yanyilin -->

D
DCloud_LXH 已提交
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
## 展开语法...

> HBuilderX 3.9+

展开语法可以在函数调用/数组构造时,将数组表达式在语法层面展开。展开语法使用 `...` 操作符表示。

### 构造字面量数组

没有展开语法的时候,只能组合使用 push, splice, concat 等方法,来将已有数组元素变成新数组的一部分。有了展开语法,通过字面量方式,构造新数组会变得更简单、更优雅:

```ts
const array1 = ['a', 'b']
const array2 = ['c', ...array1, 'd'] //把array1的内容组合赋值给array2
```

### 在函数调用时使用展开语法

如果想将数组元素迭代为函数[剩余参数](./function.md#剩余参数),也可以使用 `...` 操作符。

```ts
fn('a', ...['b', 'c'])
```

尤其是列表加载场景,从服务器取到一批新数组,就可以使用`...`快捷的追加到之前的data数组中。

假使uvue的data中定义了一个dataList数组,服务器返回了res,res.data是合法的数组,那么就可以把新数组快捷的追加到dataList数组中。

```ts
this.dataList.push(...res.data)
```


### 剩余参数

剩余语法 (Rest syntax) 看起来和展开语法完全相同,不同点在于,剩余参数用于解构数组和对象。

从某种意义上说,剩余语法与展开语法是相反的:展开语法将数组展开为其中的各个元素,而剩余语法则是将多个元素收集起来并“凝聚”为单个元素。请参考:[剩余参数](./function.md#剩余参数)

## 类型断言as@as

类型可能不明确、不唯一时,可以使用类型断言操作符 `as` 来为值指定类型。

常见于 any 类型的明确、字面量的明确,也可以用于可为空 `|null` 类型的明确。

```ts
const a: any = 'a'
a as string // as之后a就可以当做string直接使用了

const a: string | null = 'a'
a as string // 正常
```

当一个字面量可能成为多种类型时,可以通过as来明确具体类型。
```ts
// 数字字面量可以被指定为任何相容的数字类型
1.0 as Double
1.0 as number

// 对象字面量也可以as为USTJSONObject或某个type
{"id":1} as UTSJSONObject

type t = {
	id:number
}
{"id":1} as t
```

只允许将类型as为具体或更不具体的类型,不能强制转换两个不可能兼容的类型:

```ts
const a: string = 'a'

a as any // 正确
a as string // 正确
a as number // 错误
```

USTJSONObject和type不相容,无法互相as。应该在初始的字面量或JSON.parse环节就决定好类型。

类型断言会在运行时进行,如果无法强制转换,类型断言运算符会引发异常:

```ts
const a: string | null = 'a'
a as string // 正常

a = null
a as string // 异常
```

以上代码中当值为 `null` 的时,强制转换为 `string` 会引发异常。为了让这样的代码用于可空值,请在类型断言的右侧使用可空类型:

```ts
a as string  null // 正常
```

当 as 操作符的左侧为[对象字面量](./literal.md#object-literal)时,编译器会进行[特殊处理](./object.md#实例化):自动创建类型对应的实例。

```ts
{ name: 'Tom', printName: function () { } } as Person
```

另外:当 `as` 用在[模块](./module.md)导入时,它和类型断言无关,其功能为[指定别名](./module.md#指定别名)

## typeof实例类型获取@typeof

D
DCloud_LXH 已提交
398
使用 `typeof` 运算符获取一个实例对象的类型,返回表示类型的字符串。
D
DCloud_LXH 已提交
399

D
DCloud_LXH 已提交
400 401 402 403 404 405 406
| 类型                						 			 | 结果             |
| ------------------------------------------------------ | ---------------- |
| null                						 			 | "object"         |
| boolean     		  						 			 | "boolean"        |
| number       		  						 			 | "number"         |
| string       		  						 			 | "string"         |
| function     		  						 			 | "function"       |
杜庆泉's avatar
杜庆泉 已提交
407 408
| 平台专有数字类型: Int, Float, Double, Long ... 		    | "Int","Float","Double","Long" ... |
| 平台专有字符串类型: Char ... 			                    | "Char" ... |
D
DCloud_LXH 已提交
409
| 其他任何对象(包含但不限于:Date, Array, Map, UTSJSONObject) | "object"         |
DCloud-yyl's avatar
DCloud-yyl 已提交
410
| any                                                    | 实际类型 |
D
DCloud_LXH 已提交
411 412 413 414 415 416 417 418 419 420 421 422


为了与web保持一致,typeof除了布尔、数字、字符串、函数外,全部返回object。如需判断object范围内的具体类型,需另见[instanceof](#instanceof)

用法示例:

```ts
let a = 10.0  //自动推断为number类型
let b: Double = 3.14
let c: Int = 2

typeof a == "number" //true
D
DCloud_LXH 已提交
423
typeof b == "Double" //true
D
DCloud_LXH 已提交
424 425 426 427 428 429 430
typeof c == "Int" //true

// string
let str = "hello uts"
typeof str == "string" //true

//boolean
D
DCloud_LXH 已提交
431
let ret = true
D
DCloud_LXH 已提交
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
typeof ret == "boolean" //true

//function
function fn(obj: string) {
  if (obj instanceof String) {
    // ...
  }
}

typeof fn == "function" //true
typeof Math.sign == "function" //true

//object
let obj = {
	"x": 1,
	"y": 2
}

typeof obj == "object" // true

typeof null == "object" //true
typeof [1, 2, 3] == "object" //true

```

D
DCloud_LXH 已提交
457
**注意**
D
DCloud_LXH 已提交
458 459 460 461 462
`typeof` 运算符的参数只能是实例对象,不能是类型,如下操作是错误用法:
```ts
type MyType = {
    name:string
}
D
DCloud_LXH 已提交
463
typeof MyType   //报错
D
DCloud_LXH 已提交
464 465 466 467 468 469 470 471 472 473 474
```

`typeof` 运算返回值一定是字符串,不会返回 TypeScript 类型,这与TypeScript存在差异:
```ts
type MyType = {
    name:string
}
let my:MyType = {name:"abc"}
type NewType = typeof my;   //报错
```

D
DCloud_LXH 已提交
475
**特殊情况**
D
DCloud_LXH 已提交
476
在Android平台,将 number 类型赋值给 any 类型变量时,会根据数值将类型转变为实际平台专有数字类型,使用 typeof 获取此 any 类型变量将会返回实际平台专有数字类型。
DCloud-yyl's avatar
DCloud-yyl 已提交
477
同样,将 number 类型保存在 UTSJSONObject 中,通过下标 `[""]` 获取对应的属性值类型为 any,使用 typeof 获取此属性值类型也将返回实际平台专有数字类型。
D
DCloud_LXH 已提交
478 479 480 481 482 483 484 485

```ts
let a = 10.0    //自动推断为number类型
let b: Double = 3.14
let c: any = a
let d: any = b

typeof a == "number" //true
D
DCloud_LXH 已提交
486
typeof b == "Double" //true
D
DCloud_LXH 已提交
487 488 489 490 491
typeof d == "Double" //true

// 在 iOS 平台上
typeof c == "number" //true

D
DCloud_LXH 已提交
492
// 在Android平台上变量c会根据数据实际数值转换为平台专有数字类型Double
D
DCloud_LXH 已提交
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
typeof c == "number" //false 真实返回的是 "Double"

```

在Android平台,如果类型(或class)存在伴生对象(companion object)时,可以使用`typeof`运算符,返回的值为object,但不推荐这么使用

```ts
typeof Double   //在Android平台Double有伴生对象可以正常运行,实际值为object;在iOS平台报错
```


## instanceof实例类型判断@instanceof

使用 `instanceof` 运算符执行运行时检查,以标识对象是否符合给定类型。

D
DCloud_LXH 已提交
508 509 510 511 512
| 类型                						 			 								| 结果             |
| ------------------------------------------------------------------------------------ 	| ---------------- |
| Boolean                						 		 								| 编译报错,不支持    |
| Number     		  						 			 								| 编译报错,不支持    |
| String       		  						 			 								| 编译报错,不支持    |
D
DCloud_LXH 已提交
513
| 平台专有数字类型: Int, Float, Double, Long ... 			 								| true or false    |
D
DCloud_LXH 已提交
514
| typeof 结果为 "object" 的类型(包含但不限于:Date, Array, Map, UTSJSONObject, 自定义类型)	| true or false    |
D
DCloud_LXH 已提交
515

D
DCloud_LXH 已提交
516
> 特别说明:
D
DCloud_LXH 已提交
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
> HBuilderX3.9.0 使用 `instaceof` 对 Boolean, Number, String 类型的实例进行判断会编译报错,请使用 `typeof` 。在HBuilderX3.9.0之前版本可正常使用 `instaceof` 对上述类型的判断。


```ts
function fn(obj: any) {
  if (obj instanceof Date) {
    // ...
  }
}
```

包含[泛型](./generics.md)的类型,不能缺省泛型信息。如不需要判断具体的泛型类型,可以使用 `unknown` 表示任意泛型类型:

```ts
function fn(obj: any) {
  if (obj instanceof Map<unknown, unknown>) {
    // ...
  }
}
```

已经可以明确判断类型兼容性时无需使用 `instanceof` 在运行时进行判断,编译阶段会检查出这种情况会报错或者警告:

```ts
function fn(obj: Date) {
  if (obj instanceof Date) {
    // ...
  }
}
```

对于数字类型,`instanceof` 细化了判断逻辑,除了能判断是否是 number, 还能判断是否是 Int Float Double Int64 Long ... 等所有平台专有数字类型。

```ts

let a: Double = 3.14
let b: Int = 2

a instanceof Double //true
D
DCloud_LXH 已提交
556
b instanceof Int //true
D
DCloud_LXH 已提交
557 558 559 560 561 562 563

```

## await
> 3.93+ (Android)
await 操作符用于等待一个 [Promise](./buildin-object-api/promise.md) 兑现并获取它兑现之后的值。它只能在[异步函数](./function.md#async)中使用。

W
wanganxp 已提交
564
在 HBuilderX 3.93 以下的版本或者编译为swift时,await 不能与 [Promise](./buildin-object-api/promise.md) 一同使用,此时请分别参考:[安卓 异步函数](https://uniapp.dcloud.net.cn/plugin/uts-for-android.html#_6-11-synchronized-lock-等线程同步概念-在uts里怎么写)[iOS 异步函数](https://uniapp.dcloud.net.cn/plugin/uts-for-ios.html#_5-1-13-异步方法)
D
DCloud_LXH 已提交
565 566 567 568 569 570

```ts
async function test(): Promise<string> {
  return await Promise.resolve('hello world');
}
```