• javascript 作用域、预解析、变量提升


    javascript 作用域与预解析

    函数的 arguments 对象:

    当一个函数不确定传入的行参数量时,可以使用 arguments 这个函数内置的对象来获取到所有的传入参数。arguments 是一个类似数组的集合类型数据结构(伪数组)。所有函数都内置一个arguments 对象,这个对象存储了所有的函数实参。

    作用域

    全局作用域:

    在整个script标签或js文件都生效。

    局部作用域:

    函数内部声明的变量是局部作用域。如果在函数内部没有声明变量直接使用,那么变量存在隐式声明,隐式声明的变量是全局变量。

    执行效率:

    • 全局变量只有浏览器关闭才销毁,比较占用内存资源。
    • 局部变量程序执行完就会销毁,更节约资源。

    块级作用域:

    被 {} 包裹 使用 let cont 声明的变量就是块级作用域。 (ES6)

    作用域链:

    代码在执行时,会先在当前作用域查找变量如果没有找到会从上级作用查找,层层查找直到最外层的全局作用域。

    预解析

    预解析就是JS引擎会把变量和函数声明放到当前作用域最前面,变量只声明不赋值。

    var a = 10
    fn()
    function fn(){
       console.log('打印', a )
        var a = 20
        console.log('打印', a)
    }
    // 打印 undefined
    // 打印 20
    // 在全局作用域a变量被提升,在fn函数的局部作用域a变量也被提升,此时的fn函数中的a变量只有申明没有值, 第二次打印fn函数中的a已经被赋值,所以打印的结果是20
    
    function fn(){
        var a = b = c = 5
        console.log('打印', a, b, c)
    }
    fn()
    console.log('打印',  b, c)
    // 打印 5 5 5
    //  a is not defined
    
    // 这里使用了多个等号赋值实际等同于 var a = 5  b = 5 c = 5
    // 只有a变量声明了,而b和c没有声明直接赋值,没有声明的变量会被隐式声明为了全局变量。
    // 因此第一次打印 a、b、c的值都是5
    // 在函数下面打印的 a 由于没有声明会报错,如果去掉a再打印 b、c都是5
    
    var a = 5
    function a(){
        return 6
    }
    console.log('打印', a )
    // 打印 5
    // 变量a和函数a都声明并赋值了,由于函数比变量的提升优先级高一些,函数a先提升,变量a后提升,变量a赋值的时候覆盖了函数a,因此打印为 5
    
    function a(){
        return 6
    }
    var a = 5
    console.log('打印', a )
    // 打印 5
    // 与上面一个例子相同,函数a预解析提升之后比变量a考前,变量a在后覆盖了函数a
    
    console.log('打印', a )
    function a(){
        return 6
    }
    var a = 5
    // 打印 [Function: a]
    // 在申明和赋值之前打印,函数a和变量a都提升,此时函数a靠前,而变量a此时还没有赋值,因此打印 为 [Function: a]
    
    console.log('打印', a )
    var a = 5
    function a(){
        return 6
    }
    // 打印 [Function: a]
    // 上面案例相同
    
    var a = 5
    console.log('打印', a )
    function a(){
        return 6
    }
    // 打印 5
    // 函数a和变量a都提升到了最前,此时a被赋值为5,覆盖了预解析时的值,因此打印为5
    
    var a = 5
    function a(){
        return 6
    }
    console.log('打印', a )
    // 打印 5
    function a(){
        return 6
    }
    var a = 5
    console.log('打印', a )
    // 打印 5
    不管函数a声明在前还是在后,由于预解析后都比变量a提升的更靠前一些,a变量靠后赋值时覆盖了函数a的值因此都打印为5
    
  • 相关阅读:
    spring事务注解@Transactional注解失效场景
    Dubbo中服务消费者和服务提供者之间的请求和响应过程
    说说Java的Unsafe类
    java程序二叉树的深度优先和广度优先遍历
    重复注解与类型注解
    git pull 和 git fetch的区别?
    Java8新特性系列(Interface)
    二十种健康食品排行榜
    赞美的时机
    越过胆怯这道栅栏
  • 原文地址:https://www.cnblogs.com/liea/p/12511002.html
Copyright © 2020-2023  润新知