let、var、const以及块级作用域


块级作用域

ES5 中作用域有:全局作用域、函数作用域。但是没有块作用域的概念。

ES6 中新增了块级作用域。块作用域由 { } 包括,if语句和 for语句里面的{ }也属于块作用域。

<script type="text/javascript">
    {
        var a = 1;
        let b = 2;
        console.log(a); // 1
        console.log(b; // 2
    }
    console.log(a); // 1
    console.log(b); // 报错
    // 可见,通过var定义的变量可以跨块作用域访问到。let定义的变量,外部访问就会报错

    (function A() {
        var b = 2;
        console.log(b); // 2
    })();
    // console.log(b); // 报错,
    // 可见,通过var定义的变量不能跨函数作用域访问到

    if(true) {
        var c = 3;
    }
    console.log(c); // 3
    for(var i = 0; i < 4; i++) {
        var d = 5;
    };
    console.log(i); // 4   (循环结束i已经是4,所以此处i为4)
    console.log(d); // 5
    // if语句和for语句中用var定义的变量可以在外面访问到,
    // 可见,if语句和for语句属于块作用域,不属于函数作用域。
</script>

let、var、const 的区别

var 用来声明变量的,没有块的概念,可以跨块访问,但是不能跨函数访问;

let 也是用来声明变量的;声明的变量只有在let命令所在的块内才有效

const是用来声明一个常量的。即是一个只读变量,一旦声明,就必须立即初始化;

var、let 的不同点

  1. let所声明的变量只有在所在的代码块内才有效;var会变量提升;
  1. let所声明的变量一定要在声明后使用,否则会报错;var可以在声明之前使用,值为undefined;

    //var 的情况
    console.log(foo);  //输出undefined
    var foo=2;
    //let的情况
    console.log(bar);  //报错 ReferenceError
    let bar=2;
  2. ES6有明确规定,如果区域块中存在let或const命令,则这个区域块对这些命令的声明的变量从一开始就形成了封闭作用域,即只要在声明之前使用,就会报错。

    var temp=123;
    if(true){
     temp='abc';  //ReferenceError
     let temp;
    }

个人理解的封闭作用域就是暂时跟外部的作用域没有关联(在区域块中存在let或const),类似于一个独立的作用域;所以我们在if的块级作用域中使用没有声明的temp,就会报错;

  1. let不允许在相同的作用域内重复声明同一变量(因此,不能在函数内部重新声明参数),var没有限制。
    //报错
    function(){
     let a=10;
     var a=1;
    };
    //报错
    function(){
     let a=10;
     let a=1;
    };
    //报错
    function func(args){
     let arg;
    }//不报错,此时声明的变量已经跟上面的arg不在一个作用域下了
    functuon fun(arg){
     {
         let arg;
     }
    };

const

const 声明的是一个只读变量,一旦声明,常量的值就不可以改变。

const 实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址不得改动

  1. 对于简单数据类型(数值、字符串、布尔值),值就是保存在变量指向的内存地址中,因此等同于常量;
  2. 对于复合类型的数据(主要针对对象和数组),变量指向的内存地址保存的只是一个指针。const只能保证这个指针是固定的。
const foo={};
foo.prop=123; //为foo 添加一个属性,可以成功(内存地址没有改变)
foo={};  //将foo指向另一个对象,报错(此时内存地址改变了)

文章作者: Rabbit
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Rabbit !
 上一篇
关于ES6中的变量的解构赋值的介绍 关于ES6中的变量的解构赋值的介绍
(文章中介绍的都是个人观点,如有不准确的欢迎指出。但请勿喷,谢谢!) 在了解具体内容之前,我们应该带着以下问题来阅读文章。 什么叫做解构?(简单来讲就是从数组和对象中提取值) 解构赋值可以用在哪些数据结构上?(数组、对象、字符串-类似数组、
2020-03-15
下一篇 
vue自学 vue自学
路由起步 当需要把Vue Router添加进来的时候,我们需要做的就是组件映射到路由,然后告诉Vue router哪里渲染就行。 路由出口 <router-view></router-view>。 动态路由匹配co
2020-03-07
  目录