JavaScript基础——var、let、const和作用域

一、作用域

我们对作用域作简单介绍:

(1)ES5里只有两种作用域:全局作用域和函数作用域,且函数作用域内声明的变量由于存在hoisting,它的有效范围是整个函数体。

//定义全部变量
var a=2;
//定义外部函数
function outer(){
    //访问全部变量
    console.log(a);
    //定义内部函数
    function inner(){
        console.log(a);
        var a=10;
        console.log(a);
    }
    inner();
    console.log(a);
}
outer();

//输出结果:
2
undefined
10
2

(2)ES6除了上面两种,还新增了块级作用域,即最近的花括号所涵盖的范围。

注意:对类似 a=10; 这种给尚未声明的变量赋值的语句,会使得该变量a自动成为全局变量。但在"use strict"定义的严格模式下,不允许使用未声明的变量。

二、let、const

1. let用法类似var,但是let声明的变量,只在let命令所在的代码块内有效。

{
    var a=1;
    let b=2;
}

console.log(a);
console.log(b);

//输出结果:
1
Uncaught ReferenceError:b is not defined

2. let命令不存在变量提升,let声明的变量一定要在声明后使用

​console.log(b);
let b=2;

//输出结果:
ReferenceError

3.暂时性死区TDZ:只要在块级作用域内存在let命令,那么就形成了封闭作用域,在let声明变量之前,该变量都是不可用的

var tmp=1;
if(true){
    tmp=2;    //ReferenceError
    let tmp;
}

4. let不允许在相同作用域内,重复声明同一个变量。【虽然var重复声明无效】

//抛出语法错误:SyntaxError
function func(){
    let a=1;
    var a=2;
}

//抛出语法错误:SyntaxError
function func(){
    let a=1;
    let a=2;
}

5. let声明的全局变量不是全局对象的属性。为了避免与ES5冲突,ES6规定:var和function声明的全局变量,依旧是顶层对象的属性,而let、const声明的全局变量,不属于顶层对象的属性,不能通过window.变量名的方式访问该变量

6. 块级作用域补充

(1)解决的问题:内层变量会覆盖外层变量;循环变量泄露为全局变量。

(2)通过let,const声明变量实现

(3)块级作用域必须有大括号{}

7. const 和 let 的区别

const 声明的变量不能修改值(实际是一个值的只读引用),所以const一旦声明变量,就必须立即初始化,否则报错

1. const 声明的变量值是常量时,不能改变(通过重新赋值的方式);【可以通过Object.defineProperty】

2. const 声明的变量值是引用类型时,不能改变引用地址。

3. 而 let 声明的变量可以改变、值和类型都可以改变,没有限制。

const foo = {};

foo.prop = '123';  //添加属性,可以成功

foo = {key:78};  //指向另一个对象,报错

如果需要真正的冻结对象,采用Object.freeze方法。

三、let与var的区别

                           JavaScript基础——var、let、const和作用域_第1张图片

你可能感兴趣的:(JavaScript基础,javascript)