• es6---let和const


    在es6之前,只有全局作用域与函数作用,变量只能用var来声明。而es6中新增了块级作用域,变量可以用let、const来声明变量。

    内容概述

    •var和let const的区别

    •块级作用域与函数声明

    1、var和let const的区别

    1.1:let const声明的变量只在代码块作用域内有效,块作用域就是在大括号{}范围内有效;而var声明的变量在函数作用域或者全局作用域内有效,并没有块级作用域的概念。

    if (true) {
        let a = 1;
       console.log(a); // 1 } console.log(a);
    // ReferenceError: a is not defined,变量a只在if代码块内有效
     if (true) {
         var a = 1;
     }
     console.log(a); // 1
    var a = [];
    for(var i = 0 ;i < 10; i++) {
        a[i] = function () {
            console.log(i);
        }
    }
    a[6](); // 10,a[i]的值存的是一个函数对象,a[i]对应的函数在执行的时候,需要拿到i的值。而在这里,var声明的变量是一个全局变量,每次循环都会改变全局作用域中的i值,a[i]对应的函数执行的时候拿到的是同一个i值,当a[i]对应的函数执行的时候,循环已经执行完毕,i值已经变为10。
    var a = [];
    for(let i = 0 ;i < 10; i++) {
        a[i] = function () {
            console.log(i);
        }
    }
    a[6](); // 6,let声明的变量会绑定一个块级作用域,每次循环都会产生一个i值,且只在本轮循环中有效,js引擎会记住上轮循环的i值,下次循环的i值会使用上次循环的i进行初始化。

    1.2 :let和const声明的变量不存在变量提升,而var声明的变量存在变量提升。

    变量提升:就是在变量声明前可以访问变量,值为undefined。

    console.log(a); // undefined,var声明的变量会提升到全局作用域或者函数作用域的头部
    console.log(b); // ReferenceError,暂时性死区,{}代码块中存在let和const的变量的话,let和const声明的变量会绑定当前块作用域,不允许在变量声明之前使用
    typeof b; // ReferenceError,暂时性死区
    var a = 1;
    let a = 2; // SyntaxError: Identifier 'a' has already been declared,let和const不允许同一个作用域中重复声明变量
    let b = 2;

    1.3:const声明的是一个常量,不可以更改,否则报错。const命令的本质是保证变量指向的内存地址不可以改变,对于简单类型(Number,String,Boolean)而言,变量的值就是栈区中保存的值;对于对象而言,变量的值是栈区中保存的一个指向堆区的指针。

    补充堆栈数据结构:如下图;

     js中数据在堆栈中存储情况: 如下图;

    const a = 1;
    a = 2; // TypeError
    const obj = {
        name: 'es6',
        age: 5
    };
    const arr = [ 1, 2, 3];
    obj.age = 4 ;
    arr.push(4);
    console.log(obj); // {name: "es6", age: 4}
    console.log(arr); // (4) [1, 2, 3, 4]
    obj = {
        name: 'es5'
    }; // TypeError
    arr = ['a', 'b', 'c']; // TypeError

    2、块级作用域与函数声明

    首先,es5规定,函数只能在顶层作用域和函数作用域中声明,不能在块级作用域中声明。但是,浏览器并没有遵守这个规定,块级作用域中声明的函数实际上都能运行,并不会报错。在js中创建函数有函数声明和函数表达式两种方式,而函数声明存在函数提升,函数会被提升到所在作用域的头部位置。函数表达式不存在变量提升。

    foo(); // foo,函数声明提升
    bar(); // bar is not a function
    if(true) {
        function foo() {
            console.log('foo');
        }
        var bar = function () {
            console.log('bar');
        }
    }
    bar(); // bar
    
    // 实际运行代码如下:
    function foo() {
        console.log('foo');
    }
    var bar;
    foo(); // foo
    if(true) {
        bar = function () {
            console.log('bar');
        } 
    }
    bar(); // bar  

    在es6的浏览器环境中,块级作用内的函数声明类似于var,会被提升到所在的块级作用域的头部。es6的非浏览器环境中,块级作用域中函数声明当作let处理即可。下面是es6的浏览器环境中块级作用域中函数声明的例子:

    if(false) {
        function f() {
            console.log('foo');
        }
    }
    f(); // f is not a function
    
    // 实际运行的代码如下:
    var f;
    if(false) {
        function f() {
            console.log('foo');
        }
    }
    f(); // f is not a function 
  • 相关阅读:
    c# 泛型总结
    透过字节码分析java基本类型数组的内存分配方式。
    c#索引器
    redis在asp.net 中的应用
    Unity3D shaderLab
    Unity3d Asset Store 打不开
    C# 类型转换的开销
    [转]权重算法
    Coroutine的原理以及实现
    在Unity3D里使用WinForm
  • 原文地址:https://www.cnblogs.com/fairy-0518/p/12865618.html
Copyright © 2020-2023  润新知