zoukankan      html  css  js  c++  java
  • JavaScript 变量声明:var、let、const

    1. 概述

    1.1 说明

    在ES5 声明变量的方法:var命令和function命令。

    在ES6 声明变量的方法:var命令、function命令、let命令、const命令、import命令、class命令。

    以下内容主要是对 let 、var 、const 命令的理解与记录。

    1.2 let 命令

    1.2.1 let 说明

      let命令的声明变量用法类似于var,如 let a =10;(声明了一个变量:变量名为a,值为10)。但let所声明的变量,只在let命令所在的代码块内有效,即let用于声明一个块级作用域的变量。

      以下代码解析:在函数test中的if代码块中使用let进行声明变量;在if代码快中调用所声明变量可以获取正确的值,而在if代码块外调用所声明变量则会报错。

        function test() {
            if (true) {
                let x = 1;
                console.log(x); // 1
            }
            console.log(x); // Uncaught ReferenceError: x is not defined
        }
        test();

      for循环的计数器

        for (let x = 0; x < 5; x++) {
            setTimeout(function() {
                console.log(x); // 0 1 2 3 4
            }, 100);
        }
        console.log(x);// Uncaught ReferenceError: x is not defined

    1.2.1 let 特性

      详见 var 与 let 的对比。

    • 块级作用域
    • 不允许在相同作用域内,重复声明同一个变量
    • 暂时性死区

    1.3 var 命令

    1.3.1 var 说明

      使用var进行声明变量。var a =10;(声明了一个变量:变量名为a,值为10)。在ES6之前,JavaScript没有块级作用域,只有全局作用域和函数作用域。变量提升即是将变量声明提升到它所在作用域的最开始的部分。

       //全局作用域
        console.log(global); // undefined
        var global = 'global';
        console.log(global); // global
        //函数作用域
        function test () {
            console.log(x); // undefined
            var x = 1;
            console.log(x); // 1
        }
        test();// 调用函数

      以上代码中var声明的变量在不同作用域中进行了变量提升(在当前作用域下,在声明变量之前进行了调用,返回了变量值为undefined)。以上代码等同于以下代码:

        var global; // 变量提升,全局作用域范围内,此时只是声明,并没有赋值
        console.log(global); // undefined
        global = 'global'; // 此时才赋值
        console.log(global); // global
    
        function test () {
            var x; // 变量提升,函数作用域范围内
            console.log(x);// undefined
            x = 1;// 此时才赋值
            console.log(x);// 1
        }
        test();

      for循环的计数器

        for (var x = 0; x < 5; x++) {
            console.log(x); // 0 1 2 3 4
            setTimeout(function() {
                console.log(x); // 5 5 5 5 5
            }, 100);
        }
        console.log("***************");
        console.log(x);// 5

    1.3.2 省略 var

     在javascript中,若省略var关键字而直接赋值,那么这个变量为全局变量,哪怕是在function里定义的。

        function a() {
            x = 2;
        }
        function b() {
            console.log(x);// 2
        }
        a();
        b();

    1.4 let 与 var

    • 作用域的区别

        var : 没有块级作用域,因为变量提升的特性,其声明变量的作用域为整个函数或全局范围。

        let  :   拥有块级作用域的特性,其声明的变量作用域范围从声明处一直到当前块级语句({}包含)的结尾【或一直延伸到函数结尾(在函数内)或全局结尾】。

        function testVar() {
            if (true) {
                // 变量提升
                console.log(x); //  undefined
                var x = 1;
                console.log(x); // 1
            }
            // 作用域在整个函数作用域中
            console.log(x); // 1
        }
        function testLet() {
            if (true) {
                // 不存在变量提升
                console.log(y); //  Uncaught ReferenceError: y is not defined
                let y = 1;
                console.log(y); // 1
            }
            // 作用域仅在if语句块中
            console.log(y); // Uncaught ReferenceError: y is not defined
        }
        testVar();
        testLet();
    • 重复声明

        var : 允许在相同作用域内,重复声明同一个变量。

        let  :   不允许在相同作用域内,重复声明同一个变量。

        function test() {
            var x=1;
            var x=2;
            var x=3;
            console.log(x);//3
            let y=1;
            let y=2;
            console.log(y);//Uncaught SyntaxError: Identifier 'y' has already been declared
        }
        test();
    • 顶层对象的属性(window)

        var : 在全局作用域声明的变量,会作为widnow对象的成员。

        let  :   在全局作用域声明的变量,不会作为window对象的成员。

        var x = 1;
        let y = 1;
        //var声明的变量附加到window对象上
        console.log(window.x); // 1
        //let声明的变量没有附加到window对象上
        console.log(window.y); // undefined
    • 暂时性死区

        var : 不存在暂时性死区。

        let  :   存在暂时性死区【在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)】。

        var a = 123;
        if (true) {
            a = 'abc';
            console.log(a);// abc
            var a;
            console.log(a);// abc
        }
        var x = 123;
        if (true) {
            x = 'abc'; // Uncaught ReferenceError: x is not defined
            let x;
        }

      备注:ES6 明确规定,如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错

    1.5 const 命令

    1.5.1 const 说明

      使用const进行声明变量所定义的是一个只读的常量,一旦声明,常量的值就不能改变。const a =10;(声明了一个常量变量:变量名为a,值为10)。

        const x = 1;
        x = 2; // Uncaught TypeError: Assignment to constant variable

    1.5.2 const 特性

    • 块级作用域(与let命令相同)
    • 不允许在相同作用域内,重复声明同一个变量(与let命令相同)
    • 暂时性死区(与let命令相同)
    • 在全局作用域声明的变量,不会作为window对象的成员
    • 当用const声明的常量为值类型(e.g. String、Number)时,修改此常量的值会报错;但当声明的常量为引用类型(e.g. Array、Object)时,只可以修改此常量的成员
        // 1.const声明一个数组
        const x = [1, 2, 3];
        console.log(x); // => [1, 2, 3]
        x[0] = "a"; // 修改数组的第一个元素的值
        console.log(x); // ['a', 2, 3]
    
        // 2.const声明一个对象
        const obj = {};
        obj.name = 'objName';
        console.log(obj.name); // objName
  • 相关阅读:
    mysql连接error,Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection .....
    ng-model绑定的是ng-option中的什么?
    js的原型prototype究竟是什么?
    git给log设置别名来快速查看友好的log信息
    git常见使用场景总结
    $http设置headers来实现IE不缓存url请求的资源
    给sublime设置格式化代码的快捷键
    HTTP权威指南 ·
    《编写高质量代码:Web 前端开发修炼之道》 笔记与读后感
    怎么删除git本地分支以及Bitbucket的远程分支?
  • 原文地址:https://www.cnblogs.com/ajuan/p/10383477.html
Copyright © 2011-2022 走看看