JavaScript 除了双精度浮点之外没有任何其他数字类型(ECMAScript 6 除外)类型数组 http://www.ecma-international.org/ecma-262/6.0/#table-49),但底层实现可以选择以任何它喜欢的方式存储数字,只要 JavaScript 代码的行为相同。
JavaScript 现在是编译的,这意味着它可以通过许多语言中不明显的方式进行优化。
如果函数中的局部变量仅采用整数值并且不以任何方式暴露在函数外部,那么它实际上可以在编译代码时使用整数类型来实现。
不同浏览器的实现有所不同。目前,它似乎在 MS Edge 中产生了巨大的差异,在 Firefox 中产生了很大的差异,而在 Chrome 中则完全没有差异:http://jsperf.com/int-vs-double-implementation http://jsperf.com/int-vs-double-implementation(注:jsperf 认为 MS Edge 是 Chrome 42。)
进一步的研究:
JS 引擎 Spidermonkey (Firefox)、V8 (Chrome、Opera)、JavaScriptCore (Safari)、Chakra (IE) 和 Rhino(可能还有其他引擎,但很难找到实现细节)使用不同的方式使用整数类型或存储尽可能将数字视为整数。一些引言:
“有效地表示数字和 JavaScript
对象,V8 用 32 位值代表我们俩。它使用了一点
知道它是一个对象(flag = 1)还是一个整数(flag = 0)
这里是 SMall Integer 或 SMI,因为它是 31 位。”
http://thibaultlaurens.github.io/javascript/2013/04/29/how-the-v8-engine-works/ http://thibaultlaurens.github.io/javascript/2013/04/29/how-the-v8-engine-works/
“JavaScript 没有内置的整数值概念,但是
为了提高效率,JavaScriptCore 会将大多数整数表示为 int32
而不是双倍。”
http://trac.webkit.org/wiki/JavaScriptCore http://trac.webkit.org/wiki/JavaScriptCore
“[...]非双精度值是 32 位类型标签和 32 位有效负载,
通常是指针或带符号的 32 位整数。”
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals
“在 Windows 10 和 Microsoft Edge 中,我们已经开始优化 Chakra
解析器和 JIT 编译器识别非常量变量
全局定义且从不存在的整数声明
在程序执行期间发生了变化。”
https://blogs.windows.com/msedgedev/2015/05/20/delivering-fast-javascript-performance-in-microsoft-edge/ https://blogs.windows.com/msedgedev/2015/05/20/delivering-fast-javascript-performance-in-microsoft-edge/