变量提升

对于变量的提升首先我们先来看这个小例子:

a = 10;
 var a;
 console.log(a);


如果不了解变量提升,你可能会认为第三行输出的是undefined,其实结果是输出10。再看下面一个例子:

console.log(a);
 var a = 10;


对于这个例子,你可能会认为输出的地方会报错,其实不然,这里会输出undefined。
要了解上面代码输出结果的原因首先我们得知道JavaScript中代码的执行步骤和顺序:在JavaScript中代码是分两步来走的:**1、解析(词法解释/预解释)2、执行。变量的提升就发生在解析这一步,而在第二步执行这一过程中JavaScript代码是从上到下一步一步的执行的。**变量的提升的含义是:变量的声明会被提升到作用域的最顶端,无论该变量在作用域的哪个地方声明,在解析这一步骤都会被提升到作用域的最顶上去。
现在我们在来看第一个例子:第一个例子中第二行的var a;是变量的声明,按照上面所说在解析这一过程中这一行会被提升到顶部,所以第一个例子对JavaScript的执行来说是这样的:

var a;
 a = 10;
 console.log(a);


所以最后输出了10。
针对第二个例子首先我们要了解第二行的含义:var a = 10;这一行不仅仅是声明了a变量,同时还给a变量赋值为10,这一行其实是这样的:var a; a=10; var a;会被提升到顶部,而a=10;会留在原地等待执行。所以第二个例子是这样的:

var a;
 console.log(a);
 a = 10;


JavaScript从上往下执行,在打印a之前变量a只被声明没有被赋值,所以结果是undefined。
JavaScript中是没有块级作用域的,比如下面这个例子:

if(true){
 var a = 10;
 }
 console.log(a);


这个例子中定义的变量a是一个全局的变量。

在JavaScript中处理变量提升外还有函数的提升,并且函数声明的提升要优先与变量声明的提升,且函数声明和函数定义是一起被提升到作用域的顶端,变量则只有声明提升。
首先我们明确函数常见的两种定义方式:函数声明和函数表达式
函数声明,形如:

function fn(){
 console.log(“函数声明”);
 }

函数表达式:形如:

var fn = function(){
 c

onsole.log(“函数表达式”);
}

之后看下面这个例子:

fn();
 function fn(){
 console.log(a);
 var a = 10;
 }


基于前面已学的知识,这个例子在JavaScript运行中是这样的:

function fn(){ //函数提升
 var a; //变量提升
 console.log(a);
 a = 10;
 }
 fn();


所以结果输出undefined。
再看下面一个:

fn();
 var fn = function(){};


上面这个例子就是用的函数表达式的方式定义了一个函数fn,解析后如下:

var fn;
 fn();
 fn = function(){};

作用域
JavaScript中变量分为全局变量和局部变量,对应的作用域就是全局作用域和局部作用域。在函数之外声明的变量拥有全局作用域,全局作用域在函数内部也可以正常访问。与之相反局部作用域只能在声明所在的固定代码片段中访问到,比如函数内部,出了函数就不能访问。但是需要注意的一点是在函数内部声明的变量一定要加上var,否则就变成了全局变量拥有全局作用域。
JavaScript中没有所谓的块级作用域,JavaScript中的作用域是相对与函数而言的:

for(var i=0;i<10;i++){
 }
 console.log(i);


上面代码for循环中定义的i在{}外就可以访问到,不同于Java,如果是Java就不能访问,所以上面最后输出的结果是10。