很多学java的同学在接触js之后使用this的时候都是懵逼的,这特么怎么回事,怎么老是给我报“Cannot read property 'xxx' of undefined”,我的this.xxx.xxx明明已经有值啊,为什么会出现这种情况。

面对上面的问题,很多js的初学者都会很懵,不知道js的this为什么就不指向自己想要的那个this了。

  我以前也遇见过这种疑惑,直到我后来学习了一个大佬的博客(至于是谁的我还真忘了),我彻底弄懂了js的this为什么这么调皮了。

  在js中,函数的调用有三种方式:

  1. 直接调用:例如a(...params)

  2. 对象调用:例如obj.a(...params)

  3. new 函数调用:例如new A(...params)

  但其实这些都是语法糖。

  直接调用其实写完整就是:

a.call(undefined,...params)

  对象调用写完整是:

obj.a.call(obj,...params)

  而使用 new 调用函数的时候,例如

var a = new A(...params)

 其实写完整是:

  var a = {}a.call(a, ...params)a.__proto__ = A.prototype

  这就是this为什么会乱跳的根本原因所在。

  在js中,根据函数的调用方式不同,this的指向变化也不同:

  1. 直接调用函数,this指向全局:

  这里会因为环境不同而产生不同的结果:

   在严格模式下,this是undefined,但是我们大部分代码都是在非严格模式下写的,所以不探讨这个情况。

   在非严格模式下,浏览器环境下this会指向window,node环境中会指向global。

     以浏览器代码为例:

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

 显示结果是:

  

 这里出现的问题是最多的,因为很多时候函数都是直接调用的,所以this会直接指向window,导致取值错误。

 

 2.对象调用函数,this指向调用对象:

  先看代码:

const obj = {a:1,b: function (){console.log(this.a)}
}obj.b()

  这个打印出来结果是1,毋庸置疑。因为这个this指向调用对象obj,所以this.a就是obj.a。

  再看一个代码:

const obj = {a:1,b:{a:2,b:function (){console.log(this.a)}}
}
obj.b.b()

  这里打印的是多少呢。把代码在浏览器中运行一下:

   

  是2,因为obj.b.b()就相当于obj.b.b.call(obj.b),所以this指向obj.b,那么打印出来的自然是obj.b.a。

  再看一段代码:

var a = 'This is brower'const obj = {a:1,b:function(){console.log(this.a)}
}
const fn = obj.b
fn()

  这里打印的是多少呢。把代码在浏览器中运行一下:

  这是为什么?

  这是因为fn = obj.b = function(){...},在这里的fn被赋值  function(){...},跟obj.b没有关系了,所以直接调用fn其中的this指向window,而window.a则是 'This is brower'。

  

 3. 使用构造函数调用,this 指向创建的对象:

  照例,先看代码:

function A(){this.a = 1this.b = 2
}
var a = new A()
console.log(a.a)
console.log(a.b)

  这里打印出来的自然是1和2,因为new A()过程中将this指向了a。

  但是在这里有个坑,就是构造函数的返回值如果是引用类型的值就会引发错误,会直接将this指向返回的对象。

function A(){this.a = 1return {a:2}
}
var a = new A()
console.log(a.a)

  在浏览器中运行查看结果:

  上图中可以看出,a指向的是A返回的对象,所以a.a打印出的是2。

  返回的如果是一个数组的话,a也会指向返回的数组,a.a就会打印出 undefined。

 

 在es6中出现了箭头函数,箭头函数中的this始终指向函数所处的块级作用域的this。

  看代码:

var a = 'This is window'const obj = {a: 1,b: () => {console.log(this.a)}
}
obj.b()

  上答案:

  是不是又懵了,明明是obj调用的,但是this却指向了window。

  这就是箭头函数的优点,因为它的this指向是固定的,永远指向所处的块级作用域内部的this。

  在这里obj.b所处的块级作用域就是全局,所以其中的this指向window。

  再来一段代码:

function a(){this.a = 10return {a:1,b:()=>{console.log(this.a)}}
}    const obj = a()
obj.b()

  继续直接上答案:

  这次差不多懂了吧,这个箭头函数创建的时候是处于方法 a 的作用域内部的,所以箭头函数内部的this始终指向方法 a 中的this。

 上述就是我在学习js中的this时遇到的所有关于this的调用的问题,估计应该可能大概差不多maybe是有没有涉及到的,但是关于this的这些差不多够了。

转载于:https://www.cnblogs.com/FraudulentArtists/p/9831449.html

javascript中的this指向问题相关推荐

  1. JAVAscript中的this指向和this指向的修改

    JAVAscript中的this指向和this指向的修改 this 关键字 一般在函数中使用,表示哪个对象执行了当前函数. 每一个函数内部都有一个关键字是 this . 函数内部的 this 只和函数 ...

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

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

  3. JavaScript中this的指向问题

    this是面向对象语言中一个重要的关键字,理解并掌握该关键字的使用对于我们代码的健壮性及优美性至关重要.而javascript的this又有区别于Java.C#等纯面向对象的语言,这使得this更加扑 ...

  4. 理解JavaScript中this的指向详解

    this的定义和理解: this是JavaScript语言的一个关键字,它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内使用. 1.this和执行环境对象有关,和函数的声明无关. var ...

  5. JavaScript中this的指向问题及面试题你掌握了吗?

    this 作为JavaScript中的一个关键字,它的复杂度很高,主要原因是它所处不同场景的代表的指向是不一样的.这里先做一个结论,重要事情说三遍: this的指向是由上下文环境动态决定的 this的 ...

  6. JavaScript中this的指向

    JavaScript之this指向问题 js中的this指向问题一直不是很清楚,看了coderwhy老师的文章后特此记录一下. this在全局作用域下使用 this在全局作用域下指向的就是window ...

  7. JavaScript中的 this指向问题

    以下文章均已附上原文链接 ,侵删 文章一:vue中的this指向问题 vue中的this指向问题_JingG459的博客-CSDN博客_vue中this指向问题 最近写项目遇到很多this指向的问题, ...

  8. 38 JavaScript中的this指向问题

    技术交流QQ群:1027579432,欢迎你的加入! 欢迎关注我的微信公众号:CurryCoder的程序人生 1.函数内this指向问题 函数内部的this指向是当我们调用函数的时候确定的.调用方式的 ...

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

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

  10. JavaScript中this指针指向的彻底理解

    this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象 这一点与函数中自由变量Action-varibal不同 1 va ...

最新文章

  1. 使用c#訪问Access数据库时,提示找不到可安装的 ISAM
  2. 克服大数据技能差距的策略
  3. Shiro与Springboot整合:配置依赖改造登录方法
  4. 《从零开始学ASP.NET CORE MVC》:VS2019创建ASP.NET Core Web程序(三)
  5. 数据离散化 - 等宽等频聚类离散 - Python代码
  6. 从零入门Serverless|一文搞懂函数计算及其工作原理
  7. GDB调试汇编堆栈过程的学习
  8. 宝岛探险1(DFS)
  9. ctf练习之音频文件
  10. 如何使用计算机蠕虫病毒软件,计算机中了蠕虫病毒如何解决
  11. Maven读书系列:Maven仓库
  12. 【渝粤题库】广东开放大学 市场调查与预测 形成性考核
  13. 名牌产品都在使用的公关策略
  14. 【运筹学】线性规划 图解法 ( 唯一最优解 | 无穷最优解 | 无界解 | 无可行解 )
  15. Docker常用软件安装之MYSQL
  16. EPS是什么文件格式
  17. 什么是JTAG及JTAG接口简介
  18. 基于区块链技术,电子商务平台将提高安全性和透明度
  19. JS 获取和响应键盘按键事件
  20. 图文详细解决Windows11设置删除pin开机登录验证

热门文章

  1. 【资源】机器学习资源积累(积累中...)
  2. java cdt_Eclipse代码提示功能设置(Java Eclipse+CDT C/C++)
  3. 区块链 以太坊 Solidity状态变量、局部变量与memory 、storage
  4. Mac如何删除python Python cannot be opened because of a problem
  5. python2 输出\n 不要换行
  6. 小学计算机老师师德师风演讲稿,2015年小学教师师德师风演讲稿
  7. django判断ajax,Django ajax 检测用户名是否已
  8. 基于springboot的高校后勤系统
  9. java中常用的类——System类
  10. 乱码问题_win7 64位系统出现字体乱码的问题