function foo() {
console.log(length);
}
function bar() {
var length = '123';
foo();
}
bar()
为什么上述代码输出的length不是123呢,而居然是页面中iframe
的数量,这个有文档可以参考吗?
function foo() {
console.log(length);
}
function bar() {
var length = '123';
foo();
}
bar()
为什么上述代码输出的length不是123呢,而居然是页面中iframe
的数量,这个有文档可以参考吗?
这是函数作用域问题...
因为你的函数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
6 回答3k 阅读✓ 已解决
8 回答4.7k 阅读✓ 已解决
6 回答3.5k 阅读✓ 已解决
5 回答2.8k 阅读✓ 已解决
6 回答2.4k 阅读
5 回答6.4k 阅读✓ 已解决
4 回答2.3k 阅读✓ 已解决
以上代码实际翻译为
console.log(window.length)
建议阅读 Scope(作用域) 和 变量 的相关文档,在bar函数中定义的length并不会传递到foo中,所以foo中的length并没有定义,就会往this上找,而 当前执行环境中的this是默认 window 对象,就会取到window.length。
采用闭包写法,就会截然不同