JavaScript 变量声明提前

JavaScript 使用了函数作用域,变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。

到底是什么意思呢?我们来看下面这段代码

var scope = 'global';
function f(){
  console.log(scope);
  var scope = 'local';
  console.log(scope);
}
f();

你可能认为输出是

global  
local  

但是运行一下你就会发现实际结果是

undefined  
local  

深入研究你会发现就算是你使用传递参数

var scope = 'global';
function f(scope){
  console.log(scope);
  var scope = 'local';
  console.log(scope);
}
f();

实际结果依然是

undefined  
local  

或者代码改写为

var scope = 'global';
function f(){
  console.log(scope);
    return scope;
  var scope = 'local';
  console.log(scope);
}
f();

实际结果仍然是

undefined  

为什么,后面的代码能够影响到前面的代码?

照成这种结果的原因的就是前面提到的函数作用域,在 JavaScript 中上面的代码实际上是这样的

var scope = 'global';
function f(){
    var scope;
  console.log(scope);
  var scope = 'local';
  console.log(scope);
}
f();

JavaScript 这个特性被非正式地称为声明提前,即函数里声明的所有变量都被提前至函数体的顶部,但是这个声明提前至声明却不赋值。

由于拥有这种特性,在编写代码时一些程序员特意将变量声明放在函数体的顶部,而不是像其他语言中让变量声明和使用变量的代码尽量靠近。

所以在函数体中使用到 var 来声明变量时,记得将声明和赋值语句放在函数体的顶部,避免因为这种特性造成变量值为 undefinedBUG


上一篇
Git 忽略文件 Git 忽略文件
使用 git 时,经常需要忽略一些文件,比如一些 IDE 生成的配置文件。 在项目目录加上 .gitignore 文件,然后加入需要忽略文件的文件名就可以了。 .project 需要注意的是,如果需要忽略 .gitignore 文件,那么文
2012-12-23
下一篇
PHP 冒泡排序 PHP 冒泡排序
使用递归实现冒泡排序 PHP 多递归时需要 return,如下述代码中 return bubblesort($array, $count-1); 如果改为 bubblesort($array, $count-1); 上层就接不到值,即结
2012-09-22