在一些类C的编程语言中,花括号内的每一段代码都具有各自作用域,并且变量在声明他们的代码段之外是不可见的,这个概念叫做块级作用域。
javascript中没有块级作用域的概念,有的是函数作用域的概念:变量在声明他们的函数体内部的任何位置(包括这个函数体嵌套的任何函数体内)都是可读取的。
var k = "k"; if(1===1){ var j ="j"; for (var i = 0; i < 3; i++) { console.log(i); } console.log(i);//输出3,表明i不仅仅在循环中有定义,在代码段中也有定义 } console.log(j);//输出j:表明j在不仅仅在代码段内有定义 console.log(i);//输出3:表明i在循环中有定义,在代码段中有定义,另外在整个函数体各处都有定义 console.log(k);//输出k:很明显是在整个函数各处都有定义
简单的说,上面的在不同位置定义的三个变量:i,j,k都是同一个作用域--整个函数体。由于这个原因,这就意味着变量在声明之前甚至已经可用了。这个特性叫做声明提前。
比如下面这个例子,myfield为全局变量,在自定义函数中使用输入的时候,直接输出为此变量的当前值
但是如果在函数中声明了一个同名的局部变量,如果这个局部变量的声明语句在变量使用之后,如下图所示的输出结果可能和自己想象中的不太一样。
出现这个现象的原因是,局部变量在整个函数体中有定义,这个局部变量遮盖了全局变量。局部变量的声明提前了,但是变量的初始化并没有提前,还是在原来的位置。
因此,上面这段代码等价于如下: