函数作用域和声明提前

本文介绍了JavaScript中的函数作用域,指出其不同于块级作用域的特点,即变量在函数体内始终可见。同时,文章详细阐述了JavaScript的声明提前机制,即变量在声明前已可用,这一特性在预编译阶段发生。通过示例代码,解释了函数内部局部变量会遮盖同名全局变量的情况,建议程序员为保持代码清晰,可以将变量声明放在函数体顶部。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在一些类似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没有块级作用域,因此一些程序员特意将变量声明放在函数体顶部,而不是将声明靠近放在使用变量之处。这种做法使得他们的源代码非常清晰地反映了真实的变量作用域。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值