5

我在 javascript 调试会话中看到以下行为:

o // function (a1, a2, a3) {  return a1 + a2 + a3; }

typeof(o) //'function'

for (var n in o) { console.log(n); } //<a list of properties>

Object.keys(o) //TypeError: not an object

Object.prototype.toString.call(o); //"[object Function]"

这让我想知道 - 函数可以不是对象吗?

[在 Chrome 29 上运行,在 Mac 上]


请注意,这是在一个非常复杂的调试会话的中间。我不完全知道'o'来自哪里,或者它是如何创建的。此外,到目前为止,我还无法通过简单的测试用例重现此问题。一个简单的设置按预期工作:

var t = function() { return true; } //undefined
t.a = "aa" //"aa"
Object.keys(t) //["a"]
4

2 回答 2

4

当你看到这样的东西时,你可以尝试:

console.log(Object.keys)

或同等学历。

(如果您可以找到浏览器的原始密钥实现,请进行比较并确保它与您所看到的相同)

(阅读有关问题的评论以了解更多关于如果看到此类问题要查看的内容)


虚惊。函数始终是对象,Chrome 的人知道如何制作虚拟机。

我跑了

grep -r "Object.defineProperty(" *

grep -r "Object.defineProperties(" *

并找到了一个 Object.keys 被覆盖的地方,其中有一个错误的功能。

相关代码是动态加载的,所以我没有看到它在浏览器中显式加载。

于 2013-09-17T19:36:25.257 回答
2

Object.keys 该算法执行的第一步是:

  1. 如果 Type( O ) 不是 Object,则抛出TypeError异常。

由于您遇到了这样的错误,我相信您的对象必须是主机对象,正如 Bergi上面评论的那样。尽管如此,Object.prototype.toString.call(o)给出“[object Function]”还是很奇怪,因为不允许宿主对象使用“Function”作为它们的[[Class]]属性值

* 有关 的含义,请参阅规范第 8 节Type(x)的最后一句。

于 2013-09-17T18:55:29.910 回答