ES5 中JS 的作用域:
在ES5 中,JS 只有两种形式的作用域:全局作用域和函数作用域。
-
全局作用域
全局对象的作用域,任何地方都可以访问到(如果没有被函数作用域覆盖)。 -
函数作用域
整个函数的范围内可访问。
变量提升(hoisting)
ES5 中存在变量提升,ES6 中并不存在变量提升。因此下面的内容只针对ES5。
ES5 中变量声明会提升到它所在 作用域的顶端 去执行。
以下两段示例代码是一样的结果:
代码1:
x = 5; // 变量 x 设置值为 5
console.log(x);
var x; // 声明 x
代码2:
var x; // 声明 x
x = 5; // 变量 x 设置值为 5
console.log(x);
函数声明和变量声明总是会被解释器悄悄地被"提升"到方法体的最顶部。
但是需要注意的是:被初始化的变量不会提升
以下两段示例代码是不一样的结果:
代码1:
var x = 5; // 初始化 x
var y = 7; // 初始化 y
console.log(x + y);
打印结果为:12
代码2:
var x = 5; // 初始化 x
console.log(x + y);
var y = 7; // 初始化 y
打印结果为:NaN
扩展:经典面试题
console.log(v1);
var v1 = 100;
function foo() {
console.log(v1);
var v1 = 200;
console.log(v1);
}
foo();
console.log(v1);
输出的结果:

函数提升
ES5 中不仅仅是变量声明有提升的现象,函数的声明也是一样。
具名函数的声明有两种方式:
1、函数声明式
function a () {}
2、函数字面量式
var b = function () {}
函数字面量式的声明跟变量提升类似,但是函数声明式的提升现象和变量提升略有不同。
示例:
console.log(a);
a();
function a () {
console.log("我是函数a");
}
运行结果:

它的执行顺序相当于:
function a () {
console.log("我是函数a");
}
console.log(a);
a();
字面量式声明函数的提升是整个代码块提升到它所在的作用域的顶部执行。
网友评论