Simple is beauty

JavaScript 高级特性

1. 作用域

作用域(scope)是结构化编程语言中的重要概念,它决定了变量的可见范围和生命周期,正确使用作用域可以使代码更清晰、易懂。作用域可以减少命名冲突,而且是垃圾回收的基本单元。JavaScript 的作用域不是以花括号包围的块级作用域(block scope) ,这个特性经常被大多数人忽视,因而导致莫名其妙的错误。

if (true) {
var somevar = 'value';
}
console.log(somevar); // 输出 value
在其他大多数类C语言中会出现变量未定义的错误,而在Javascript中却完全合法,这是因为Javascript中的作用域完全由函数
来决定,if,for语句中的花括号不是独立的作用域

1.1 函数作用域
不同于大多数类 C 语言,由一对花括号封闭的代码块就是一个作用域, JavaScript 的作用域是通过函数来定义的,在一个函数中定义的变量只对这个函数内部可见,我们称为函数作用域。在函数中引用一个变量时, JavaScript 会先搜索当前函数作用域,或者称为“局部作用域”,如果没有找到则搜索其上层作用域,一直到全局作用域。

var v1 = 'v1';
var f1 = function() {
console.log(v1); // 输出 v1
};
f1();
var f2 = function() {
var v1 = 'local';
console.log(v1); // 输出 local
};
f2();
以上事例十分明了,变量的搜索顺序,由内到外。直到全局作用域


看以下代码:

var scope = 'global';
var f = function() {
console.log(scope); // 输出 undefined
var scope = 'f';
}
f();

这是 JavaScript 的一个特性,按照作用域搜索顺序,在 console.log 函数访问 scope 变量时, JavaScript会先搜索函数 f 的作用域,恰巧在 f 作用域里面搜索到 scope 变量,所以上层作用域中定义的 scope 就被屏蔽了,但执行console.log 语句时, scope 还没被定义,或者说初始化,所以得到的就是 undefined 值。我们还可以从另一个角度来理解:对于开发者来说,在访问未定义的变量或定义了但没有初始化的变量时,获得的值都是 undefined。

于是我们可以认为,无论在函数内什么地方定义的变量,在一进入函数时就被定义了,但直到 var 所在的那一行它才被初始化,所以在这之前引用到的都是 undefined 值。

30 条评论