致读者
本文是“一个 JSer 的 Dart 学习日志”系列的第五篇,本系列文章次要以开掘 JS 与 Dart 异同点的形式,在温习和坚固 JS 的同时安稳地过渡到 Dart 语言。
如无非凡阐明,本文中 JS 蕴含了自 ES5 至 ES2021 的全副个性,Dart 版本则为 2.0 以上版本。
鉴于作者尚属 Dart 初学者,所以意识可能会比拟浮浅和全面,对常识的概括不免有所疏漏,如您慧眼识虫,望不吝指正。本系列文章首发于思否平台,勘误及新增内容也仅限于思否,如您是在别的中央看到本文,请移步思否免得看到未订正的内容。
对于
ES5 的五种根本类型(
Number
、String
、Null
、Undefined
、Boolean
)是陈词滥调的面试题,ES2015 带来的Symbol
和 ES2019 新增的BigInt
丰盛了 JS 可用的根本类型。
在数据结构方面,JSer 们一开始只能基于内建的Object
和Array
组织数据,其间经常伴着一些不成文的束缚,直到 ES6 带来了Map
和Set
。而在内建数据类型方面,Dart 的终点显著要比 JS 高。JS 作为一门解释性的语言,其语言规范对运行的宿主有所束缚(尽管厂商未必遵循此规范),所以在 JS 的规范中能够明确内存的应用形式,例如除了变量的援用之外,某些数据也寄存在栈内存中,这些数据即所谓“根本类型”数据。
而 Dart 往往须要编译到其余语言,通过规范明确地束缚宿主的行为只会徒增工作量,这兴许就是 Dart 没有明确规定“根本类型”的起因。但这并不障碍咱们用 Dart 中那些性能相仿的类型与 JS 的根本类型作比。
一、Number
共同点
- 应用十进制数字字面量申明;
- 应用十六进制的字面量申明;
-
应用迷信计数法申明:
/****** Both JS and Dart ******/ var dec = 42; var hex = 0X2A; var sic = 4e2;
不同点
1. Dart 没有二进制字面量
- JS 中应用
0b
结尾的语法申明二进制字面量(b
也可大写); -
Dart 不反对二进制字面量:
> /* JS */ | // Dart > var bin = 0b101010; | // var bin = 0b101010; > | // 去掉下面的正文,将无奈通过编译
2. int
和 double
- JS 的
Number
类型均以双精度浮点类型存储和计算; -
Dart 的
Number
分为整形int
和双精度浮点类型double
,以应答不同的示意和运算需要:> /* JS */ | // Dart > var i = 1; | var i = 1; > var d = 1.1; | var d = 1.1; > console.log(typeof i); | print(i.runtimeType); > console.log(typeof d); | print(d.runtimeType); > // number | // int > // number | // double
不过,应用 Dartpad 实测得悉:
如果小数点后只有0
的话,d.runtimeType
为int
;
但如果将d
申明为num
或int
,并作为double
类型的函数参数,将无奈通过编译。
是否阐明 Dart 设计者其类型推断性能过于自信?
另外在 Dart 中:
如果两个数字相减为 0,那么应用==
判断相等的时候,返回的是true
;double
与int
相加,后果的类型为double
。
3. 从其余类型创立数字
- 在 JS 中应用
Number
构造函数能够创立数字(但不能应用new
关键字),如果参数是一个其余类型的表达式的话,会将此表达式转为数字类型; -
在 Dart 中仅可应用
num.parse
/num.tryParse
将字符串转为数字,:var a = Number('2'); | var a = num.parse('2');
parse
遇到无奈转为数字的字符串会抛错;tryParse
遇到无奈转为数字的字符串则返回null
;
二者都会进行严格的参数类型匹配。
4. 非凡的数值
- 对应 JS 中的
NaN
,然而没有NaN
字面量; - Dart 中的
double.maxFinite
对应 JS 中的Number.MAX_VALUE
(然而具体值要看宿主环境); - Dart 中的
double.minPositive
对应 JS 中的Number.MIN_VALUE
; - Dart 中的
double.infinity
对应于 JS 中的Number.POSITIVE_INFINITY
; - Dart 中的
double.negativeInfinity
对应于 JS 中的Number.NEGATIVE_INFINITY
。
不晓得算共同点还是不同点。
Dart 中的int
类型更像 JS 中的BigInt
,下面这几个值,它们——都!没!有!
二、Boolean
VS 布尔类型
共同点
- 应用字面量申明。
不同点
1. 没有隐式类型转换和万能的构造函数
- JS 中能够在本该应用
Boolean
类型的中央应用值为任何类型的表达式,这些表达式的值在运算时会被转换为一个布尔值,此过程波及一个非常复杂的真值表,其成果等同于调用Boolean(exp)
; - Dart 中应用
bool
类型的中央必须应用该类型,并且bool
不是一个可执行的函数或构造函数,也没有转换其余类型值的办法。
因而在任何中央判断虚实的时候肯定要显式地将表达式转为布尔类型。
三、String
VS Strings
共同点
- 可应用单双引号(即
"
或'
)申明字符串字面量; - 应用反斜杠(
\
)本义特殊字符; -
应用加号(
+
)拼接字符串:/****** Both JS and Dart ******/ var stringA = 'This is a string'; var stringB = 'This\'s a string'; var stringC = stringA + stringB;
不同之处
1. 多行字符串
- ES5 是没有多行字符串字面量的,应用
\n
示意换行符,ES6 新增了反引号(`
)语法,能够间接回车输出换行; -
Dart 应用三引号(
'''
或"""
)语法示意多行字符串:> /* JS */ | // Dart > const a = | const a = > `Line 1st | '''Line 1st; > Line 2nd`; | Line 2nd'''; > console.log(a); | print(a); > // Line 1st \nLine 2nd | // Line 1st \nLine 2nd
2. 字符串模板
- ES5 同样没有字符串模板性能,开发者通常应用字符串拼接或片段替换来向字符串嵌入表达式,而 ES6 新增的反引号语法中能够应用
${exp}
向字符串中来达到同样的成果; -
Dart 中所有字符串均可应用
${exp}
或$varName
将表达式 / 变量的值嵌入字符串中:> /* JS */ | // Dart > const val = 'expression'; | const val = 'expression'; > var oldVer = 'This is' + val; | const oldVer = "This is $val"; > const newVer = `This is ${val}`; | const newVer = 'This is ${val}'; > console.log(oldVer === newVer); | print(oldVer == newVer); > // true | // true
3. 没有隐式转换和构造函数
- 在 JS 中,咱们能够应用字符串连贯任何表达式失去一个新的字符串,该表达式的
.toString
办法会被默认执行,另外也能够应用String(exp)
将表达式转为字符串; - 在 Dart 中字符串不能与其余类型的表达式进行连贯,
Strings
也不是可调用的函数或构造函数。
借助操作符重载性能,咱们应该能够在 Dart 中实现隐式类型转换,惟一的问题就是:咱们有这个必要吗?
4. raw
字符串
- JS 没有
raw
字符串,也没有相似的概念; -
Dart 中,在引号前加一个
r
,示意此字符串中的斜杠不是本义符:// Dart only const raw = r'In a raw string, not even \n gets special treatment.';
这里的
\n
不会被视作换行符。
当然,作为 UI 编程中最为常见的根本类型,字符串有着很多便当的办法和丰盛的用法,预计列举这些异同点会占用较大篇幅,此处按下不表。
四、Symbol
共同点
-
应用
Symbol(String t)
创立一个Symbol
:/****** Both JS and Dart ******/ const symbol = Symbol('symbol');
不同点
1. 不同 Symbol 实例的相等性
- JS 中的不同 Symbol 是不相等的,即使创立时传入的字符串统一;
-
Dart 中向
Symbol
传入的字符串统一,则所得实例相等:> /* JS */ | // Dart > const a = Symbol('symbol'); | const a = Symbol('symbol'); > const b = Symbol('symbol'); | const b = Symbol('symbol'); > console.log(a == b); | console.log(a == b); > // false | // true
2. #
号语法
-
在 Dart 中能够应用
#
快捷地申明一个常量Symbol
:#symbol; print('This is ${#symbol}'); // This is Symbol("symbol")
留神
- 应用的时候也要带上
#
号; - 申明的
Symbol
明确是编译时常量,因而不能再应用var
、const
、late
等关键字,也不能应用Symbol
申明其类型。
- 应用的时候也要带上
五、Null
VS Null
&& Undefined
- JS 中有两种空值:
undefined
和null
,类型别离为undefined
和Null
,前者常作为未赋值变量的默认值,而后者往往作为一些接口无目标值时的返回值; -
Dart 中只有
null
空值,作为未赋值变量的默认值,在空平安 (sound null safety
) 模式下须应用Type?
语法能力赋值:String? someString = null; // 空平安模式下,须要应用 `?`,能力为变量申明初值