美文网首页饥人谷技术博客
一道关于this的面试题

一道关于this的面试题

作者: 大春春 | 来源:发表于2017-02-27 22:26 被阅读0次

    最近一段时间学习了一下JS原型相关的知识,其中一个重要的点是关于this关键字的值究竟是什么?讲真,在此之前,虽然我也有用过this这个关键字,但是关于它的值到底是什么一直都没有很明确的一个知识点,有点像靠猜来达成目的的。所以今天写一篇博客来做几个关于this的面试题巩固一下知识,如果中间有错误,希望大家能在评论区指出。

    题目一:名字是什么?

    var a = {
        name:"zhang",
        sayName:function(){
            console.log("this.name="+this.name);
        }
    };
    var name = "ling";
    function sayName(){
        var sss = a.sayName;
        sss(); //this.name = ?
        a.sayName(); //this.name = ?
        (a.sayName)(); //this.name = ?
        (b = a.sayName)();//this.name = ?
    }
    sayName();
    

    输出结果如下:

    分析:
    1.在全局变量中执行函数sayName,先是var sss = a.sayName,相当于sss = function(){console.log(this.name)},然后执行sss(),这时候调用sss()函数就已经不是a.sayName了,而是window环境下的sayName函数,拿到的this的值自然就是"ling";
    2.然后执行a.sayName(),这个a.sayName函数中的this指向的是对象a,所以拿到的也是对象a中的属性name的值;
    3.执行(a.sayName)(),这一条代码中,可以等价于a.sayName(),括号的作用只是包裹了a.sayName,然后执行它,a.sayName中的this依旧指向的是对象a,所以拿到的还是对象a中的name的值;
    4.执行(b = a.sayName)(),这一条代码中,首先执行了b = a.sayName这个赋值操作,然后执行b(),和第一条的执行sss()没有什么区别,所以拿到的this也是全局变量name;


    题目二:名字是什么?(变形一)

    var name = "ling";
    function sayName(){
        var a = {
            name:"zhang",
            sayName:getName
        };
         
        function getName(){
            console.log(this.name);
        }
         
        getName(); //this.name = ?
        a.sayName(); //this.name = ?
        getName.call(a);//this.name = ?
    }
    sayName();
    

    首先来看执行结果:


    分析:
    1.当执全局上下文中的函数sayName时,其实就是执行了该函数内的getName(); a.sayName();getName.call(a);这三个函数,其中第一个getName();因为是直接在全局上下文中进行的调用,所以该函数内的this指向window,this.name指向window.name的值;
    2.执行a.sayName();时就不一样了,因为a.sayName是在对象a的上下文中,这时候对象a中的属性sayName中的值getName函数的执行上下文就切换到了对象a上,所以这时候的this.name指向a.name;
    3.执行getName.call(a),这条代码中,加入了call关键字,而call的作用是切换函数的执行上下文(也就是动态改变this的值),而第一个参数是a,相当于把getName函数绑定到a对象中去,这时候的this指向的就是对象a;


    题目三:名字是什么?(变形二)

    var name = "ling";
    var obj = {
        name:"zhang",
        sayName:function(){
            console.log("this.name="+this.name);
        },
        callback:function(){
            var that = this;
            return function(){
                var sayName = that.sayName;
                that.sayName(); //this.name = ?
                sayName();//this.name = ?
            }
        }
    }
    obj.callback()()
    

    执行结果:


    分析:
    1.当执行obj.callback()()时,中介是分了两个阶段的,第一阶段执行了obj.callback(),在这一步执行了var that = this;,这时候的callback函数还是处于对象obj的上下文中,所以这时候的this指向obj,所以that === obj,然后返回一个函数出来;
    2.现在来到第二阶段,执行obj.callback()返回出来的函数,在这个函数中,首先执行出结果的是that.sayName();,而在第一阶段中,that指向的是obj,相当于执行obj.sayName(),得出的结果自然是"zhang";
    3.然后有var sayName = that.sayName;这句话,相当于sayName = function(){console.log(this.name)},然后执行这个sayName(),这时候就要回头看obj.callback()返回出来的这个函数是在哪里进行调用的了,答案是在window中进行调用的,所以在这个函数中的this指向的是window,所以这时候执行sayName()
    得到的答案是全局变量name的值"ling"

    以上是基于我个人的理解,大家如果看出了什么错误,欢迎在评论区提出。

    相关文章

      网友评论

        本文标题:一道关于this的面试题

        本文链接:https://www.haomeiwen.com/subject/fncvwttx.html