首先看一个例子:
function Foo() {
getName = function () { alert (1); };
return this;
}
Foo中的getName理解为变量,它没有var声明, 所以先向当前Foo函数作用域内寻找getName变量,没有。
再向当前函数作用域上层,即外层作用域内寻找是否含有getName变量。
是一个从里到外寻找变量的过程, 会一直向上查找到window对象,若window对象中也没有getName属性,就在window对象中var一个getName变量(全局变量)。
![](https://images2015.cnblogs.com/blog/897551/201603/897551-20160319144244849-99871587.png)
先贴上几个例子的代码截图,方便从基础理解之
![](https://images2015.cnblogs.com/blog/897551/201603/897551-20160319144303943-927711268.png)
JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部。
1 'use strict';
2
3 function foo() {
4 var x = 'Hello, ' + y;
5 alert(x);
6 var y = 'Bob';
7 }
8
9 foo();
对于上述foo()
函数,JavaScript引擎看到的代码相当于:
function foo() {
var y; // 提升变量y的申明
var x = 'Hello, ' + y;
alert(x);
y = 'Bob';
}
把var y = 'Bob';拆分为了 var y ;y='Bob';所以y的值为undefined
所以为了避免各种怪异事件的发生,最好在函数开头声明需要的变量;
function foo() {
var
x = 1, // x初始化为1
y = x + 1, // y初始化为2
z, i; // z和i为undefined
// 其他语句:
for (i=0; i<100; i++) {
...
}
}
JavaScript默认有一个全局对象
window
直接访问全局变量
a
和访问window.a
是完全一样的'use strict';
function foo() {
for (var i=0; i<100; i++) {
//
}
i += 100; // 仍然可以引用变量i
}
为了解决块级作用域,ES6引入了新的关键字
let
,用let
替代var
可以申明一个块级作用域的变量'use strict';
function foo() {
for (var i=0; i<100; i++) {
//
}
i += 100; // 仍然可以引用变量i
}