Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/430.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript EcmaScript 5 Google TechTalk-范围界定事故1例_Javascript_Prototype_Scope - Fatal编程技术网

Javascript EcmaScript 5 Google TechTalk-范围界定事故1例

Javascript EcmaScript 5 Google TechTalk-范围界定事故1例,javascript,prototype,scope,Javascript,Prototype,Scope,我正在看这个讲座: 在第35分钟,出现上述问题。讲师表示,某些浏览器将返回foo,而不是8 为什么? 顺便说一句,在写这个问题的时候,我发现了这个问题,但我还是会发布这个问题,因为这是一个有趣的问题:) 现场演示: Opera 11警报'foo',所有其他浏览器(包括IE9)返回8 更新:我收回我说过的关于我已经弄明白了这一点的话。它与嵌套函数是命名函数有关。如果删除名称(baz),Opera将返回8,这意味着该问题仅发生在命名的嵌套函数中 但是为什么呢?我承认我查过了。至少可以说,我不认

我正在看这个讲座:

在第35分钟,出现上述问题。讲师表示,某些浏览器将返回
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"