语言特性概览
与 JS 比较
分号
| JavaScript | ReScript |
|---|---|
| 被 linter/formatter 强制要求 | 不需要分号! |
注释
| JavaScript | ReScript |
|---|---|
// 行注释 | 相同 |
/* 块注释 */ | 相同 |
/** 文档注释 */ | /** 类型/值之前的注释 */ |
/*** 独立的文档注释 */ |
变量
| JavaScript | ReScript |
|---|---|
const x = 5; | let x = 5 |
var x = y; | 无对应(谢天谢地) |
let x = 5; x = x + 1; | let x = ref(5); x := x.contents + 1 |
字符串和字符
| JavaScript | ReScript |
|---|---|
"Hello world!" | 相同 |
'Hello world!' | 字符串必须使用 " |
"hello " + "world" | "hello " ++ "world" |
`hello ${message}` | 相同 |
布尔值
| JavaScript | ReScript |
|---|---|
true, false | 相同 |
!true | 相同 |
||, &&, <=, >=, <, > | 相同 |
a === b, a !== b | 相同 |
| 没有深比较(递归比较) | a == b, a != b |
a == b | 相等判断没有隐式转换(谢天谢地) |
数字
| JavaScript | ReScript |
|---|---|
3 | 相同 * |
3.1415 | 相同 |
3 + 4 | 相同 |
3.0 + 4.5 | 3.0 +. 4.5 |
5 % 3 | mod(5, 3) |
* JS 没有区分整数和浮点数。
对象/记录(Record)
| JavaScript | ReScript |
|---|---|
| 没有类型 | type point = {x: int, mutable y: int} |
{x: 30, y: 20} | 相同 |
point.x | 相同 |
point.y = 30; | 相同 |
{...point, x: 30} | 相同 |
数组
| JavaScript | ReScript |
|---|---|
[1, 2, 3] | 相同 |
myArray[1] = 10 | 相同 |
[1, "Bob", true] | (1, "Bob", true) * |
* JS 中的异构(heterogenous)数组对我们来说是不允许的,使用元组(tuple)代替。
空值
| JavaScript | ReScript |
|---|---|
null, undefined | None * |
* 同样,这里只是精神上的等价物;我们没有 null,也没有 null bug!但我们确实有一个 option 类型,当你真正需要 null 时可以使用这个类型。
函数
| JavaScript | ReScript |
|---|---|
arg => retVal | 相同 |
function named(arg) {...} | let named = (arg) => {...} |
const f = function(arg) {...} | let f = (arg) => {...} |
add(4, add(5, 6)) | 相同 |
代码块
| JavaScript | ReScript |
|---|---|
|
|
条件表达式
| JavaScript | ReScript |
|---|---|
if (a) {b} else {c} | if a {b} else {c} * |
a ? b : c | 相同 |
switch | 拥有强大模式匹配功能!的 switch |
* 我们的条件式总是表达式!你可以这样写:let result = if a {"hello"} else {"bye"}
解构
| JavaScript | ReScript |
|---|---|
const {a, b} = data | let {a, b} = data |
const [a, b] = data | let [a, b] = data * |
const {a: aa, b: bb} = data | let {a: aa, b: bb} = data |
* 给出良好的编译器警告,数据长度可能不为 2。
循环
| JavaScript | ReScript |
|---|---|
for (let i = 0; i <= 10; i++) {...} | for i in 0 to 10 {...} |
for (let i = 10; i >= 0; i--) {...} | for i in 10 downto 0 {...} |
while (true) {...} | while true {...} |
JSX
| JavaScript | ReScript |
|---|---|
<Comp message="hi" onClick={handler} /> | 相同 |
<Comp message={message} /> | <Comp message /> * |
<input checked /> | <input checked=true /> |
| 没有子节点展开 | <Comp>...children</Comp> |
* 参数双关(punning)!
异常
| JavaScript | ReScript |
|---|---|
throw new SomeError(...) | raise(SomeError(...)) |
try {a} catch (Err) {...} finally {...} | try a catch { | Err => ...} * |
* 没有 finally。
代码块
由 {} 限定的块的隐式返回最后一个表达式(函数体也是这样)。在 JavaScript 中,这只能通过一个立即调用函数表达式(IIFE, Immediately Invoked Funtion Expression)来模拟(利用函数作用域)。
| JavaScript | ReScript |
|---|---|
|
|
普通特性的 JS 输出
| 特性 | 例子 | JavaScript 输出 |
|---|---|---|
| 字符串 | "Hello" | "Hello" |
| 字符串插值 | `Hello ${message}` | "Hello " + message |
| 字符(不推荐) | 'x' | 120 (字符码) |
| 整数 | 23, -23 | 23, -23 |
| 浮点数 | 23.0, -23.0 | 23.0, -23.0 |
| 整数加法 | 23 + 1 | 23 + 1 |
| 浮点加法 | 23.0 +. 1.0 | 23.0 + 1.0 |
| 整数除法/乘法 | 2 / 23 * 1 | 2 / 23 * 1 |
| 浮点除法/乘法 | 2.0 /. 23.0 *. 1.0 | 2.0 / 23.0 * 1.0 |
| 浮点幂运算 | 2.0 ** 3.0 | Math.pow(2.0, 3.0) |
| 字符串拼接 | "Hello " ++ "World" | "Hello " + "World" |
| 比较 | >, <, >=, <= | >, <, >=, <= |
| 布尔运算 | !, &&, || | !, &&, || |
| 浅等价和深等价 | ===, == | ===, == |
| 列表(不推荐) | list{1, 2, 3} | {hd: 1, tl: {hd: 2, tl: {hd: 3, tl: 0}}} |
| 列表头部拼接 | list{a1, a2, ...oldList} | {hd: a1, tl: {hd: a2, tl: theRest}} |
| 数组 | [1, 2, 3] | [1, 2, 3] |
| 记录 | type t = {b: int}; let a = {b: 10} | var a = {b: 10} |
| 多行注释 | /* Comment here */ | 无输出 |
| 单行注释 | // Comment here | 无输出 |
请注意,这是一个整理过的对照表;有几个例子的 JavaScript 输出与实际略有不同。