• 【面试题】作用域和闭包


    1. 作用域

    作用域是指变量的合法使用范围
    例如下图中,函数fn3内定义的变量a3,无法在函数fn3以外的区域使用。
    在这里插入图片描述
    作用域分为全局作用域,函数作用域,块级作用域(ES6新增

    • 全局作用域:变量没有受到函数的约束,在全局中都可以使用,例如图中的变量a
    • 函数作用域:在函数中定义的变量,只能在当前函数中使用。
    • 块级作用域:if、while、for等大括号{}内的区域称为块级作用域。
      在这里插入图片描述

    2. 自由变量

    自由变量是指一个变量在当前作用域没有定义,但是被使用了。当前作用域中没有该变量,会向上级作用域,一层一层依次寻找,直到找到为止。

    如果向上寻找一直找到全局作用域都没找到,则会报错xxx is not defined
    在这里插入图片描述

    3. 闭包

    闭包是作用域应用的特殊情况,有两种表现:函数作为返回值函数作为参数被传递
    闭包的影响:闭包中的变量,在闭包执行结束后,依然留存在内存中,得不到释放。会影响性能。

    所有自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方进行查找。

    • 函数作为返回值
    function create(){
        const a = 100
        return function(){
            console.log(a)
        }
    }
    
    const fn = create()
    const a = 200
    fn()   // 函数的执行结果为 100
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 函数作为参数被传递
    function print(fn){
        const a = 200
        fn()
    }
    
    const a = 100
    function fn(){
        console.log(a)
    }
    
    print(fn)   // 打印的结果是 100
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4. this指向

    在 JavaScript 中,this 关键字用于引用当前正在执行的函数所属的对象。this取什么值,是在函数执行的时候确定的,不是在函数定义的时候确定的。

    场景1:普通函数的this指向

    function fn1(){
        console.log(this)
    }
    fn1()
    
    • 1
    • 2
    • 3
    • 4

    普通函数的this指向Window
    在这里插入图片描述

    场景2:使用call apply bind调用

    function fn1(){
        console.log(this)
    }
    fn1()
    
    fn1.call({x: 100})
    
    const fn2 = fn1.bind({x: 200})
    fn2()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    this指向call、apply、bind中传入的对象。call和apply调用函数会直接返回结果,但是bind不会直接返回结果,需要将返回值赋给一个新的函数,再执行该函数。
    在这里插入图片描述

    场景3:作为对象的方法被调用

    const zhangsan = {
        name: '张三',
        sayHi(){
            console.log(this)
        },
        wait(){
            setTimeout(function(){
                console.log(this)
            })
        },
        waitAgain(){
            setTimeout(()=>{
                console.log(this)
            })
        }
    }
    zhangsan.sayHi()    // this指向当前对象
    zhangsan.wait()     // this指向 window
    zhangsan.waitAgain()  // this指向当前对象 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述
    箭头函数的this不是在函数运行时确定的,是在函数定义时确定的,箭头函数没有自己的this,它们继承父级作用域中的 this。

    场景4:在class方法中被调用

    class People{
        constructor(name){
            this.name = name
            this.age = 20
        }
        sayHi(){
            console.log(this)
        }
    }
    
    const lisi = new People('李四')
    lisi.sayHi()    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    5. 实际开发中闭包的应用

    5.1 隐藏数据

    实现一个简单的cache工具。
    下面代码,无法直接修改data中的数据,需要调用set和get方法才能修改,因为data的作用域在函数内,因此可以隐藏data的数据。

    function createCache(){
        const data = {}      // 闭包中的数据,被隐藏,不被外界访问
        return {
            set: function(key, val){
                data[key] = val
            },
            get:function(key){
                return data[key]
            }
        }
    }
    
    const c = createCache()
    c.set('a', 100)
    console.log(c.get('a'))    // 100
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    5.2 点击标签跳出相应数字

    // 创建 10 个 '' 标签,点击的时候弹出来对应的序号
    let a
    for(let i = 0; i < 10; i++){
        a = document.createElement('a')
        a.innerHTML = i + '
    '
    a.addEventListener('click', function(e){ e.preventDefault() alert(i) }) document.body.appendChild(a) }

    在这里插入图片描述

  • 相关阅读:
    无密码解锁iPhone
    图像处理神经网络是什么,图像处理神经网络模型
    一、CSS浮动
    ChatGPT调教指南 | 咒语指南 | Prompts提示词教程(三)
    【集成学习】对已训练好的模型进行投票
    AndroidX使用Paho MQTT报找不到android/support/v4/content/LocalBroadcastManager
    ZYNQ之FPGA学习----RAM IP核使用实验
    【JVM笔记】Serial回收器:串行回收
    git 常用命令
    解决WordPress升级后提示:无需升级,您的WordPress数据库已经是最新的了
  • 原文地址:https://blog.csdn.net/zx1041561837/article/details/128010939