this 的值到底是什么?一次说清楚

你可能遇到过这样的 JS 面试题:

var obj = {  foo: function(){    console.log(this)  }}var bar = obj.fooobj.foo() // 打印出的 this 是 objbar() // 打印出的 this 是 window

请解释最后两行函数的值为什么不一样。

-------

初学者关于 this 的理解一直很模糊。今天这篇文章就要一次讲清楚了。

而且这个解释,你在别的地方看不到。看懂这篇文章,所有关于 this 的面试题,都是小菜。

有用请点赞。

函数调用

首先需要从函数的调用开始讲起。

JS(ES5)里面有三种函数调用形式:

func(p1, p2) obj.child.method(p1, p2)func.call(context, p1, p2) // 先不讲 apply

一般,初学者都知道前两种形式,而且认为前两种形式「优于」第三种形式。

从看到这篇文章起,你一定要记住,第三种调用形式,才是正常调用形式:

func.call(context, p1, p2)

其他两种都是语法糖,可以等价地变为 call 形式:

func(p1, p2) 等价于func.call(undefined, p1, p2)obj.child.method(p1, p2) 等价于obj.child.method.call(obj.child, p1, p2)

请记下来。(我们称此代码为「转换代码」,方便下文引用)

至此我们的函数调用只有一种形式:

func.call(context, p1, p2)

这样,this 就好解释了

this,就是上面代码中的 context。就这么简单。

this 是你 call 一个函数时传的 context,由于你从来不用 call 形式的函数调用,所以你一直不知道。

先看 func(p1, p2) 中的 this 如何确定:

当你写下面代码时

function func(){  console.log(this)}func()

用「转换代码」把它转化一下,得到

function func(){  console.log(this)}func.call(undefined) // 可以简写为 func.call()

按理说打印出来的 this 应该就是 undefined 了吧,但是浏览器里有一条规则:

如果你传的 context 是 null 或 undefined,那么 window 对象就是默认的 context(严格模式下默认 context 是 undefined)

因此上面的打印结果是 window。

如果你希望这里的 this 不是 window,很简单:

func.call(obj) // 那么里面的 this 就是 obj 对象了

再看 obj.child.method(p1, p2) 的 this 如何确定

var obj = {  foo: function(){    console.log(this)  }}obj.foo()

按照「转换代码」,我们将 obj.foo() 转换为

obj.foo.call(obj)

好了,this 就是 obj。搞定。

回到题目:

var obj = {  foo: function(){    console.log(this)  }}var bar = obj.fooobj.foo() // 转换为 obj.foo.call(obj),this 就是 objbar() // 转换为 bar.call()// 由于没有传 context// 所以 this 就是 undefined// 最后浏览器给你一个默认的 this —— window 对象

[ ] 语法

function fn (){ console.log(this) }var arr = [fn, fn2]arr[0]() // 这里面的 this 又是什么呢?

我们可以把 arr[0]( ) 想象为arr.0( ),虽然后者的语法错了,但是形式与转换代码里的 obj.child.method(p1, p2) 对应上了,于是就可以愉快的转换了:

arr[0]() 假想为    arr.0()然后转换为 arr.0.call(arr)那么里面的 this 就是 arr 了 :)

箭头函数

我不明白为什么需要讨论箭头函数,实际上箭头函数里并没有 this,如果你在箭头函数里看到 this,你直接把它当作箭头函数外面的 this 即可。外面的 this 是什么,箭头函数里面的 this 就还是什么,因为箭头函数本身不支持 this。

有人说「箭头函数里面的 this 指向箭头函数外面的 this」,这很傻,因为箭头函数内外 this 就是同一个东西,并不存在什么指向不指向。

总结

  1. this 就是你 call 一个函数时,传入的第一个参数。(请务必背下来「this 就是 call 的第一个参数」)

  2. 如果你的函数调用形式不是 call 形式,请按照「转换代码」将其转换为 call 形式。

以后你遇到所有跟 this 有关的笔试题,都不会有疑问了。

完。

(0)

相关推荐

  • 一文搞懂 this、apply、call、bind

    "this" 关键字允许在调用函数或方法时决定哪个对象应该是焦点. 在JavaScript中this可以是全局对象.当前对象或者任意对象,这完全取决于函数的调用方式,this 绑定 ...

  • 【第765期】你不懂JS:this豁然开朗!

    前言 昨天第一篇分享就被@烛火星光发现是跟<你不知道的javascript>上册(一看就是看过书的),没看过书的童鞋也没关系,可以跟着早读君每天看一篇.今天继续由前端早读课专栏作者@Het ...

  • 谈"this"

    首先,很多人对this有两个误解 1.this指向的是当前函数本身 什么意思呢,下面看一段代码. 1 function func(){ 2 this.a ++; 3 } 4 5 var a = 0; ...

  • js笔记合集

    基础篇 ------------------------------------------------- history: 用来控制网页前进和后退,根据的是网页历史纪录 history.back() ...

  • 反射,双下方法

    一. 反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序 ...

  • 求你了,别再用 print 调试代码了

    大家好,我是小五. 对于每个程序开发者来说,调试几乎是必备技能.代码写到一半卡住了,不知道这个函数执行完的返回结果是怎样的?调试一下看看代码运行到一半报错了,什么情况?怎么跟预期的不一样?调试一下看看 ...

  • 类的进阶

    面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个"函数"供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的 ...

  • 被包装出来的“剑圣”:宫本武藏武力值到底怎么样?

    本 文 约 6450 字 阅 读 需 要 16 min 从格斗游戏<侍魂>到大名鼎鼎的手游<王者荣耀>,很多人认识了一位厉害的日本剑客--宫本武藏. 游戏中,宫本武藏武艺高强. ...

  • 张飞生擒老将严颜,严颜的武力值到底怎样?比魏延如何?

    严颜是汉末三国时期将领,早期在益州牧刘璋手下效力,担任巴郡太守,刘备攻打益州,庞统战死,刘备召诸葛亮等人入川,其中,张飞一路遭遇了严颜的顽强抵抗,严颜最终战败被俘. 面对张飞的质问,严颜大义凛然,说, ...

  • 鹿晗腕表加起来值一千万,他到底代言哪家?

    我们曾经出于好奇,翻阅鹿晗这两年的微博,数数他到底有几块表,值多少钱. 从鹿晗微博照片来看,他至少有16块手表傍身:3块理查德·米尔,5块爱彼,3块劳力士,1块宇舶,1块罗杰·杜彼,1块香奈儿,1块卡 ...

  • 隐形车衣:到底值不值?算一笔账你就懂了!

    这年头挣钱绝对是一件不容易也不轻松的事情.也许大家也发现了,钞票是日益贬值了,和上窜下跳的房价比起来,我们的工资涨幅,或许真的是个笑话--一句话,挣钱不容易!还记得大虎悠去年在途虎给同学们上公开课,公 ...

  • 3周尿酸值直降250umol/L,刘先生到底做了什么?(内附方法)

    今天介绍的这位患者,身份比较特殊,刘某,男,48岁,是一名警察.在2020年6月感觉双脚大拇指关节处发痒,由于工作比较忙,所以一直没有时间检查.在2021年初单位体检的时候,查出尿酸升高(524umo ...

  • 宋辽签订澶渊之盟,30万岁币换来百年和平到底值不值?

    经过长达25年的战争后,北宋和辽国签订了历史上著名的澶渊之盟.这份盟约虽然被后世很多人所不齿,但是对于当时的北宋而言,却意义重大.毫无疑问,30万岁币换来百年的和平,简直太值了! 一场双方都心虚的议和 ...

  • 中国花360亿建造大型对撞机 到底值不值|电子|高能物理|粒子

    关注风云之声 提升思维层次9小时前 [王贻芳 中国科学院高能物理研究所所长院士] 以下为王贻芳演讲实录: 我是王贻芳,来自中科院高能物理研究所.我研究的领域叫粒子物理,也叫高能物理. 过去讲故事,开头 ...

  • 解读潜伏(22):斯蒂庞克和玉座金佛到底值多少钱?

    解读潜伏(22):斯蒂庞克和玉座金佛到底值多少钱?

  • 蓝宝石到底值不值钱?看看就明白了

    蓝宝石的颜色几乎覆盖所有色域,下面就开始说说关于蓝宝石的颜色,颜色是彩色宝石的灵魂,颜色是否好看决定着宝石是否美丽. 星蓝宝石可以被有星芒效应的玫瑰红石英加上蓝色珐琅模仿.或者在一块被切割成弧面型的蓝 ...