面试系列-面试官:你能给我解释一下javascript中的this吗?
作者:小土豆biubiubiu
掘金:https://juejin.im/user/58c61b4361ff4b005d9e894d
简书:https://www.jianshu.com/u/cb1c3884e6d5
微信公众号:土豆妈的碎碎念(扫码关注,一起吸猫,一起听故事,一起学习前端技术)
码字不易,点赞鼓励哟~
一.前言
关于javascript中的this对象,可能已经被大家说烂了。
即使是这样,我依然决定将这篇文章给水出来。毕竟全国在新型肺炎的影响下,公司没法正常复工。
除了刷刷手机,还是要适当的学习一下。
废柴是真不好当,劳逸结合才是王道。
二.正戏开始
面试官:你能给我解释一下javascript中的this吗
我:(当然可以哇,胸有成竹,咳咳)javascript中的this对象是指函数运行时,在函数内部生成的一个对象。
面试官:那你大概说一下它的用法吧
我:(摩拳擦掌准备开始吹水)好,我大概说几种使用场景。(接下来就需要我一个人演戏了)
第一种是全局函数中的this对象。
比如下面这个全局函数test
<script>
function test(){
}
</script>
假如我们将这个全局函数作为普通函数使用,那么这个全局函数内部的this对象指向的就是window对象。
(事实胜于雄辩,虽然不能给面试官看结果,但是气势上已经拿到一分)
除了作为普通函数使用之外,test全局函数也可以作为构造函数去使用,那么函数内部的this对象指向的是构造函数创建出来的实例。
在test构造函数中,this.a=10这行是关键代码。
假设我们在不知道this对象是什么的情况下,这行代码仅仅是给this对象添加了一个属性a,并且赋值为10 。
然后看测试结果打印出来的对象o,发现o也多了一个属性a,它的值也为10 。
所以不难想到在test函数运行时,this绑定到了new出来的对象上,即this指向了构造函数创建出来的实例o;
第一种this的使用场景就吹完了,如果这样啰嗦的回答面试官,估计就直接让我回家了。
所以总结一下我这样回答面试官:
第一种全局函数中的this对象,假如我们将这个全局函数作为普通函数使用,那么这个全局函数内部的this对象指向的就是window对象;
如果将这个全局函数作为构造函数使用,那么函数内部的this对象指向的是构造函数创建出来的实例。
第二种是对象方法中的this。
在比如下面这个obj对象的increase方法。
var obj = {
a: 10,
increase: function(){
this.a++;
}
}
现在我们去调用obj对象的increase方法
obj的increase方法中的关键代码为this.a++,该函数调用完成后,在去打印obj对象,发现obj对象中a的属性值由10增加为11。
那么increase方法这中的this.a++的效果实际上等效于obj.a++。
所以对于第二种对象方法中的this,它指向的就是该对象本身。
那么到这里,我已经我的能力范围内回答完了面试官的问题。
(如果幸运的话,面试官应该还不会赶我走)
面试官:说了这么多,那我这里有几个实例代码,你来给我分别说一下这几个示例代码输出都是什么吧。
(接着面试官扔给我几张写满了代码的A4纸)。
我:(突然心慌慌,但是不能怂,按照前面说的几种场景往里套呗)
题目一:
(看到这个心情愉快呀,这不就是我刚说的this的第一种使用场景吗。而且是将全局函数作为普通函数使用,那函数里的this指向的就是window。那既然函数f中的this指向的是window对象,那this.age就相当于window.age。然后我不慌不忙的回答面试官)
题目一按照代码执行的输出顺序,第4行的输出结果为20,第7行的输出结果也是20(面试官不说话,应该是默认了我的回答是正确的)。
题目二:
(这个乍一看跟题目一有些相似,只是在第3行中对age的定义有了变化,而且在第6行还多了一个打印输出。
在往下看,发现函数f依然是作为普通函数去使用的,那既然是这样,第3行的this.age=40也就相当于window.age=40。
所以第3行代码执行的时候肯定会覆盖第1行对age的赋值。到这里我微微一笑,开始回答面试官)
题目二按照代码执行的输出顺序,第6行输出结果为20;第4行当输出结果为40;第8行当输出结果为40。
题目三:
(这个题目一看还是我前面说的this的第一种使用场景,只是全局函数作为普通函数使用)
题目三按照代码执行的输出顺序,第5行输出20;第8行输出20。
题目四:
(额,这个代码有点长呀,但是不能慌。
看完前8行觉得没啥问题,第9、10行看完后心里咯噔了一下。
将obj的getName方法赋值给了一个变量fn,然后打印fn()???
静下心想一想,第9行实际上是以声明式方式创建了一个全局函数fn,然后在第10行调用fn。
接着我陷入了沉思,那调用fn时,这个this到底是指向obj对象呢,还是指向全局的window对象。
大脑飞速旋转,想到刚开始对面试官说的那句话:javascript中的this对象是函数运行时,在函数内部生成的一个对象。
于是我不断的重复这句话,然后一个激灵反应上来,既然是this是函数运行时生成的,那我应该关注fn函数运行时的情况呀。
先抛开函数fn是由obj的getName方法赋值生成的这个事情。
fn生成以后,它是一个全局函数,这个毋庸置疑。再者,fn运行时是以普通函数的方式调用的。
那fn函数在运行时,内部的this对象就是window了,那第10行打印就是全局的"babi"了,恩,一定是这样。
擦擦汗在继续看,又发现了16行的代码,感觉和第10行代码有些异曲同工之处。
接着前面的思路往里套,不管otherObj.getName是怎么创建的,它在运行的时候是作为otherObj对象的方法运行的,那这就符合前面说的第二种使用this的场景:对象方法中的this,它指向的就是该对象本身。
想完这些抬头看了一下面试官,一言不发甚至有些不耐烦,于是虚虚的回答他)
题目四按照代码执行的输出顺序,第10 行的输出结果为"babi";第17行的输出结果为"mini"。
(此时看到面试官眉头舒展,微微一笑)
面试官:好,那这个问题到此结束......
三.拷问结束
面试官的灵魂拷问结束后,回到家里把记得的示例代码都验证了一遍,竟然发现都对了。
于是默默的奖励自己一个鸡腿。
声明:文章中场景纯属捏造,切勿当真。小小总结,欢迎拍砖。
作者:小土豆biubiubiu
掘金:https://juejin.im/user/58c61b4361ff4b005d9e894d
简书:https://www.jianshu.com/u/cb1c3884e6d5
微信公众号:土豆妈的碎碎念(扫码关注,一起吸猫,一起听故事,一起学习前端技术)
码字不易,点赞鼓励哟~
面试系列-面试官:你能给我解释一下javascript中的this吗?的更多相关文章
- 面试官:能解释一下javascript中bind、apply和call这三个函数的用法吗
一.前言 不知道大家还记不记得前几篇的文章:<面试官:能解释一下javascript中的this吗> 那今天这篇文章虽然是介绍javascript中bind.apply和call函数 ...
- JavaScript面试系列:JavaScript设计模式之桥接模式和懒加载
我写的程序员面试系列文章 Java面试系列-webapp文件夹和WebContent文件夹的区别? 程序员面试系列:Spring MVC能响应HTTP请求的原因? Java程序员面试系列-什么是Jav ...
- 2019前端面试系列——Vue面试题
Vue 双向绑定原理 mvvm 双向绑定,采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫持各个属性的 setter.getter,在数 ...
- 【Java进阶面试系列之一】哥们,你们的系统架构中为什么要引入消息中间件?
转: [Java进阶面试系列之一]哥们,你们的系统架构中为什么要引入消息中间件? **这篇文章开始,我们把消息中间件这块高频的面试题给大家说一下,也会涵盖一些MQ中间件常见的技术问题. 这里大家可以关 ...
- 【阿里面试系列】Java线程的应用及挑战
文章简介 上一篇文章[「阿里面试系列」搞懂并发编程,轻松应对80%的面试场景]我们了解了进程和线程的发展历史.线程的生命周期.线程的优势和使用场景,这一篇,我们从Java层面更进一步了解线程的使用.关 ...
- 程序员面试系列之Java单例模式的攻击与防御
我写的程序员面试系列 Java面试系列-webapp文件夹和WebContent文件夹的区别? 程序员面试系列:Spring MVC能响应HTTP请求的原因? Java程序员面试系列-什么是Java ...
- 2019前端面试系列——JS面试题
判断 js 类型的方式 1. typeof 可以判断出'string','number','boolean','undefined','symbol' 但判断 typeof(null) 时值为 'ob ...
- 2019前端面试系列——JS高频手写代码题
实现 new 方法 /* * 1.创建一个空对象 * 2.链接到原型 * 3.绑定this值 * 4.返回新对象 */ // 第一种实现 function createNew() { let obj ...
- 2019前端面试系列——CSS面试题
盒模型 /* 红色区域的大小是多少?200 - 20*2 - 20*2 = 120 */ .box { width: 200px; height: 200px; padding: 20px; marg ...
随机推荐
- 关于本地用svn up的时候报cannot update svn folder: "unversioned directory of the same name already exists
这是因为本地有手动添加过一个文件夹,然后和svn上的同名文件夹重名了,所以无法从svn update下来 解决办法如下: 1.先给本地的重名文件夹改名 mv dirname repeatdirnam ...
- umask 设置
背景: 有时候需要在linux上从其他人的目录里copy文件过来. 最近遇上的事情很麻烦,就是copy的时候发现很多文件copy不过来,copy一个文件夹时,当前文件把权限修改了,结果子目录的中的还没 ...
- [reviewcode] 那些基础comments
多次提醒我,为变量取个合适的名字, so cute person: Not a big deal, but try using variable names better than my_sa 每个参 ...
- Linux下搭建实现HttpRunnerManager的异步执行、定时任务及任务监控
前言 在之前搭建的HttpRunnerManager接口测试平台,我们还有一些功能没有实现,比如异步执行.定时任务.任务监控等,要完成异步执行,需要搭建 RabbitMQ 等环境,今天我们就来实现这些 ...
- 【时区问题】SpringBoot+mybatis查询mysql的datetime类型数据时间差14小时
[时区问题]MyBatis查询MySQL的datetime类型数据时间差14小时 故障解决方式 与数据库连接时,定义时区,避免mybatis框架从mysql获取时区.在连接上加上 serverTime ...
- 精选腾讯技术干货200+篇,云加社区全年沙龙PPT免费下载!
2019年已经过去,小编为大家整理了这一年以来云加社区发布的 200多篇腾讯干货,点击文章标题即可跳转到原文,请速速收藏哦~ 看腾讯技术: 腾讯成本优化黑科技:整机CPU利用率最高提升至90%: 腾讯 ...
- 使用rapidjson把文本json数据解析到树状结构
一个递归搞定 无聊的时候练练手就写了一个 头文件什么的我就不贴了 demo程序是MFC写的 void ParseObject(rapidjson::Value dc, CTreeCtrl * pTre ...
- 一文MyBatis-Plus快速入门
目录 一.依赖及配置 1.在idea中创建一个SpringBoot项目,在pom.xml中添需要的依赖 2.配置数据库连接 3.在启动类中添加注解 @MapperScan 扫描Mapper接口包 4. ...
- 1072 开学寄语 (20分)C语言
下图是上海某校的新学期开学寄语:天将降大任于斯人也,必先删其微博,卸其 QQ,封其电脑,夺其手机,收其 ipad,断其 wifi,使其百无聊赖,然后,净面.理发.整衣,然后思过.读书.锻炼.明智.开悟 ...
- DLC双端锁,CAS,ABA问题
一.什么是DLC双端锁?有什么用处? 为了解决在多线程模式下,高并发的环境中,唯一确保单例模式只能生成一个实例 多线程环境中,单例模式会因为指令重排和线程竞争的原因会出现多个对象 public cla ...