Javascript之变量声明——var let 与const

131 阅读2分钟

JavaScript中的变量是松散类型的,可以保存任何类型的数据。在Javascript中,可以声明变量的关键字有 varletconst

1. var

在ES5阶段,使用var定义变量,其定义的变量具有以下特征

1.1 函数作用域

用var定义的变量,其作用域为全局作用域或函数作用域,没有块级作用域的概念,可以跨块访问,但不能跨函数访问。

function func(){
    var a="孙悟空"
}
{
    var b= "猪八戒"
}
{
    var c = b
}
func();
console.log(a) // ReferenceError: a is not defined
console.log(b) // "猪八戒"
console.log(c) // "猪八戒"
1.2 变量提升

概念:变量提升指的在javascript代码执行过程中(严格来说是执行上下文的创建阶段/代码编译阶段),javascript引擎把函数和变量的声明提升到代码作用域开头的行为。通过var声明的变量被存储到执行上下文的变量环境中,并设置默认值为undefind,因此执行阶段可以在声明前使用。

1.3 重复声明

var 可以重复声明变量

1.4 全部变量挂载到window

浏览器环境中,全局作用域下,使用var声明的变量,会挂载到window对象上。

var a = 1;
console.log(window.a === a); // true

2.let

2.1 块级作用域

以let声明的变量具有块级作用域,只能在包含其内的区域被引用

2.2 不可重复声明
2.3 暂时性死区

用let声明的变量,在执行上下文创建阶段,会被创建而不会被初始化,因此执行阶段不能在其声明前以任何方式来引用它,故而将let声明之前的执行瞬间称为暂时性死区。

3.const(共同特点同let,下面两点为其特性)

3.1 声明变量同时必须初始化
3.2 一旦声明不能再修改(这里指的是变量对应的内存地址)

4. 经典面试题

以下代码运行后会输出什么?

for(var i = 1;i <= 5; i++){
    setTimeout(function(){
        console.log(i)
    },0);
}

答案:6 6 6 6

上述代码执行时,创建了多个函数对象,而每个函数对象的执行上下文中都含有[[scope]]属性指向其可以直接访问的作用域(也可以理解为父级作用域),此处就是window,而var声明的变量i恰好也在window上,所以循环每次对i的修改,全局i也会跟着变,而i是被所有函数对象所共享的。循环结束,i的值变成了6,所以最后会输出5个6。