zoukankan      html  css  js  c++  java
  • es6 新增变量声明方式

    let 与 var

    var

    var声明的变量拥有全局作用域或者局部作用域

    在全局中声明变量即为全局变量
    
    在函数中声明变量即为局部变量
    

    而var在使用过程中也逐渐暴露出许多问题

    var的几大问题

    变量提升

    使用var来声明变量会出现变量提升的问题,即在声明变量之前就调用变量

    console.log(info);//undefined
    
    var info = 10;
    

    出现上面情况其实是非常不好的,因为在声明之前使用的话应该去报出一个错误而不是用一个undefined给这个变量赋值。

    这个问题在函数中尤为明显

    var info = 10;
    
    function fn1(){
        console.log(info);//undefined
        var info = 20;
    }
    
    fn1();
    

    在循环中的问题

    var在循环中的问题也是相当严重

    下面我遇到的一个情况

    //html中有四个span
    var oSpan = document.getElementsByTagName('span');
    for(var i = 0 ; i < oSpan.length ; i++ ){
        oSpan[i].onclick = function(){
            console.log(this);//点击出现 你点的那个span
        }
    }
    

    我们发现在这时是可以获得点击的元素的

    但是我们把this换成oSpan[i]时就会出问题

    for(var i = 0 ; i < oSpan.length ; i++ ){
        oSpan[i].onclick = function(){
            console.log(oSpan[i]);//点击出现 undefined
            console.log(i);//点什么都是4
        }
    }
    

    我们这个时候会发现我们已经选取不到事件处理函数中i的瞬时值了。而这又是因为什么呢

    我们可以把代码拆开

    //拆开for
    var i = 0;
    oSpan[i].onclick = function(){
        console.log(i);
    }
    var i = 1;
    oSpan[i].onclick = function(){
        console.log(i);
    }
    ...
    var i = 3;
    oSpan[i].onclick = function(){
        console.log(i);
    }
    var i = 4;
    
    //在你点击的时候是在页面加载完才调用的函数
    

    上面的会看出来由于var声明的变量是全局变量,所以函数中的变量接收是4

    解决办法是在循环中写一个闭包函数,模拟一个块级作用域

    for(var i = 0 ; i < 4 ; i++){
        oSpan[i].onclick = function(arg){
            return function(){
                console.log(arg);//出现 0,1,2,3
            }
        }(i);
    }
    

    然而es6给我们提供了更好的声明变量的方式

    let

    在es6中,let声明的变量是块级作用域

    块级作用域是指在{}中间可以有效使用

    for(let i = 0; i < 4 ; i++){
        oSpan[i].onclick = function(){
            console.log(i);
        }
    }
    

    上面的就可以找到i的瞬时值原因是每个i与下面的都是同一块作用域,而与另几个循环中的函数互不影响。所以每个函数调用的都是与其同一块作用域的i值。

    let其他作用

    在let声明的变量不可重复声明否者会报错

    let b = 10;
    
    let b = 20;//报错
    

    let不会有变量提升这个问题,let会产生暂时性死区

    console.log(a);//报错
    
    let a = 20;
    

    顶层对象的属性

    在浏览器的顶层对象是window,在Node环境中是global

    在es5中顶层的属性与全局变量是等价

    window.a = 1;
    a = 2;
    console.log(window.a)//2
    

    由于顶层对象的属性与全局变量相关,就会产生许多问题

    1. 无法再编译时就提示变量未声明的错误,只有运行在会知道

    2. 容易不知不觉的就创建出全局变量,导致顶层对象的属性到处都可以读写,这非常不利于模块化编程

    3. window对象有实体含义,指的是浏览器窗口对象,这样也是不合适的

    但是let声明的变量不属于顶层对象的属性

    var a = 1;
    
    console.log(this.a);//1
    
    let b = 1;
    
    console.log(this.b);//undefined
    

    const

    const也是es6的声明方式之一

    const声明的变量大多数是做为一个常量,而作为常量时不可对值进行修改,变成只读模式

    
    const INFO = 10;
    
    INFO = 20; //报错
    
    const INFO = 20;//报错
    

    而当const声明的是一个引用数据类型的时候,引用类型内的值是可以修改的,因为引用类型的值存放在堆中的。修改操作是在堆中进行,而变量储存的是地址,不会被修改,而地址指向的数据已经发生改变,故而const声明的变量的值被修改了

    const arr = [1,2,3,4];
    
    arr.push(5);
    
    console.log(arr);//[1,2,3,4,5]
    
  • 相关阅读:
    在Xampp中添加memache扩展
    使用PHP中的curl发送请求
    php开启openssl扩展
    chisel初见2
    chisel初见
    数字IC设计之DC(二):DC设置、库和对象
    数字IC设计之DC(一):DC简介
    IC基础(八):数字电路设计中常用的算法
    IC基础(七):FPGA为什么与ASIC频率差异巨大?
    IC基础(六):时序分析过程需要的相关计算以及处理方法
  • 原文地址:https://www.cnblogs.com/strongtyf/p/11981396.html
Copyright © 2011-2022 走看看