• 【JavaScript】this指向经典面试题(超详细)


    在这里插入图片描述

    文章目录

    ??前言

    本篇文章主要写的是【JS中this指向面试题(超详细代码解读)】,面试遇到的经典问题不少,所以本文总结一写常见的分享给各位。
    只要我们掌握了this的四个绑定规则,仔细的去慢慢分析一定没有问题。接下来为大家展示四个经典的面试题。

    面试题参考文章:

    【面试专栏】—— 点击链接即可订阅面试专栏

    由于先写代码然后再在代码块下面进行分析解释,怕xdm找不到对应的句子,所以直接就在代码块中,相应的句子后面给出了分析解释。下面的四个案例皆是如此,望见谅。

    面试题一:

    这道面试题非常简单,无非就是绕一下,希望把面试者绕晕:

    var name = 'window'
    // var name = 'window' 表示在window中name的值为 ’window‘
    
    var person = {
        name: 'person',
        sayName: function () {
            console.log(this.name)
        }
    }
    
    function sayName () {
        var sss = person.sayName;
    
        sss();// window  独立调用指向全局对象window
    
        person.sayName(); // person  隐式调用
    
        (person.sayName)(); // person  和上一句效果一样(person.sayName) 带小括号不带小括号没区别
    
        (b = person.sayName)() // window  间接引用 ,(b = person.sayName)的结果是一个值,并没有和person对象有联系,所以后面加一个()进行调用的时候,还是属于默认绑定(直接调用),this指向全局对象
    }
    
    sayName()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    面试题二:

    这道面试题比上一道更加绕一些,在对象内部进行了函数的声明:

    var name = 'window'
    
    var person1 = {
        name: 'person1',
    
        foo1: function () {
            console.log(this.name)
        },
    
        foo2: () => {
            console.log(this.name)
        },
    
        foo3: function () {
            return function () {
                console.log(this.name)
            }
        },
    
        foo4: function () {
            return () => {
                console.log(this.name)
            }
        }
    }
    
    var person2 = { name: 'person2' }
    
    // 正题来咯
    
    person1.foo1(); // person1 (隐式绑定)
    person1.foo1.call(person2); // person2 (call显示绑定person2,显示绑定优先级大于隐式绑定)
    
    person1.foo2(); // window (箭头函数不绑定作用域,找到上层作用域为全局window)
    person1.foo2.call(person2);// window (箭头函数没有this,call()无效)
    
    person1.foo3()(); // window (person1.foo3()得到一个return的函数,再加上一个小括号属于独立调用指向全局对象window)
    person1.foo3.call(person2)(); // window (person1.foo3.call(person2)这句话得到返回值后,后面加小括号调用,还是属于独立调用 指向window) 
    person1.foo3().call(person2);// person2 (最终调用return函数时,显示绑定上了person2)
    
    person1.foo4()();// person1 (person1.foo4()这句话得到return后的函数为箭头函数进行调用,箭头函数中没有this向上一层作用域找,上层作用域为foo4,this指向person1)
    person1.foo4.call(person2)();// person2 (上层作用域被显示绑定为person2 ,在箭头函数中找不到this后,向上层所用域找 就找到了之前被显示绑定的person2)
    person1.foo4().call(person2);// person1 (person1.foo4()这句话得到return后的函数为箭头函数进行显示绑定person2,但箭头函数中没有this,显示绑定无效,向上一层作用域找,找到函数foo4,this指向person1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    面试题三:

    第三题就更加绕了,学过构造函数的小伙伴应该不难看懂,没学过的也可以去学习一下:

    var name = 'window'
    
    function Person (name) {
        this.name = name
        this.foo1 = function () {
            console.log(this.name)
        }
    
        this.foo2 = () => console.log(this.name)
    
        this.foo3 = function () {
            return function () {
                console.log(this.name)
            }
        }
    
        this.foo4 = function () {
            return () => { console.log(this.name) }
        }
    }
    
    var person1 = new Person('person1')
    var person2 = new Person('person2')
    
    
    person1.foo1() // person1  (隐式绑定)
    person1.foo1.call(person2) // person2 (显示绑定person2,显示绑定优先级高于person1.foo1的隐式绑定)
    
    person1.foo2() // person1  (上层作用域中的this是person1函数)
    person1.foo2.call(person2) // person1 (显示绑定在箭头函数中无效,所以结果还是上层作用域中的this是person1函数)
    
    person1.foo3()() // window (person1.foo3()得到返回函数 加小括号进行直接调用 this指向全局作用域window)
    person1.foo3.call(person2)() // window (person1.foo3.call(person2)得到返回函数后,独立函数调用指向全局)
    person1.foo3().call(person2) // person2 (person1.foo3()得到返回函数后,显示绑定person2)
    
    person1.foo4()() // person1 (箭头函数中没有this,向上一层作用域找 this指向person1)
    person1.foo4.call(person2)() // person2 (person1.foo4.call(person2)显示绑定person2,得到返回的箭头函数后,向上一层作用域找,this指向person2)
    person1.foo4().call(person2) // person1 (person1.foo4()得到返回箭头函数显示绑定person2无效,向上一层作用域找,this指向person1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    面试题四:

    var name = 'window'
    
    function Person (name) {
        this.name = name
        this.obj = {
            name: 'obj',
            // 此时foo1,foo2的上层作用域为obj对象
            foo1: function () {
                return function () {
                    console.log(this.name)
                }
            },
            foo2: function () {
                return () => {
                    console.log(this.name)
                }
            }
        }
    
    }
    
    var person1 = new Person('person1')
    var person2 = new Person('person2')
    
    
    person1.obj.foo1()() // window  (person1.obj.foo1()得到返回函数后直接调用,this指向全局对象)
    person1.obj.foo1.call(person2)() // window (还是直接调用,this指向全局对象)
    person1.obj.foo1().call(person2) // person2 (person1.obj.foo1()这句话得到返回函数后,使用显示调用绑定person2,this指向person2)
    
    person1.obj.foo2()() // obj (person1.obj.foo2()这句话得到返回函数后调用,但是箭头函数没有this,向上一层作用域找,上一层作用域为foo2函数,foo2是被obj对象调用的,所以this指向obj对象)
    person1.obj.foo2.call(person2)() // person2 (person1.obj.foo2.call(person2)将foo2的上层作用域指向了person2,再进行调用的时候,上一层作用域就是person2)
    person1.obj.foo2().call(person2) // obj (person1.obj.foo2()的到返回函数,使用显示绑定call无效,上一层作用域为foo2函数,foo2是被obj对象调用的,所以this指向obj对象)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    这里可能产生一点有疑问的地方,首先说明在对象中是没有作用域的,person1.obj.foo2()() 这句,按照之前的理解,person1.obj.foo2()这句话得到返回函数后调用,但是箭头函数没有this,向上一层作用域找,因为obj对象是没有作用域的,按道理来讲this应该指向person1,但是foo2函数是被obj对象隐式绑定进行调用的,所以会指向obj对象。


    不了解this的四种绑定规则或者this的指向问题的小伙伴,可以参考【JavaScript】this关键字的指向问题(五千字详解)JavaScript中this四种绑定规则优先级比较与箭头函数中的this获取,有详细进行描述与举例说明。

    ??专栏分享:

    JavaScript相关面试题就更新到这里啦,相关 Web前端面试题 可以订阅专栏哦??
    专栏地址:《面试必看》


    名言警句:说能做的做说过的 extcolor{red} {名言警句:说能做的做说过的} 名言警句:说能做的做说过的

    原创不易,还希望各位大佬支持一下 extcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下

    ?? 点赞,你的认可是我创作的动力! extcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!

    收藏,你的青睐是我努力的方向! extcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!

    评论,你的意见是我进步的财富! extcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    Python使用CV2库捕获、播放和保存摄像头视频
    Vue之html中特殊符号的展示
    云栖大会“云计算加速开源创新论坛” 揭晓 2022 年度开源人物
    【数据结构】二叉树的层序遍历~动画超详解
    SpringMVC中文乱码(request或response)前后端处理
    Java概述
    设计模式——访问者模式(Visitor Pattern)+ Spring相关源码
    如何在移动钱包中搭建一个小程序应用商店
    [附源码]SSM计算机毕业设计学生互评的在线作业管理系统JAVA
    构建快速、安全、可扩展的静态站点:终极指南
  • 原文地址:https://blog.csdn.net/m0_67401660/article/details/126080579