目录

声明函数中的 this

函数表达式中的 this

对象方法中的 this

复合案例

构造函数中的 this

修改 this 默认指向


本文将详细介绍 “ JavaScript 中的 this 到底指向谁?”

this 指向问题核心就是把握如下两点:

1)this 指向的是对象

2)与函数或者方法如何声明的无关,而是要看这个函数或者方法最终被谁调用,谁最终调用这个函数或方法,那么这个函数或方法中的 this 就是谁

下面从简单到复杂的开始进行介绍。

声明函数中的 this

​
<script type="text/javascript">//声明式函数function showTime1(X) {console.log("showTime1+" + X, this);}//声明式函数function showTime2() {this.showTime1(130);}showTime1(110);window.showTime1(120);showTime2();
</script>

showTime1(X)、showTime2() 作为声明式函数在编译的时候就已经绑定到了 Window 对象上,全局函数等同于给 Window 对象添加方法。

所以第 13 行、第 14 行调用 showTime1(X) 函数本质一样,因为 showTime1(X) 被 Window 对象调用,所以 showTime1(X) 函数中的 this 就表示 Window 对象。

第 15 行实在也同样是 Window 对象在调用 showTime2()函数,所以 showTime2() 中的 this 也就是 Windows 对象,而 Window 对象自然可以调用 showTime1(X)。运行结果如下:

函数表达式中的 this

  • ES5 声明变量只有两种方式:var 和 function。
  • ES6 新增 let、const、import、class 再加上 ES5 的 var、function 共有六种声明变量的方式
  • 浏览器环境中顶层对象是 window,Node 中是 global 对象。
  • ES5 中顶层对象的属性等价于全局变量,即 var 定义的全局变量和函数都是在为 Window 对象追加属性和方法。
  • ES6 开始 var 定义、function 声明的全局变量,依然是顶层对象的属性;let、const、class 定义的全局变量不属于顶层对象的属性,Scope 是 Script ,即从 ES6 开始,全局变量和顶层对象的属性开始分离。
    <script type="text/javascript">//var 定义的全局变量提升为顶层对象 window 的属性var var_id = 110;//let 定义的全部变量则不再是顶层对象 window 的属性,作用域 Scope 为 Scriptlet let_id = 120;console.log(var_id, let_id);//输出:110 120console.log(window.var_id, window.let_id);//输出:110 undefined</script>

通过调试也可以看到,var_id 的 Scope 是 Global,会位于顶层对象 Window 下,而 let_id 的 Scope 是 Script,并不是在顶层对象 Window 下。

    <script type="text/javascript">//var 定义的全局变量提升为顶层对象 window 的属性var var_id = 110;var var_fun = function (param) {console.log("var_fun", this.var_id, param);};/**let 定义的函数作用域是 Script,并不会提升到顶层对象 window 下去* 但是在定义位置后面都可以使用此函数,包括后面引入的 <script/>文件中也照样可以调用*/let let_fun = function () {//this 代表的是 window 对象console.log("let_fun", this.var_id, this);};var_fun(1);//正常调用window.var_fun(2);//正常调用let_fun();//正常调用/**因为 let_fun 并没有提示为顶层对象 window 的函数,* 所以如下调用会报错:Uncaught TypeError: window.let_fun is not a function*/window.let_fun();//调用报错</script>

对象方法中的 this

<script type="text/javascript">let jsonObj = {id: 9527,name: "华安",showAge: function () {console.log("年方18", this);console.log(this.id, this.name);}};jsonObj.showAge();
</script>

jsonObj 是 Json 对象,第 10 行的 showAge() 方法由 jsonObj 对象调用,所以 showAge 方法中的 this 就表示 jsonObj 对象,运行结果如下:

复合案例

案例一:

    <script type="text/javascript">//声明式函数function showTime() {console.log(new Date().getTime(), this);}/**全局变量,也相当于为 window 对象添加的属性*/var id = 1001;var name = "宁王";//Json 对象let jsonObj = {id: 9527,name: "华安",showAge: function () {console.log("年方18", this);console.log(this.id, this.name);}};showTime = jsonObj.showAge;showTime();</script>

关键在第 20 行,将 jsonObj 对象中的 showAge 函数的函数体赋值给了 showTime,所以第 21 行调用的肯定是第 15-18 行,已经知道第 21 行 showTime()本质就是 window.showTime(),也就是说方法其实是被 window 对象调用了,于是第 16-17 行中的 this 就表示 window 对象。运行结果如下:

案例二:

    <script type="text/javascript">//声明式函数function showTime() {console.log(new Date().getTime(), this);}/**全局变量,也相当于为 window 对象添加的属性*/var id = 1001;var name = "宁王";//Json 对象let jsonObj = {id: 9527,name: "华安",showAge: function () {console.log("年方18", this);console.log(this.id, this.name);}};jsonObj.showAge = showTime;jsonObj.showAge();</script>

关键点同样在第 21 行,将 showTime 函数的函数体赋值给了 jsonObj 对象的 showAge 函数,所以第 22 行调用之后运行的肯定是第 3-5 行,而调用它的对象是  jsonObj 对象,所以第 4 行中的 this 就表示 jsonObj 对象。运行结果如下:

案例三:

    <script type="text/javascript">/**全局变量,也相当于为 window 对象添加的属性*/var id = 1001;var name = "宁王";//Json 对象let jsonObj = {id: 9527,name: "华安",tiger: {id: 8866,name: "江小白",showAge: function () {console.log(this);console.log(this.id, this.name);}}};jsonObj.tiger.showAge();</script>

关键点在第 19 行,jsonObj 是 JSON 对象,它的属性 tiger 也是 JSON 对象,而真正调用 showAge() 函数的是 tiger 对象,所以第 15 行中的 this 表示 tiger 对象。运行结果如下:

构造函数中的 this

    <script type="text/javascript">/**ES5 中的类和普通函数写法类似,Tiger 就相当于一个构造器*/function Tiger() {this.id = 9527;this.name = "华安";console.log("构造器执行", this.id);this.showAge = function () {console.log(this.name + " 今年 28 岁.");}}let tiger = new Tiger();console.log(tiger);console.log(tiger.id, tiger.name);tiger.showAge();</script>

new 关键字创建对象,构造器会执行,其中的 this 指向这个对象,同时这个对象会返回。

修改 this 默认指向

除了指定函数中 this 的指向之外,JavaScript 还提供了一套机制来修改 this 的默认指向,可以让函数中的 this 指向想让它指向的对象。

ES5 中通常采用函数上下文调用模式,如 call、apply、bind 等,

 <script type="text/javascript">/**全局变量,相当于给 window 对象添加属性*/var id = 120;var name = "华太师";// json 对象let json = {id: 110,name: "华安"};//全局函数,相当于给 window 添加方法function showTime() {console.log(this);console.log(this.id, this.name);}//默认情况下调用时,其中的this表示window对象showTime();//使用 call 将 json 对象替换默认原来的 window 对象showTime.call(json);</script>

运行结果如下:

ES6 开始可以使用箭头函数 ()=> ,它会将 this 表示的对象往外抛一级,如下所示:

    <!-- 箭头函数属于 ES6 ,所以 type 类型要改成 module--><script type="module">/*** Tiger 相当于一个类* @constructor*/let Tiger = function () {this.id = 110;this.name = "宁王";/**Dog 是一个 Json对象*/this.Dog = {id: 120,name: "华太师",/**非箭头函数写法*/showInfo1: function () {console.log(this.id, this.name);},/**箭头函数写法*/showInfo2: ()=> {console.log(this.id, this.name);}}};/**这种写法已经说过了,调用 showInfo1 函数的是 Dog 对象,里面的 this 就表示 Dog 对象*/new Tiger().Dog.showInfo1();/**虽然调用 showInfo2 函数的是 Dog 对象,但是箭头函数会往外抛一层,里面的 this 表示的是 Tiger*/new Tiger().Dog.showInfo2();</script>

运行结果如下:

JavaScript 中的 this 到底指向谁?相关推荐

  1. JavaScript 中的 hoisting 到底是甚麼 ?

    JavaScript 中的 hoisting 到底是甚麼 ? 前言 正文 到底什麼是 hoisting? let const 與 hoisting 為什麼要有 hoisting? hoisting 到 ...

  2. 【JS】Javascript中的this到底是什么

    JavaScript中的this是一个对于新手来说特别吓人并且不友好的概念.对于一个前端萌新来说,这个概念既模糊,又看不到它存在的意义.本文将深度解析JavaScript中的this,并且逐一分析他在 ...

  3. 如何延长作用域链_通过实例理解javaScript中的this到底是什么和它的词法作用域...

    最近,听到李笑来说,讲解编程的过程中,举例子很重要. 而且,我最近看的各种javaScript工具书中的例子,也都有点复杂. 所以啊,我试着举一些简单又直观的例子,与各位苦学javaScript的同学 ...

  4. JavaScript中函数上下文this指向问题#面试常见读代码

    this 总是指向执行时的当前对象.JavaScript 的 this 总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境.也就是说 this 的绑定和 ...

  5. javascript中的this到底是指什么(一)?

    写js也有两年多了,在平时工作中也经常会用到this关键字,但是仅局限于用它,如果要求我讲明白this到底是什么的话可能就有点懵逼了,相信大家在面试的时候面试官也经常会问你this是神马东东,为了避免 ...

  6. 科普向--详解JavaScript中的数据类型

    对于前端的小伙伴而言,JS的数据类型可谓是必懂的知识点.虽然这个知识点很是基础了,不过仍然有不少人会在这一块犯些小错误.比如网上流传的"JavaScriptS一切皆对象",其实是个 ...

  7. 一篇文章把你带入到JavaScript中的闭包与高级函数

    在JavaScript中,函数是一等公民.JavaScript是一门面向对象的编程语言,但是同时也有很多函数式编程的特性,如Lambda表达式,闭包,高阶函数等,函数式编程时一种编程范式. funct ...

  8. $.ligerdialog.open中确定按钮加事件_彻底搞懂JavaScript中的this指向问题

    JavaScript中的this是让很多开发者头疼的地方,而this关键字又是一个非常重要的语法点.毫不夸张地说,不理解它的含义,大部分开发任务都无法完成. 想要理解this,你可以先记住以下两点: ...

  9. 图解javascript中this指向

    JavaScript 是一种脚本语言,支持函数式编程.闭包.基于原型的继承等高级功能.JavaScript一开始看起来感觉会很容易入门,但是随着使用的深入,你会发JavaScript其实很难掌握,有些 ...

  10. javascript中关于this指向问题详解

      前  言 LiuDaP 在前端的学习中,我们必然要用到js,js可以说是前端必不可少的的东西.在学习js的过程中,我们会经常用到this这个东西,而this的指向问题就变得尤为重要.今天正好有空闲 ...

最新文章

  1. 学习PHP 逛的几个网站。
  2. jQuery EasyUI API 中文文档 - 日期框(DateBox)
  3. KDD 18 AAAI 19 | 异构信息网络表示学习论文解读
  4. mysql触发器如果某个字段被修改_mysql trigger触发器 一张表一个字段改变 更新另一张表对应字段...
  5. 复旦大学把衣服变成了显示器,能聊天能导航,水洗弯折都不怕
  6. Servlet 处理多种请求应用
  7. Confluence 6 PostgreSQL 创建数据库和数据库用户
  8. js过滤时间方法,几分钟前,1小时前
  9. Java带有效期的Map
  10. 双色球的实现(基于Vuejs)
  11. 如何理解实时频谱分析仪的几个“带宽”参数(1)——实时带宽(RTBW)
  12. 关于 Cannot read property ‘length‘ of null 报错的解决办法
  13. 中缀表达式X=A+B*(C-(D+F))/E转后缀表达式之后是什么?
  14. 仿微信、qq聊天,@好友功能
  15. 一篇3分文章的水稻转录组分析实战
  16. 一款超好用的开源密码管理器?
  17. 统计自然语言处理梳理二:句法分析
  18. Python自动化测试框架
  19. (python)Day9丨测试代码
  20. 循环视图——RecycleView

热门文章

  1. 读取usb接口数据_笔记本接口不够?无须担心!小米分线器开箱初体验
  2. 拓端tecdat|基于出租车GPS轨迹数据的研究:出租车行程的数据分析
  3. simhash实现html页面相似度,基于改进的Simhash算法的相似文档识别技术
  4. mysql study_mysql_study_3
  5. About 产量数据选取问题
  6. 抖音创作规范_实体店如何借势抖音为门店获客?
  7. linux系统uptime解读,Linux中的uptime命令详解
  8. 【论文笔记】HyperFace: ADeep Multi-task Learning Framework for Face Detection
  9. python求解比一个给定的数字大的最小对称数
  10. 2021-06-29初识JQuery