您的位置:首页 > Web前端 > JavaScript

函数作用域和声明提前

2017-06-07 11:34 288 查看
在一些类似C语言的编程语言中,花括号内的每一段代码都具有各自的作用域,而且变量在声明他们的代码段之外是不可见的,我们称之为块级作用域。而JavaScript中没有块级作用域。JavaScript取而代之地使用了函数作用域:变量在声明的函数体以及这个函数体嵌套的任意函数体内都是有定义的。

在如下所示的代码中,在不同位置定义了变量i,j和k,它们都在同一个作用域内 - 这三个变量在函数体内军事有定义的。

function test(o){
var i=0;//i在整个函数体内均是有定义的
if(typeof o == 'object'){
var j=0;//j在函数体内是有定义的,不仅仅是在这个代码段内
for(var k=0;k<10;k++){//k在函数体内是有定义的,不仅仅是在循环内
console.log(k);//输出数字0-9
}
console.log(k);//k已经定义了,输出10
}
console.log(j);//j已经定义了,输出0
}


JavaScript的函数作用域是指在函数内声明的所有变量在函数体内始终是可见的。有意思的是,这意味着变量在声明之前甚至已经可用。Javacript的这个特性被正式地称为声明提前,即JavaScript函数里声明的所有变量(但不涉及赋值)都被‘提前’到函数体的顶部.

*

‘声明提前’这步操作是在JavaScript引擎的‘预编译’时进行的,是在代码可是运行之前。

*

看如下代码:

var scope='global';
function fn(){
console.log(scope);//输出‘undefined’,而不是‘global’
var scope='local';//变量在这里赋初始值,但变量本身在函数体内任何地方均是有定义的
console.log(scope); //输出‘local’
}


你可能会误以为函数中的第一行会输出‘global’,因为代码还没有执行到var语句生命局部变量的地方。其实不然,由于函数作用域的特性,局部变量在整个函数体始终是有定义的,也就是说,在函数体内局部变量遮盖了同名全局变量。尽管如此,只有程序执行到var语句的时候,局部变量才会被真正赋值。因此,上述过程等价于:

var scope='global';
function fn(){
var scope;//在函数顶部声明了局部变量
console.log(scope);//变量存在,输出‘undefined’
scope='local';//变量在这里赋初始值
console.log(scope); //输出‘local’
}


在具有块级作用域的编程语言中,在狭小的作用域里让变量声明和使用变量的代码尽可能靠近彼此,通常来讲,这是一个非常不错的编码习惯。由于JavaScript没有块级作用域,因此一些程序员特意将变量声明放在函数体顶部,而不是将声明靠近放在使用变量之处。这种做法使得他们的源代码非常清晰地反映了真实的变量作用域。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript