• js 中的变量声明提前总结


    一、var 声明

    ES6之前,js 中声明变量基本上用 var 关键字;

    1、如果访问未声明的变量,会报错:ReferenceError

    image

    2、声明了未赋值,值为 undefined,跟前面的报错是两回事,虽然信息看起来像;

    image

    3、对于没有声明的变量可以直接赋值,不过这是一个非常不好的习惯;

    image

    而用 var 声明的全局变量,作为全局对象的属性,是不可配置的;

    4、重复声明等价于赋值语句;

    image

    JavaScript从来不会告诉你是否多次声明了同一个变量;遇到这种情况,它只会对后续的声明视而不见(不过,它会执行后续声明中的变量初始化)。

    5、声明提前(hoisting)

    由于变量声明(以及其他声明)总是在任意代码执行之前处理的,所以在代码中的任意位置声明变量总是等效于在代码开头声明。这意味着变量可以在声明之前使用,这个行为叫做“hoisting”。“hoisting”就像是把所有的变量声明移动到函数或者全局代码的开头位置,但是 var 的赋值操作保留在原处。

    image

    声明原理:var 声明在代码执行之前,被提升到所在函数或全局环境的顶部,仅仅是声明提前,不涉及赋值操作;

    总结:

      在 var 声明的函数或全局环境访问:在赋值操作之前访问,返回 undefined,不报错;在赋值操作之后访问,返回实际值,不报错;

      在 var 声明的函数或全局环境访问,报错,除非闭包; 

    举例:

    image

    实际上等价于:

    image

    更多例子:戳 MDN

    二、let,const 声明

    书上说没有声明提前,这样理解也没有问题,所以直接看 三 吧;

    但是我的总结是可能有声明提前:

      1、在声明的函数或全局环境访问:

        在声明的代码块之访问:声明的位置之前访问(即使是使用 typeof),会报错(官方称”暂时性死区”);声明的位置之后访问,返回实际值;

        在声明的代码块之访问:报错(但使用 typeof 操作符不报错,返回不正确,可能为 undefined,与上述相比,证明了可能有声明提前);

      2、在声明的函数或全局环境访问,报错,除非闭包;

      证明可能有声明提前的代码:

    function f() {
        console.log(typeof a);
        if (true) {
            let a = 0;
        }
    }
    f();//undefined

      下面代码报错:

    function f() {    
        if (true) {
            console.log(typeof a);
            let a = 0;
        }
    }
    f();//ReferenceError: a is not defined

      下面不报错:

    function f() {    
        if (true) {
            console.log(typeof b);
            let a = 0;
        }
    }
    f();//undefined

    三、函数声明语句(不是函数表达式)

    声明提前原理:函数声明语句在代码执行之前,被提升到所在函数或全局环境的顶部;

    总结:

      在声明的函数或全局环境访问:都返回实际值;

      在声明的函数或全局环境访问,报错,除非闭包;

    实际上是跟 var 一样声明提升了,不同的是:函数整体提升,不仅仅是声明提升,而且没有块级绑定(ES6 严格模式下会有);

    参考资料:

    JavaScript权威指南-第6版

    JavaScript高级程序设计-第3版

    深入理解ES6-中

  • 相关阅读:
    数据库主键策略
    经历alidns在国外的严重延时
    无题 MVC
    Jquery操作select,左右移动,双击移动 取到所有option的值
    Computop支付网关(一) credit Card
    [转载] 测试的道理
    微信砍价活动总结
    transform,变换
    transition,过渡效果
    文字居底方法
  • 原文地址:https://www.cnblogs.com/xianshenglu/p/8110316.html
Copyright © 2020-2023  润新知