JavaScript的确有很多和C-like编程语言不一样的地方,就比如简章的变量作用域。让写惯了C++/Java的我很不习惯。
C/C++/Java里的变量作用域被称为block scope, 也就是块作用域。但JavaScript里可不一样,它的作用域称为function scope-函数域。简单点说,就是变量不管在哪声明,在整个函数范围内是可见的。
举个例子先:
1 2 3 4 5 6 7 8 9 10 11 |
function testScope() { var i = 0; for (var j = 0; j < 10; ++j) { for (var k = 0; k < 5; ++k) { console.log(j * 10 + k); } } console.log(j); console.log(k); console.log(i); } |
怎么样,是不是有点别扭?j, k在for block之外,在function block之内就可以被访问。
那如果是下面这个函数呢,
1 2 3 4 5 |
function testScope2() { console.log(scope); // undefined var scope = "hello"; console.log(scope); // hello } |
这个也是正确的,它等价于:
1 2 3 4 5 6 |
function testScope2() { var scope; console.log(scope); // undefined scope = "hello"; console.log(scope); // hello } |
简单的说,就是变量像是被提到函数开始的地方声明,这被称为hoisting(informally).
所以JavaScript不能像C/C++/Java那样,在使用变量时才就近声明该变量,反而应该为了避免这种默认提前声明所产生的误解,自己手动把变量声明写到函数开始的地方。唉,不爽! 😥