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
  • 相关阅读:
    leetcode--Populating Next Right Pointers in Each Node II
    leetcode—Populating Next Right Pointers in Each Node
    Pascal's Triangle II
    leetcode—pascal triangle
    leetcode—triangle
    October 23rd, 2017 Week 43rd Monday
    October 22nd, 2017 Week 43rd Sunday
    October 21st 2017 Week 42nd Saturday
    October 20th 2017 Week 42nd Friday
    October 19th 2017 Week 42nd Thursday
  • 原文地址:https://www.cnblogs.com/ajuan/p/10383477.html
Copyright © 2011-2022 走看看