从有前端到如今,JavaScript 语言一直都是实现前端逻辑的首选。可是,因为 JavaScript 是一个弱类型语言,很难进行相关的类型检测。所以在构建大型应用时,使用 JavaScript 不免会遇到一些隐式类型转换等相关的问题,从而致使程序的 bug。javascript
在当前的选择中,有两个流派,都可以解决 JavaScript 弱类型语言带来的弊病,给前端带来强类型语言的支持。前端
做为最近被你们关注的愈来愈多的强类型语言,ReasonML 的发展也是须要咱们持续关注的。java
说了这么多背景,咱们来正式介绍下 ReasonML 这门语言。首先,让咱们来看下[官网][1]对于 ReasonML 的介绍。git
Reason lets you write simple, fast and quality type safe code while leveraging both the JavaScript & OCaml ecosystems. Reason利用 JavaScript 和 OCaml 语言的生态,让你编写简单、快速和高质量类型安全的代码。github
从这个介绍中咱们能够知道, ReasonML 是从 OCaml 语言衍生出来的,能够支持 JavaScript 的新的强类型语言。首页介绍中,还提到了这个语言的三个特色:npm
听了这么多关于 ReasonML 的介绍,咱们来简单的看下相关的语法。经过相关的语法和示例,咱们可以帮助咱们更好的理解这门语言。json
咱们就使用官方的一些简单的示例来快速入门这个语言。数组
由于目前浏览器没法直接识别强类型语言,所以咱们须要经过编译器,将强类型语言编译成 JavaScript 之后才可以在前端浏览器或者 Node.js 中运行。浏览器
首先,咱们来看下如何进行安装:安全
npm install -g bs-platform
复制代码
首先,咱们经过 NPM 来对编译平台 bs-platform
进行全局安装,安装完成后,咱们就可使用这个 cli 自带的命令了。
安装完成后,咱们须要初始化一个项目,所以咱们须要执行如下命令:
bsb -init my-new-project -theme basic-reason
复制代码
经过这个命令,咱们就建立了一个名字为 my-new-project
的项目文件了。
这个时候,咱们进入这个项目文件夹中,看看这里面到底初始化了哪些东西。首先咱们来看下 package.json
文件。
{
"name": "my-new-project",
"version": "0.1.0",
"scripts": {
"build": "bsb -make-world",
"start": "bsb -make-world -w",
"clean": "bsb -clean-world"
},
"keywords": [
"BuckleScript"
],
"author": "",
"license": "MIT",
"devDependencies": {
"bs-platform": "^4.0.18"
}
}
复制代码
接下来,咱们先来看下 src/Demo.re
文件的内容。
Js.log("Hello, BuckleScript and Reason!");
复制代码
咱们须要重点关注的就是,咱们能够经过 npm run build
命令来编译整个项目,它会将 src/Demo.re
编译成 src/Demo.re.js
文件。让咱们来看下编译出来的内容是什么样子的。
// Generated by BUCKLESCRIPT VERSION 4.0.18, PLEASE EDIT WITH CARE
'use strict';
console.log("Hello, BuckleScript and Reason!");
/* Not a pure module */
复制代码
你们能够看到,咱们经过 ReasonML 的编译器,将 ReasonML 的代码编译成了 JavaScript。
说完了构建编译相关的流程,咱们来正式看下 ReasonML 这门语言的语法。
ReasonML 的类型系统能够自动进行类型推断,在本文介绍中我会尽量详细的进行介绍,可是若是没有声明具体类型,你们能够自主进行推断。
咱们能够经过下面这个表格来快速看下当前的数据结构:
数据类型 | 示例 |
---|---|
字符串 | "Hello" |
字符 | 'x' |
整型数字 | 23 , -23 |
浮点型数字 | 23.0 , -23.0 |
整型数字加法 | 23 + 1 |
浮点型数字加法 | 23.0 +. 1.0 |
整型数字除法/乘法 | 2 / 23 * 1 |
浮点型数字除法/乘法 | 2.0 /. 23.0 *. 1.0 |
浮点型数字求幂 | 2.0 ** 2.0 |
字符串组合 | "Hello " ++ "World" |
比较运算符 | > , < , >= , =< |
布尔运算符 | ! , && , || |
引用(浅)比较,结构(深)比较 | === , == |
不可变列表 | [1, 2, 3] |
不可变前置声明(Immutable Prepend) | [item1, item2, ...theRest] |
元组(Tuple) | [1, "string"] |
数组 | [|1, 2, 3|] |
记录(Records) | type player = {score: int}; {score: 100} |
对象 | type tesla = {var red = "red"; pub color = red;}; tesla#color |
注释 | /* Comment here */ |
这里面有一些内容须要详细介绍下差异。
字符与字符串。在 ReasonML 中,字符与字符串分别是用单引号和双引号来进行表示,而不是统一认为是字符串,单双引号通用。
浅比较和深比较。在 JavaScript 中,==
和 ===
对于对象和数组之类的变量来讲,都是进行地址的比较。而在 ReasonML 中,咱们能够在运算符中实现深比较。
不可变列表与数组。在 JavaScript 中,数组能够存储任意类型的内容。而在 ReasonML 中,出现了一个不可变列表,只能存储同一种数据类型(好比所有都是整型数字),而且是不可变数据类型。ReasonML 的数组是一个可变数据类型,可是仍然只能存储同一种数据类型。若是须要实现存储不一样的数据类型,则须要使用元组(Tuple)——一个不可变的有序类型,具体代码以下:
let ageAndName = (24, "Lil' Reason");
复制代码
对象与记录。在 ReasonML 中,出现了对象和记录两种类似的数据类型,咱们来看下二者的区别。记录是一个须要提早声明的默认不可变的数据结构,在 ReasonML 中推荐使用。而在 ReasonML 的对象,则是一个不须要提早声明的数据结构。不过在 ReasonML 中,推荐优先使用记录。
关于语法相关的内容,我只是简单介绍了一下核心的数据结构,有不少内容没有介绍到,若是你们想要系统的学习 ReasonML 的话,能够看一下官方文档。
若是咱们须要在 ReasonML 中使用 JavaScript 代码,咱们能够按照以下的方法:
[%bs.raw {| console.log('here is some javascript for you') |}];
复制代码
上面的代码通过编译后,能够获得以下的 JavaScript 代码。
'use strict';
console.log('here is some javascript for you');
复制代码
这个方法与全局注入变量的方式相似,会直接将上述代码替换成编译后的 JavaScript 代码。所以咱们能够这么用:
let x = [%bs.raw {| 'here is a string from javascript' |}];
复制代码
获得的代码为:
var x = ( 'here is a string from javascript' );
复制代码
许多的语法差别咱们在上述语法介绍中都已经介绍过了,若是须要详细的比对,能够看官方文档中的语法比较。
ReasonML 是一门比 TypeScript 约束严格的多的强类型语言(TypeScript 编译报错能够选择忽略掉,不影响使用)。强类型语言对于大型的项目开发来讲,确实能够带来明显的优点。可是,咱们能不可以大规模使用 ReasonML 呢?
先说下我的的基本判断:持续关注,不建议在大型应用场景中使用。
从 ReasonML 目前的状况来看,它与 TypeScript 很是类似。
TypeScript 因为对 JavaScript 的生态彻底兼容,因此即便咱们须要进行部分代码的重写,咱们仍然能够快速的复用 JavaScript 的强大生态。
而因为 ReasonML 来讲,这个方面就会明显相差很多。与此同时,ReasonML 的相关语法与 JavaScript 相差较大,所以对于前端工程师的学习成原本说,也有必定的提提高。
综上所述,若是你们须要在前端使用强类型语言来构建大型项目,建议选择 TypeScript 语言。
若是在迁移 TypeScript 中有什么问题,能够看下我以前写的一篇文章——旧项目 TypeScript 改造问题与解决方案记。
黄珏,2015年毕业于华中科技大学,目前任职于美团基础研发平台大象业务部,独立负责大象 Web SDK 的开发与维护。
本文未经做者容许,禁止转载。