Šim*_*das 5 javascript scope prototype
我正在看这个讲座:http://www.youtube.com/watch?v = Kq4FpMe6cRs

// the speaker states that "'bar' is just some function 
// that invokes whatever function is passed to it"
function bar(fn) {
    fn();
}
function foo() {
    var x = 8;
    bar(function baz() { return x; });
}
Object.prototype.x = 'foo';
在第35分钟,呈现上述问题.讲师说,有些浏览器会返回foo而不是8.
为什么?
顺便说一句,在写这个问题时,我想出来了,但无论如何我都会发布这个问题,因为这是一个有趣的问题. :)
现场演示: http ://jsfiddle.net/simevidas/mHyKc/
Opera 11警报'foo',所有其他浏览器(包括IE9)返回8.
更新:我收回了我所说的关于解决这个问题的内容.它与作为命名函数的嵌套函数有关.如果删除名称(baz),则Opera返回8,这意味着只有命名的嵌套函数才会出现问题.
但为什么?
我承认我查过。至少可以说,我认为我不会那么容易地弄清楚这一点。http://kangax.github.com/nfe/#spidermonkey-peculiarity
为了理解这个问题,命名函数表达式的语义是必要的。引用该链接,“命名函数表达式的标识符仅适用于函数的本地范围。” 具体来说,这意味着:
var fn = function aNamedFunction() {
  typeof aNamedFunction;  // "function"
};
typeof aNamedFunction;  // "undefined"
为了实现此行为,SpiderMonkey 和其他 JS 引擎在父框架(即定义函数的范围)和函数的内部框架之间创建一个虚拟环境框架,该框架在每次调用函数时创建。这个虚拟框架的构造就像被调用一样,并且包含从函数对象本身到函数对象本身的new Object()映射。aNamedFunction
在问题的代码示例中,x通过首先查看函数调用的最内层框架来解决。由于函数体没有声明var x;,因此找不到它,解释器会检查上一层的帧,这是虚拟帧。由于虚拟框架是由new Object()(或语义上等效的东西)创建的,因此在虚拟框架中查找x将遍历原型链,就像对任何其他 JavaScript 对象所做的那样。因此,它搜索,找到绑定到 的Object.prototype字符串,然后返回它。'foo'x
感谢上帝 ES5 一致的词法范围。
替代阅读:http://dmitrysoshnikov.com/ecmascript/chapter-5-functions/#nfe-and-spidermonkey