Javascript EcmaScript 5 Google TechTalk-范围界定事故1例
我正在看这个讲座: 在第35分钟,出现上述问题。讲师表示,某些浏览器将返回Javascript EcmaScript 5 Google TechTalk-范围界定事故1例,javascript,prototype,scope,Javascript,Prototype,Scope,我正在看这个讲座: 在第35分钟,出现上述问题。讲师表示,某些浏览器将返回foo,而不是8 为什么? 顺便说一句,在写这个问题的时候,我发现了这个问题,但我还是会发布这个问题,因为这是一个有趣的问题:) 现场演示: Opera 11警报'foo',所有其他浏览器(包括IE9)返回8 更新:我收回我说过的关于我已经弄明白了这一点的话。它与嵌套函数是命名函数有关。如果删除名称(baz),Opera将返回8,这意味着该问题仅发生在命名的嵌套函数中 但是为什么呢?我承认我查过了。至少可以说,我不认
foo
,而不是8
为什么?
顺便说一句,在写这个问题的时候,我发现了这个问题,但我还是会发布这个问题,因为这是一个有趣的问题<代码>:)
现场演示: Opera 11警报
'foo'
,所有其他浏览器(包括IE9)返回8
更新:我收回我说过的关于我已经弄明白了这一点的话。它与嵌套函数是命名函数有关。如果删除名称(
baz
),Opera将返回8
,这意味着该问题仅发生在命名的嵌套函数中
但是为什么呢?我承认我查过了。至少可以说,我不认为我能那么容易地解决这个问题 为了理解这个问题,命名函数表达式的语义是必要的。引用该链接,“命名函数表达式的标识符仅对函数的本地范围可用。”这具体意味着:
var fn = function aNamedFunction() {
typeof aNamedFunction; // "function"
};
typeof aNamedFunction; // "undefined"
为了实现此行为,SpiderMonkey和其他JS引擎在父框架(即定义函数的范围)和函数的内部框架(每次调用函数时都会创建)之间创建一个虚拟框架。此虚拟帧的构造方式类似于调用了new Object()
,并包含从aNamedFunction
到函数对象本身的映射
在问题的代码示例中,x
通过首先查看函数调用的最内层框架来解决。因为函数体没有声明var x代码>,找不到它,解释器检查上一级的帧,即虚拟帧。由于虚拟帧是由newobject()
(或语义上等价的东西)创建的,因此在虚拟帧中查找x
将遍历原型链,就像对任何其他JavaScript对象一样。因此,它搜索Object.prototype
,找到绑定到x
的字符串'foo'
,并返回它
谢天谢地,ES5的词汇范围是一致的
另类阅读:我理解问题的重点,我相信这是一个重要的区别,但是这个foo
函数有一些代码味道。啊,是的。我记得在规范中读过关于包装器对象的内容。所以标识符解析将首先遍历作用域链以到达包装器对象,然后遍历该对象的原型链以到达x。我无法想象这对随意的JavaScript程序员来说会有多困惑:)
var fn = function aNamedFunction() {
typeof aNamedFunction; // "function"
};
typeof aNamedFunction; // "undefined"