【发布时间】:2014-12-19 14:40:26
【问题描述】:
如果我定义一个函数
inc = function(x) { return x + 1 }
并对其进行嵌套调用
inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(1)))))))))))))))))))))
这将产生值22。如果我修改嵌套表达式以改为使用call,则将null 传递给this,如
inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, 1)))))))))))))))))))))
这也将产生值22。
但是,在 JavaScriptCore 上,第二种形式似乎会消耗 O(2^n) 内存,其中 n 是嵌套调用的数量.如果我在 Firefox 或 Chrome 中尝试此 JavaScript,情况并非如此,因此它似乎与 JavaScriptCore 隔离。
我的 JavaScript 经验很少(几乎没有)。我不知道各种 JavaScript 实现可能做出的权衡,也不知道示例代码在某些实现中是否合理(为闭包提供通用支持等),而在其他实现中高效。
我的问题是:这段代码本身就存在问题吗?是否应该将其重写为以不同的方式构建?还是代码没问题——JavaScriptCore 只是有一个错误?
我做了一些实验,重构一些对临时对象的内部调用将“截断”内存加倍行为
var temp1 = inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, 1)))))));
var temp2 = inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, temp1)))))));
inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, temp2)))))));
【问题讨论】:
-
我肯定会称之为错误。
-
谢谢@Pointy。我已经向 Apple 提交了 rdar。
-
将 rdar 移至 WebKit:bugs.webkit.org/show_bug.cgi?id=139847
-
这个问题似乎离题了,因为它实际上只是一个错误报告,这篇文章提出的三个问题中有两个主要是基于意见的。
-
这个问题不是主观的。它是关于特定 JavaScript VM 的行为是否正常。此外,由于 iOS 是常见的开发目标,因此其他程序员会想知道这个问题。