js作用域和var、let、const关键字的小知识

141 阅读3分钟

JavaScript(简称JS)是一种高级的、动态的编程语言,广泛应用于Web开发中。作为一门灵活而强大的语言,JavaScript 的作用域是其核心概念之一。理解 JavaScript 作用域的机制对于编写高质量的代码至关重要。在本文中,我们将深入探讨 JavaScript 作用域的概念、特性以及与闭包的关系。

什么是作用域?

在程序设计中,作用域是指程序中定义变量的区域,该变量在此区域内可被访问。JavaScript 采用的是词法作用域,也称为静态作用域。这意味着作用域是在代码编写阶段就确定了,而不是在运行时确定。

全局作用域

全局作用域是指在代码中任何地方都可以访问的作用域。在浏览器环境中,全局作用域通常是指 window 对象。全局作用域中定义的变量和函数可以被任何地方访问。

javascriptCopy code
var globalVariable = 'I am in global scope';

function globalFunction() {
    console.log('I am a global function');
}

函数作用域

除了全局作用域外,JavaScript 还具有函数作用域。函数作用域是指在函数内定义的变量只能在该函数内部访问。

javascriptCopy code
function myFunction() {
    var localVar = 'I am a local variable';
    console.log(localVar); // 可以访问 localVar
}

console.log(localVar); // 无法访问 localVar,会抛出错误

函数作用域中的变量查找可以从内部作用域内往外部作用域查找的,但是不能由外到内查找。

var a = 1 

const foo = () => {
    var c = true
    console.log(a) // 可以去外面查找到: var a = 1 输出 1
    const bar = () => {
        console.log(a) // 同理函数中没有出现变量a的声明,于时向外部查找 输出 1
    }   //属于函数表达式 
    bar()
}
foo()
    var a = 1
    const foo = () => {
        var a = 2 
        console.log(a) // 内部域a变量声明 输出为 2
    }
    foo()

块级作用域

在ES6(ECMAScript 2015)之前,JavaScript 没有块级作用域,只有函数作用域和全局作用域。但是,引入了 letconst 关键字之后,JavaScript 也支持了块级作用域。

javascriptCopy code
if (true) {
    let blockScopedVar = 'I am a block scoped variable';
    console.log(blockScopedVar); // 可以访问 blockScopedVar
}

console.log(blockScopedVar); // 无法访问 blockScopedVar,会抛出错误

var、let和const的一些区别

引入的letconst关键字与原先ES6之前的var,在声明变量上有一些区别,例如:

       var a = 1
       var a = 2
       console.log(a) //输出为 2
    let a = 1
    let a = 2 // 报错
    console.log(a) // 没有输出,会有错误
    const a = 1
    const a = 2 //报错
    a = 3 // 报错
    console.log(a) // 没有输出,会有错误

从上面的代码可以看到 letconst,无法重复声明一个同一个变量,同时const设置的变量不可以用赋值的手段改变它,因为使用 const 关键字声明的变量被称为常量(constant),常量一旦被声明并赋值,其值就不能被修改。

于此同时var还有一个与letconst不同的特点,那就是var会把声明提升(hoisted)。

    console.log(a)
    var a = 2
    console.log(a)

是不是会有人觉得上面的输出结果都是2,然而并不是,因为var只是将变量a的声明提到了全局作用域的最顶部,变成了下面的样子

    var a 
    console.log(a)
    a = 2
    console.log(a)

所以看的出来,结果应该是:undefined, 2

总结

JavaScript 作用域是理解 JavaScript 编程语言的关键部分之一。全局作用域、函数作用域和块级作用域提供了不同的变量访问范围。而闭包则允许函数保持对其作用域的访问权限,使得 JavaScript 具有了更强大的编程能力。深入理解 JavaScript 作用域有助于开发人员编写更加健壮和可维护的代码。