# 简介

AssemblyScript 编译 TypeScript (在新窗口中打开)(JavaScript 的类型化超集)的 **变体** 到 WebAssembly (在新窗口中打开),使用 Binaryen (在新窗口中打开),看起来像

export function fib(n: i32): i32 {
  var a = 0, b = 1
  if (n > 0) {
    while (--n) {
      let t = a + b
      a = b
      b = t
    }
    return b
  }
  return a
}
asc fib.ts --outFile fib.wasm --optimize

它类似于 TypeScript,但具有 **WebAssembly 类型**,由于编译 **严格类型化** 的代码 **提前**,所以有一些限制,但也有一些源于 WebAssembly 功能集的附加功能。虽然不能支持所有 TypeScript,但它与 JavaScript 的紧密关系使其成为已经习惯编写 Web 代码的开发者的熟悉选择,并且也有可能与现有的 Web 平台概念无缝集成,以生成精简高效的 WebAssembly 模块。

# 从 WebAssembly 的角度看

AssemblyScript 将 WebAssembly 和编译器基础作为 内置函数 提供,使其适合作为原始 WebAssembly 之上的薄层。例如,可以使用直接编译为 WebAssembly 指令的内置函数访问内存

store<i32>(ptr, load<i32>(ptr) + load<i32>(ptr, 4), 8)

为了比较,以下 C 代码大致等效

*(ptr + 2) = *ptr + *(ptr + 1)

大多数 WebAssembly 指令也可以直接在 AssemblyScript 代码中编写,并且也提供通用变体

i32.ctz(...)             // ctz<i32>(...)
f64.reinterpret_i64(...) // reinterpret<f64>(...)
i64.load32_u(...)        // <i64>load<u32>(...)
...

# 从 JavaScript 的角度看

AssemblyScript 在其低级功能之上实现,提供了一个类似 JavaScript 的 标准库,其中包含许多人们习惯于从 JavaScript 中使用的类和命名空间,包括 Math(也包括 Mathf 用于单精度)、Array<T>StringMap<K,V>、类型化数组等等。

上面的加载/存储示例在使用标准库时可能看起来像这样

var view = new Int32Array(12)
...
view[2] = view[0] + view[1]

可以混合使用两种观点,具体取决于是否需要使用 WebAssembly 指令进行低级控制,或者需要使用托管标准库中的惯用概念来完成一项特定任务。

# 常见问题解答

AssemblyScript 是否涉及解释器,或者“VM 中的 VM”?

不,AssemblyScript 直接将 WebAssembly 字节码编译成静态的提前时间。

AssemblyScript 和 TypeScript 之间有什么区别?

TypeScript 转译成 JavaScript,JavaScript 是一种动态的即时编译语言。另一方面,AssemblyScript 编译成静态的 WebAssembly 二进制文件。它们的编译器实现大不相同。但是,这两种语言在表面上非常相似,以至于它们共享了许多概念。例如,TypeScript 工具可以用来编写和重构 AssemblyScript 代码,并且经过一些努力,相同的代码库可以使用 tsc 转译成 JavaScript,并且可以使用 asc 编译成 WebAssembly,或者共享代码。AssemblyScript 编译器本身是可移植的。

AssemblyScript 最终会支持所有 TypeScript 吗?

它可能不会。虽然 TypeScript 为 JavaScript 添加了类型,但它毕竟是一个超集,并且可以描述 JavaScript 的许多动态特性,并非所有这些特性都可以在提前时间编译中支持。然而,足够严格的 TypeScript 代码通常可以轻松地与 AssemblyScript 编译器兼容。

AssemblyScript 的哪些用例很好?

计算密集型逻辑,如图像处理、热游戏逻辑、专用算法、模拟器、编译器等等,都是 WebAssembly 的绝佳用例,因此也是 AssemblyScript 的绝佳用例。在某些情况下,交付字节码而不是缩小后的 JS 也可能更可取,或者仅仅是使用类似 TypeScript 的语言的能力可能会带来新的机会,例如用于嵌入式脚本或插件。

AssemblyScript 是否可以以非标准方式使用,比如在浏览器之外使用?

当然可以!AssemblyScript 模块是自包含的,可以在任何支持 WebAssembly 的地方运行。事实上,可以支持任何任意的主机接口。这里有一个 使用 WASI 导入而不是 Web API 的示例 (在新窗口中打开).

为什么名字很奇怪?

AssemblyScript 对于 Assembly 就像 JavaScript 对于 Java 一样。不太一样。

但是现在,让我们 开始