JavaScript--变量的作用域 & varletconst详解

Posted Z && Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript--变量的作用域 & varletconst详解相关的知识,希望对你有一定的参考价值。

1. 什么是ES6?

ES的全称是ECMAScript ,它是由ECMA国际标准化组织,制定的一项脚本语言的标准化规范。其中的6代表这个规范的版本。
在这里插入图片描述

ES6实际上是一个泛指,泛指ES2015及后续的版本。

2 预备知识


2.1 变量的作用域

javascript中,用 var 申明的变量实际上是有作用域的。如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量:

    'use strict';

    function foo() {
        var x = 1;
        x = x + 1;
    }

    x = x + 2; // ReferenceError! 无法在函数体外引用变量x

如果两个不同的函数各自申明了同一个变量,那么该变量只在各自的函数体内起作用。换句话说,不同函数内部的同名变量互相独立,互不影响:

    'use strict';

    function foo() {
        var x = 1;
        x = x + 1;
    }

    function bar() {
        var x = 'A';
        x = x + 'B';
    }

由于JavaScript的函数可以嵌套,此时,内部函数可以访问外部函数定义的变量,反过来则不行:

在这里插入图片描述

如果内部函数和外部函数的变量名重名怎么办?来测试一下:

在这里插入图片描述


2.2 变量提升

在这里插入图片描述
在这里插入图片描述


2.3 全局作用域

在这里插入图片描述

进一步大胆地猜测,我们每次直接调用的 alert() 函数其实也是 window 的一个变量:

    'use strict';

    window.alert('调用window.alert()');
    // 把alert保存到另一个变量 注意不要加():
    var old_alert = window.alert;
    // 给alert赋一个新函数:
    window.alert = function () {
    };
    alert('无法用alert()显示了!');
    // 恢复alert:
    window.alert = old_alert;
    alert('又可以用alert()了!');

运行结果:

在这里插入图片描述
在这里插入图片描述

全局变量会绑定到 window 上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,并且很难被发现。减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中。例如:

在这里插入图片描述


2.4 局部作用域

由于JavaScript的变量作用域实际上是函数内部,我们在 for 循环等语句块中是无法定义具有局部作用域的变量的:

在这里插入图片描述
在这里插入图片描述


2.5 常量

在这里插入图片描述


3 let关键字

  • let声明的变量只在所处于的块级有效(所谓的块级作用域就是指的是一个大括号内的区域)
    if (true) {
      let a = 10;
    }
    console.log(a);// a is not defined.
    for (let i = 0; i < 100; i++) {// 括号1
      if (true) {// 括号2
        console.log(i);// 在这个大括号内部可以方位 i 因为 这里的输出语句仍在 括号1 里面
      }
    }

这个特性可以放在循环变量变为全局变量

  • let关键字声明的变量不存在变量提升
    console.log(a);
    let a = 100; // Cannot access 'a' before initialization

这个特性表明let关键字声明的变量必须先声明再去使用

  • let关键字声明的变量具有暂时性死区的特点
    var a = 10;
    if (true) {
      /* 因为下面用let定义了a 所以这个这里不能直接输出上面的 a
        而是转向下面去寻找a 这个特点被称为暂时性死区*/
      console.log(a);// Cannot access 'a' before initialization
      let a = 100;
    }
  • let关键字经典面试题
    下面这段代码的输出是什么:
    var arr = [];
    for (var i = 0; i < 2; i++) {// 这里是i用var关键字声明
      arr[i] = function () {
        console.log(i);
      };
    }
    arr[0]();// 2
    arr[1]();// 2

在这里插入图片描述
请看下面这段代码的输出又是什么:

    var arr = [];// 这里是i用let关键字声明
    for (let i = 0; i < 2; i++) {
      arr[i] = function () {
        console.log(i);
      };
    }
    arr[0]();
    arr[1]();

在这里插入图片描述


4 const关键字

作用:声明常量,常量就是值(内存地址)不能变化的量。

  • const关键字声明的常量具有块级作用域
    if (true) {
      const a = 100;
    }
    console.log(a);// a is not defined

请思考下列代码依次输出什么值?

    if (true) {
      const a = 100;
      if (true) {
        const a = 10;
        console.log(a);// 10
      }
      console.log(a);// 100
    }
    console.log(a);// a is not defined
  • const关键字声明的常量必须赋予初始值
      const a;
      console.log(a);// Missing initializer in const declaration
  • const关键字声明的常量值不能更改
    1.普通数据类型的值,值不能更改
    const PI = 3.1415926;
    PI = 100;
    console.log(PI);// Assignment to constant variable

引用数据类型的值,内存地址不能更改

    const ary = [100, 200];
    ary[0] = "a ";
    ary[1] = "b ";
    console.log(ary);
    // 这里更改了数组在内存里面的地址
    ary = ["a ", "b "]; // Assignment to constant variable.

5 let,var,const关键字的区别

  • 1.使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象。
  • 2.使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升。
  • 3.使用const声明的是常量,在后面出现的代码中不能再修改该常量的值,常用来声明函数等。
    在这里插入图片描述


以上是关于JavaScript--变量的作用域 & varletconst详解的主要内容,如果未能解决你的问题,请参考以下文章

javaScript定义函数的三种方式&amp;变量的作用域

JavaScript 作用域

自学JavaScript 变量-作用域

JavaScript作用域

JavaScript 作用域作用域链变量提升

JavaScript 作用域作用域链变量提升