js中this的指向问题

 JS 面试题:

var obj = {

  foo: function(){

    console.log(this)

  }

}

 

var bar = obj.foo

obj.foo() // 打印出的 this 是 obj

bar() // 打印出的 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.foo

obj.foo() // 转换为 obj.foo.call(obj),this 就是 obj

bar()

// 转换为 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 了 :) 

 

总结

 

  1. this 就是你 call 一个函数时,传入的 context。

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

 

转载于:https://www.cnblogs.com/alex-415/p/6763393.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/488500.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是数据中台?全面解读数据中台

来源:与数据同行伴随着云计算、大数据、人工智能等IT技术迅速发展及与传统行业实现快速融合,一场由数字化和智能化转型带来的产业变革正在孕育。随着企业规模不断扩大、业务多元化——中台服务架构的应运而生。“中台”早期是由美军的作战体系演化而来的…

add结果 bigdecimal_java.math.BigDecimal.add(BigDecimal augend)方法

全屏java.math.BigDecimal.add(BigDecimal augend)方法java.math.BigDecimal.add(BigDecimal augend) 返回一个BigDecimal,其值为(this augend),其标度为 max(this.scale(), augend.scale())。声明以下是java.math.BigDecimal.add()方法的声明public Bi…

近指针, 远指针和巨指针

近指针, 远指针和巨指针是在段寻址的16位处理器中产生的。 (http://blog.csdn.net/zhoudengqing/article/details/41347607)转载于:https://www.cnblogs.com/ArcherHuang/p/6767858.html

python导出oracle数据到excel_【python】 python 查询oracle数据生成excel

接上篇安装好了cx_Oracle.msi MySql.msi 下载安装 xlwt-0.7.5.tar.gz, 到安装目录下 命令窗口cmd下执行 python setup.py install即可 被引用的文件: # coding: utf-8 # xlswriter.py # http://pypi.python.org/pypi/xlwt import xlwt class XLSWriter(o…

指挥控制系统中的自然智能和人工智能

来源:人机与认知实验室【编者按:为什么美军的“深绿系统”不好用?并常常被指挥员所诟病。但这是指控系统智能化的关键之所在!你也许会简单地说:“是人、机、环境系统失调造成的”,若进一步问“那是怎样失调…

execel公式 java工具_PAP-快速开发框架:JAVA 计算器 自定义公式 解决EXCEL计算公式问题...

JAVA 自定义公式计算器, 形如EXCEL中含有大量的计算公式-财务函数: PMT FV NPER PV DB DDB 这些:可以通过编码方式,解决在JAVA中进行数据计算, 同时可以自定义扩展自己想要的数据函数。执行语句: PMT(0.00515,360,-77…

Sublime Text 3 搭建 React.js 开发环境

Sublime有很强的自定义功能,插件库很庞大,针对新语言插件更新很快,配合使用可以快速搭建适配语言的开发环境。 1. babel-sublime 支持ES6, React.js, jsx代码高亮,对 JavaScript, jQuery 也有很好的扩展。关于 babel 的…

python中对象的方法_在Python中表示一个对象的方法

在 Python 中一切都是对象。如果要在 Python 中表示一个对象,除了定义 class 外还有哪些方式呢?我们今天就来盘点一下。 0x00 dict 字典或映射存储 KV 键值对,它对查找、插入和删除操作都有比较高效率。用一个 dict 对象可以非常容易的表示一…

AI造假 vs AI打假 终结“猫鼠游戏”不能只靠技术

来源:和讯网人脸识别作为生物识别中的重要手段,成为了近年身份识别中最热门的领域。但与人脸识别技术共同发展的,还有借助机器学习系统、图像视频和音频内容,更改人脸、物体或环境呈现方式的深度伪造技术。随着这一技术的日趋成熟…

单例设计模式之安全的懒汉式

package 单例模式; /*** 单例设计模式之安全的懒汉式*/ class Single{private static Single single null;//私有构造方法private Single() {}//对外提供公有的获取内部创建的Single对象public static Single getInstance(){if(singlenull){synchronized(Single.class){if(sing…

navicat导入excel_傻瓜式教学【数据库管理工具Navicat】

想玩数据怎么能连sql都不会,想写sql怎么能不会用最简单的NavicatNavicat的安装看这里手把手教你安装Navicat——靠谱的Navicat安装教程​www.jianshu.com猴子:客户端navicat安装教程​zhuanlan.zhihu.com装好了Navicat,首先将csv格式的excel文…

你好AI丨重读图灵经典之作,九条反驳意见引人深思

来源: AI科技评论编译 | 丛末、蒋宝尚当一台计算机能够骗过人类,让他们相信它就是一个人的时候,就能够被称作智能。编者按:对于艾伦图灵,相信大家都并不陌生,作为人工智能鼻祖,图灵的诸多观点即…

java 比较源文件_Beyond Compare比较Java源代码文件的操作方法

今天小编就带大家来共同学习BeyondCompare如何比较Java源代码文件希呢?望可以帮助到有需要的小伙伴哦,下面就是详细完整的操作步骤。打开BeyondCompare,在主页面左侧目录下选择文本比较会话,打开会话操作界面。分别单击比较会话界面“打开文…

关于研究的方法

转载于:https://www.cnblogs.com/freedommovie/p/6769717.html

【学术快报】韩世辉课题组在《eLife》发表论文揭示群体冲突中复仇的神经生物学机制...

来源:脑科学在群体冲突中,看到对手伤害自己的队友会激发报复行为,去攻击对手。这一复杂社会行为贯穿人类历史,阐明其机理具有重要科学意义和社会价值。心理学研究提出对“内群体的爱”(ingroup love)或/和对…

无聊的python课程_python教案课程

第五单元进阶程序设计(总10课时)第一节选择编程语言(1课时)一、教学目标1、了解程序设计语言和两种翻译方式;2、了解Python背景、功能、安装,熟悉Python编程环境;3、编程初体验。体验一个小程序从建立、输入、调试、运行、保存的全过程。掌握…

《面向对象程序设计》课程作业二

github链接作业链接编写一个程序,要求根据给定的圆的半径求圆的面积,并将求得的结果打印出来。……建立一个工程,将程序写成两个.cpp和一个.h的形式。 这个问题倒是没什么难的,但对于同学们来说是一个上手模块化的好开端。从现在开…

报告 | 超级智能城市2.0 – 人工智能引领新风尚(附下载)

来源:智慧城市决策参考未来智能实验室是人工智能学家与科学院相关机构联合成立的人工智能,互联网和脑科学交叉研究机构。未来智能实验室的主要工作包括:建立AI智能系统智商评测体系,开展世界人工智能智商评测;开展互联…

icmp协议_ICMP协议【41】

1、回顾TCP/IP协议栈为了更有效地转发IP数据报和提高交付成功的机会......2、ICMP协议的简介(1)ICMP,全称为Internet Control Message Protocol,即网际控制报文协议、网际控制消息协议。(2)它是TCP/IP协议族的一个子协议,用于在IP主机、路由器…

java的字节码无法显示_【java】查看Java字节码文件内容的方法+使用javap找不到类 解决方法...

研究synchronized底层实现,涉及到查看java字节码的需要前提是,你的PC已经成功安装了JDK并别配置了环境变量。查看方法一.javap查看简约字节码方式1.准备一个java文件例如,文件所在目录在此处Student.java文件内容如下:packagecom.…