一道关于this的面试题

最近一段时间学习了一下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"

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,764评论 18 399
  • 指向调用函数的那个对象,是函数运行时内部自动生成的一个内部对象,只能在函数内部使用 使用场景 单纯的函数调用thi...
    skoll阅读 524评论 0 1
  • 前言 JavaScript中this变量是一个令人难以摸清的关键字,当初学习javascript的时候被这个thi...
    车大棒阅读 460评论 3 4
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,827评论 2 17
  • 觉得本人写的不算很烂的话,可以登录关注一下我的GitHub博客,新手写东西写的不好之处,还望见谅,毕竟水平有限,写...
    微醺岁月阅读 1,168评论 10 9