任何变量或对象都有其赖以生存的上下文。如果简单地将对象理解为一段代码,那么对象处在不同的上下文,这段代码也会执行出不同的结果。

例如,我们定义一个函数 getUrl 和一个对象 pseudoWindow

function getUrl() {console.log(this.document.URL);
}var pseudoWindow = {document: {URL: "I'm fake URL"},getUrl1: getUrl,getUrl2: function (callback) {callback();this.func = callback;this.func();}
}

执行 getUrl(),打印出当前页面的 URL。

执行 pseudoWindow.getUrl1(),打印出 I'm fake URL

执行 pseudoWindow.getUrl2(getUrl),先打印出当前页面 URL,后打印 I'm fake URL

下面让我们用最简单粗暴的语言来解释以上代码。

概念

什么是 this?

this 就是函数调用使用的上下文。

什么是上下文

上下文是在句号标记法中,句号前面的那个东西。

例如 pseudoWindow.getUrl1pseudoWindowpseudoWindow.getUrl1() 的上下文。

什么是自由变量

当一个变量没有绑定到任何上下文时(或者说绑定到顶级作用域时,例如浏览器中的 window),它就是自由变量

什么是变量对象

变量就是代码中你所用的标识符,一个标识符就是一个变量,多个变量可能指向同一个对象。例如:

pseudoWindow.getUrl1 === getUrl  // 得到 true

变量所处的上下文就是对象的作用域。

代码分解

调用 getUrl()

首先 getUrl 函数是定义在全局环境中,它是一个自由变量,在浏览器中(以下描述均为浏览器环境)它的上下文就是 window,所以 window.getUrl()getUrl() 是等价的。因此 this 指向 window 对象,打印出当前 URL。

调用 pseudoWindow.getUrl1()

首先 pseudoWindow 是一个对象,它可以充当上下文角色。我们给它定义了一个属性 getUrl1,你可以将属性视为被绑定到某个上下文的变量,变量 getUrl1 本身又指向了变量 getUrl 所指向的对象,所以 pseudoWindow.getUrl1 === getUrl 才会为 true

当我们调用 pseudoWindow.getUrl1() 时,它的意思是执行 getUrl() 这段代码,执行代码所需的参数为空,上下文为 pseudoWindow

所以函数中的 this 指向了 pseudoWindow,而 pseudoWindow 对象恰好又有 document 属性,该属性恰好又有 URL 属性,因此打印出 I'm fake URL

调用 pseudoWindow.getUrl2(getUrl)

同理我们又定义了一个变量 getUrl2,并绑定到 pseudoWindow 对象身上,使之成为后者的一个属性。而这个属性本身又指向一个匿名函数,我们姑且称之为 A,该函数对象接受另一个函数对象作为回调函数。

因此执行 pseudoWindow.getUrl2(getUrl) 时,意思是执行代码 A,执行代码所需的参数为 getUrl 这段代码,上下文为 pseudoWindow

因此函数 A 中的 this 指向了 pseudoWindow

当程序执行到函数 A 内部的 callback() 时,因为变量 callback 没有绑定到任何上下文,因此它相当于一个自由变量,它的上下文就指向了 window 对象,因此首先打印出当前页面的 URL。

接下来 this.func = callback 意味着三件事:

  • 我们新申明了一个变量 func
  • 通过 = 操作符,我们将该变量指向了 callback 所指向的函数对象。
  • 通过 . 操作符,我们将该变量绑定到了 this 对象上,使之成为后者的一个属性,而本例中 this 指向的就是 pseudoWindow 对象。

于是当程序执行到 this.func() 时,它的意思是执行 callback 这段代码,执行代码所需的参数为空,上下文为 pseudoWindow。于是打印出了 I'm fake URL

这段代码带来的一个副作用是我们隐式地为 pseudoWindow 对象添加了一个新的属性 func,如果我们想要通过回调的方式打印出 pseudoWindowdocument.URL 属性,又不想对 pseudoWindow 对象造成任何影响,那么我们可以使用函数的 apply 方法。所有函数都有 apply 方法,它会将它接收的第一个参数设置为函数的上下文。

例如本例中我们可以改写代码成这样子:

var pseudoWindow = {document: {URL: "I'm fake URL"},getUrl1: getUrl,getUrl2: function (callback) {callback();        callback.apply(this);}
}

严格地说,你应该先检查 callback 参数类型是否是函数对象。

总结

Javascript 支持将函数作为参数传递,回调函数变量指向的函数对象都未与任何上下文绑定,所有未与明确上下文绑定的变量都是自由变量,浏览器器中所有自由变量的上下文都是 window 对象。

转载于:https://www.cnblogs.com/ifantastic/p/4654370.html

理解 JS 回调函数中的 this相关推荐

  1. JS回调函数中的this指向

    什么是this:自动引用正在调用当前方法的.前的对象. this指向的三种情况 obj.fun() fun中的this->obj,自动指向.前的对象 new Fun() Fun中的this-&g ...

  2. js中回调函数的理解 举例说明js回调函数

    初学js的时候,被回调函数搞得很晕,现在回过头来总结一下什么是回调函数. 我们先来看看回调的英文定义:A callback is a function that is passed as an arg ...

  3. js回调函数的理解(轉)

    js回调函数(callback)理解Mark!讲之前说一句function say(){alert(,,,,,,,,)}var say=function (){alert(,,,,,,,)}var s ...

  4. 来自Android客户端什么意思,如何通过回调函数中的Node.js来自Android客户端

    我想从插座Android客户端将数据发送到服务器的Node.js .. 在服务器端做了什么香港专业教育学院:如何通过回调函数中的Node.js来自Android客户端 socket.on('new u ...

  5. html js 回调函数,js中回调函数的学习笔记

    回调函数是什么在学习之前还真不知道js回调函数怎么使用及作用了,下面本文章把我在学习回调函数例子给各位同学介绍一下吧,有需了解的同学不防进入参考. 回调函数原理: 我现在出发,到了通知你" ...

  6. 【转】JS回调函数--简单易懂有实例

    JS回调函数--简单易懂有实例 初学js的时候,被回调函数搞得很晕,现在回过头来总结一下什么是回调函数. 我们先来看看回调的英文定义:A callback is a function that is ...

  7. 理解javascript 回调函数

    理解javascript 回调函数 原文:理解javascript 回调函数 ##回调函数定义 百度百科:回调函数 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一 ...

  8. mysql.js回调函数_js回调函数(callback)

    Mark! js学习 不喜欢js,但是喜欢jquery,不解释. 自学jquery的时候,看到一英文词(Callback),顿时背部隐隐冒冷汗.迅速google之,发现原来中文翻译成回调.也就是回调函 ...

  9. JS回调函数——简单易懂有实例

      初学js的时候,被回调函数搞得很晕,现在回过头来总结一下什么是回调函数.什么是JS?(点击查看) 下面先看看标准的解释: <script language="javascript& ...

最新文章

  1. shiro整合oauth
  2. Gridview分页模板
  3. DRF_APIView之认证、授权配置
  4. 数据库表名大小写_某教程学习笔记(一):09、MYSQL数据库漏洞
  5. 学习:配置hibernate
  6. SpringCloud之 Feign的简单使用
  7. ADO.NET 【攻击及防御】
  8. wⅰndows办公软件2003,办公软件2003
  9. 杀软自己做 编写autorun病毒免疫工具
  10. 统计学简介之十七——双因素方差分析
  11. 大数据营销咨询公司AIO获数百万美元天使轮融资
  12. Data Binding学习(一)
  13. 移动互联网业务的产业链
  14. usb 接口触摸屏驱动
  15. Science:工具使用和语言句法在基底神经节共享计算机制和神经表征
  16. A/B Problem(大数)
  17. python连乘函数_(Python3) 连加 连乘 代码
  18. GSM通话断续问题分析
  19. 华为机试第二题420 按照路径替换二叉树
  20. alternate端口什么意思_alternate是什么意思_alternate在线翻译_英语_读音_用法_例句_海词词典...

热门文章

  1. 双11拼团最后的福利!老用户如何解散团并加入新团!
  2. 【wpf】在win10系统上弹出toast和notification
  3. 47. Python socket编程 2
  4. 字符串的切割操作(strtok,split)
  5. silverlight 学习笔记 (七):Prism的第一个应用
  6. 通过发送WM_GETTEXT命令获得EDIT中的信息
  7. c++学习笔记(7) 面向对象思想
  8. 深度学习李宏毅PPT学习笔记一(深度学习介绍)
  9. ROS学习笔记13(测试一个简单的消息发布和消息订阅)
  10. python 复制列表内容_Python复制列表列表