为什么函数输出为iframe的数量呢?

catchonme
  • 144
function foo() {
    console.log(length);
}

function bar() {
    var length = '123';
    foo();
}

bar()

为什么上述代码输出的length不是123呢,而居然是页面中iframe的数量,这个有文档可以参考吗?

回复
阅读 1.2k
3 个回答

以上代码实际翻译为
console.log(window.length)
建议阅读 Scope(作用域)变量 的相关文档,在bar函数中定义的length并不会传递到foo中,所以foo中的length并没有定义,就会往this上找,而 当前执行环境中的this是默认 window 对象,就会取到window.length。

采用闭包写法,就会截然不同

function bar() {
    var length = '123';
    function foo() {
        console.log(length);
    }
    foo();
}

bar();

这是函数作用域问题...
因为你的函数foo不是在函数bar内部定义的,所以foo函数的上下文中并没有你声明的length变量...
foo()在执行的时候,由于它的上下文中并没有length变量,所以它会去作用域链中找,一直找到全局作用域中的window对象,刚好window对象有length属性。

function bar() {
    var length = '123';

    function foo() {
        console.log(length);
    }
    foo();
}

bar()

上面这样写,才会输出你定义的变量length...


关于window.length,看看这个:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/length

这个很明显的一个问题是作用域变量查找的问题

(function(){ 
var length3='length3';
function foo() {
    console.log(length); // 1
    console.log(length2); //2
    console.info(length3); //3
}
function bar() {
    var length = '123'; // 4
    length2="length2";  // 5
    foo();
}
bar()
})();

4 的位置会在bar的函数内的作用域中,添加一个length的声明,并赋值为 '123'。
5 的位置会在全局作用域中,添加一个length2的声明,并赋值为'length2'。
1 的位置在执行时,查抄的顺序是,foo的方法作用域内是否有length的声明,然后在网上层作用域查找,而foo的上层作用域是指,foo这个方法声明的位置的上层作用域,也就是匿名函数内的作用域,如果还未找到会一直向上,直到找到根作用域,也就是global对象,而在浏览器中,global对象,指向的是window,所以1的位置会找到window.length,所以结果是iframe的数量
2 的位置按照查找作用域的方式查找,会查找到全局作用域中的由于 5 的位置声明的 length2
3 的位置按照查找作用域的方法查找,会查找到匿名函数作用域里的length3
综上所述,最终的输出结果是
iframe数量
length2
length3

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏