乍一看,Observable 看上去好像就是普通的 JavaScript 。这是刻意的:通过构造 web 的本地语言,Observable 更熟悉并且你可以使用你知道和喜欢的库,例如 D3 ,Three 和 TensorFlow 。然而对于 dataflow,Observable 需要在几个方面改变 JavaScript 。
这里有一个不同之处的快速概述。
(我们还共享了我们的 grammarparser。)

Cells are separate scripts.

单元格是单独的脚本

notebook 中的每个单元都是独立运行的独立脚本。一个单元的语法错误不会妨碍其他单元格的运行。
运行错误时也是如此
同样的,局部变量只对定义它们的单元格可见。

Cells run in topological order.

单元格按拓扑顺序运行

在普通的 JavaScript 中,代码从上到下运行。不是这里,Observable 运行时像一个电子表格,所以你可以以任何有意义的顺序定义你的单元格。
通过拓展,循环定义是不允许的。

Cells re-run when any referenced cell changes.

当任何引用的单元格发生改变时,单元格会重新运行

当你编辑或互动时,你不需要显示运行单元格——notebook 将自动更新。通过点击下方 play 按钮来运行单元格,或者同时按下 Shift-Enter 。只有引用单元格运行,然后它们的引用单元格运行,其他单元格不受影响。
如果计算单元分配了垃圾收集器不会自动清理的资源,例如动画循环或事件侦听器,则使用无效承诺手动处理这些资源并避免泄露。

Cells implicitly await promises.

单元格暗中等待承诺

你可以定义一个承诺值的单元格。
如果你引用一个这样的单元格,你不用 await ;直到值解析之前,引用单元格不会运行。

Cells implicitly iterate over generators.

单元格暗中遍历生成器

如果一个单元格产生,任何引用单元格可以看到最近产生的值。
同样,每个动画帧产生出现次数不会超过一次:通常每秒60次,使得生成器便于动画制作。如果生成了一个 DOM 元素,会在生成器恢复前被加到 DOM 中。

Named cells are declarations,not assignments.

命名单元格是声明,不是赋值

命名单元格和普通 JavaScript 中赋值表达式外观和功能看起来都很像。但是单元格可以以任何顺序定义,所以把它们看成升起的函数声明。
你不能分配另一个单元格的值(尽管下边它们看起来是可变的)。
单元格名字也必须是唯一的。如果有两个或更多单元格名字相同,那它们都会出错。
( Observable 还不支持通过解构赋值来声明多个名字,但是我们希望尽快添加。)

Statements need curly braces,and returm(or yield).

语句需要花括号,然后返回(或生产)

一个单元格正文可以是一个简单的表达式,例如数字或字符串文字,或是函数调用。但是有时你想要声明,例如 for 循环。你需要花括号和返回声明给单元格赋值。认为这个单元格是一个函数,这个函数除了没有参数。
同样的道理,你需要圆括号把对象包起来,或使用带返回的块语句。

Cells can be views.

单元格可以是视图

Observable 有一个特殊的 viewof operator 它允许定义交互式的值。一个视图是有两面的单元格:用户页面以及编程价值。尝试编辑下方输入框,请注意,引用的单元格是自动运行的。

Cells can be mutables.

单元格是可变的

Observable 有一个特殊的 mutable operator,所以你可以选择进入可变状态:你可以从其他单元格设置可变值。
可变值可以被动地引用或不主动引用,这取决于您是否希望在可修改的值发生更改时自动运行单元格。

Observable has a standard library.

Observable 有一个标准库

Observable 为基本特性提供了一个小的标准库,例如 Markdown 标记的模板文本和响应宽度。

Cells can be imported from other notebooks.

单元格可以从其他 notebook 输入

你可以从任何 notebook 导入任何命名单元格,其语法类似静态 ES 导入。但是 Observable 导入是惰性的:如果你不使用它,它不会运行。
此外,你还可以 import-with,它允许你将当前 notebook 的单元注入到导入的 notebook 中,覆盖原始定义。你可以将任何 notebook 视为可扩展的模板!

Static ES imports are not supported;use dynamic imports.

不支持静态 ES 导入;使用动态接口

由于 Observable 中的所有东西本质都是动态的,所以实际上并不需要静态的 ES 导入——不过,我们将来可能会添加支持。注意,只有最新的浏览器支持动态导入,所以现在可以考虑使用 require 。

require is AMD,not CommonJS.

require 是 AMD,不是 CommonJS

Observable’s require 看起来像 CommonJS 因为单元格暗中等待承诺。但在底层它使用 Asynchronous Module Definition(AMD)
这个约定终究会被现代 ES 和导入所取代。但是它目前仍然有用,为许多库的作者还没有发布 ES 模块。