3.10.1函数作用域和声明提前

本文探讨了JavaScript中的函数作用域,指出其不同于C语言的块级作用域。在JavaScript中,变量在函数体内始终可见,且存在声明提前(hoisting)现象,即变量声明会被提升到函数体顶部,但赋值操作仍保持原位置。这种特性可能导致预期外的行为,如局部变量会覆盖同名全局变量。良好的编程习惯建议将变量声明置于函数体顶部,以清晰展示作用域。

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

在一些c语言中的编程中,花括号内的每一段代码都具有各自的作用域,而且变量声明他们的代码段之外是不可见的,我们称之块级作用域。而javascirpt中没有块级作用域。javascirpt取而代之地使用了函数作用域:变量在声明它们的函数体嵌套的任意函数体内都是要有定义的。

以下代码所示,在不同的位置定义了变量i,j和k,他们都在同一个作用域内–这三个变量正在函数体内均是由定义的

function test(){
    var i = 0;                       //i 在整个函数体内均是要有定义的
    if(typeof 0 == "object"){
        var j = 0;
        for(var k = 0; k < 10; k++){ //k在函数体没有定义的,不仅仅是在循环内
            console.log(k);          //输出数字0~9
        }
        console.log(k);              //k已经定义了,输出10
    }
    console.log(j);                 //j已经定义了,但可能没有初始化
}

javascirpt的函数作用域是指在函数内声明的所有变量在函数体内始终均是可见的。有意思的是,这意味着变量在声明之前甚至已经可用。javascirpt的这个特性被非正式地称为声明提前(hoisting),即javascirpt函数里声明的所有变量(但不涉及赋值)都被称”提前”至函数体的顶部,看一下代码;

var scope = "global"
function f (){
    console.log(scope) ;    //输出'undefined',而不是'global'
    var scope = 'local';    //变量在这里赋值,函数体内均有定义的
    console.log(scope);     //输出'local'
}

你可能会误认为第一行输出是‘gloal’,由于函数作用域的特性,局部变量在整个函数体始终是有定义的,也就是说函数体的局部变量掩盖了同名的全局变量。
在函数体内的变量声明 ‘提前’ 至函数体顶部,同时变量初始化留在原来的位置:

function f (){
    var scope;          //在函数顶部声明了全局变量
    console.log(scope); //变量存在,但其值是'ubdefied'
    scope = 'local';    //这里将其初始化赋值
    console.log(scope)  //这里它具有了我们所期望的值
}

在具有块级作用域的编程语言中,在狭小的作用域里让变量声明和使用变量的代码尽可能靠近彼此,通常来讲这是一个非常不错的编程习惯。由于javascirpt没有块级作用域,因此一些程序员特意将变量声明放在函数体的顶部,而不是将声明靠近放在使用变量之处,这种做法使得他们的源代码非常清晰地反应真实的变量作用域。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值