当前位置:首页 > 网站用户体验专题

高效执行的 javascript 而不是字节码和机器码

2019-06-07

大家都知道 react 是 facebook 的产品,而 angular 是 google 产品,angular 是用 typescript 来编写,通过 typescript 这个 javascript 超级是 angular 可以轻松地胜任开发大型应用。


而且形成自己生态,自己语言自己框架。所以 facebook 可能也不甘示弱,准备用一门其他语言类型的语言来高效写出稳定可靠的 javascript 语言。最终选择了这个有了 20 多年历史的语言 ocaml, 估计很多人连听都过这门语言。


这是一门函数式编程的语言。但是 ocaml 是无法运行在浏览器上的,而且需要对前端那些熟悉 javascript 的程序员友好。为了解决这些问题,出现了 Reason ,reason 是 OCaml 的语言接口,对于有 javascript 开发经验的开发者友好。有了 reason 那么如何将 reason 编译为 javascript 呢?答案是 BuckleScript ,BS (BuckleScript )是将 ocamel/reason 编译为 javascript 的编译器。


这不是一个简单的编译转换工具,BS 不但可以将 Ocaml

 代码编译为 javascript 而且是可以编译为高效的 javascript,而且易于阅读。编译后的代码你是看不这是机器写的,而且 BS 也是中国人写的,是我们的骄傲。




这么三个相对独立的语言和工具,他们之间的关系又是怎么建立起来的呢?
我们通过分析 Ocaml 编译器来看一看是如何将他们整合到一起的。


我们从 Ocaml 编译过程作为切入点进行分析,将三者联系起来。


source code :在这个阶段编译器获取 OCaml 的代码

unTyped AST :进行代码进行解析和预处理,后生产一个棵没有类型的 AST 。

Typed AST :然后对类型进行推测和检验生产有类型的 AST。

Lambda IR :这应该是 Ocaml 重点,但是应该不是我们今天重点,不过可以了解一下

将定义类型的 AST 转为为无类型的 IR ,转换格式依据 s-express

这句话中出现了两个难懂的词 IR 和 s-express

s-express 知乎一下没有,wiki 中找到了,我们尝试理解一下。

百度一下,百度翻译的还不错。在此基础解释一下。

**s-expression**应该是一种表示数据结构的表达方式例如(*2(+3 4)),就是将刚刚生产树形结构数据表达成这样。是嵌套列表(树形结构)数据的一种表示法,由编程语言lisp发明并推广,它将它们用于源代码和数据。

Bytecode :最后经过进行推理将 IR 编译成字节码或机器码

了解 ocaml 的整个编译过程,那么我们的 reason 和 bs 出现在哪个阶段呢?



Reason 出现在 unTyped AST 这个编译阶段,通过一些预处理让我们源码可以解析成 AST 支持一些新语法的特性


BuckleScript 将使用无类型的 IR 进行编译为可以高效执行的 javascript 而不是字节码和机器码

BuckleScript 的神奇之处编译的 javascript 可能比你这的还好。计算机更喜欢函数式编程。让我们拥抱机器,学一点稍微难于理解但是高效的函数式编程吧。


React 已经采用 reason 来写组件,下面列出其好处。

- 更安全,更简洁的方式去构建 React 组件

- 完全兼容 JSX

- 类型安全兼容 javascript 编写的组件

- 用于一种全新的表述型 API 来描述状态管理


昨天我们通过一个示例,做了一个简单的 Demo。也知道我们可以用 reason 来写 react 组件,reason 提供两种模板让我们来创建组件。

无类型的组件statelessComponent


let component = ReasonReact.statelessComponent("SimpleComponent");let make = _children => { ...component, render: _self =>
(ReasonReact.string("Reason Projects"))
,
};

然后我们创建一个 TutData.re 文件,其中定义一个 tut 类型,定义数据的结构。


type tut = { title:string, body:string}

我们创建一个 statessComponent 组件。


let component = ReasonReact.statelessComponent("SimpleComponent");let make = _children => { ...component, render: _self => {  

(ReasonReact.string("Reason Projects"))

; },};

我们在定义一个组件 TutItem,~tut 表示给这个参数打一个标签,虽然我们可调整参数的位置,然后通过标签对参数进行传值。


let component = ReasonReact.statelessComponent("TutItem");let make =(~tut: TutData.tut, _children) => { ...component, render: _self => { //创建数据  
(ReasonReact.string(tut.title))
; },};

创建 tut 类型的 dummyTut 的数据,然后将 dummyTut 通过 prop 传入组件。


let component = ReasonReact.statelessComponent("SimpleComponent");let make = _children => { ...component, render: _self => { //创建数据 let dummyTut:TutData.tut = { title:"angular tut", body:"angular tut body" }; <div>  <h1>(ReasonReact.string("Reason Projects")) h1> <TutItem tut=dummyTut/> div>; },};


免费获取报价

  • 29923329

  • 杭州市丰庆路498号北软智慧科创大厦203

  • 0571-85815193

  • pady@1t2.cn

网站地图 版权所有 © 2008-2021 杭州派迪科技有限公司  Copyright © 2008-2020  www.hzpady.com  All Rights Reserved    浙ICP备14029905号-1     公安备案:33010802008411    软著登字第3457658号