原因
在对象内部的方法中使用对象内部的属性是一个非常普遍的需求。但是 JavaScript 的作用域机制并不支持这一点,基于这个需求,JavaScript 又搞出来另外一套 this 机制。
类别
由于this和执行上下文是绑定的,执行上下文有三种,那this也对应的有三种。
- 全局this
全局执行上下文中的 this 是指向 window 对象的。这也是 this 和作用域链的唯一交点,作用域链的最底端包含了 window 对象,全局执行上下文中的 this 也是指向 window 对象。
- 函数里的this
函数内部的this
- eval中的this
eval函数里的this
存在位置
this是存在与执行上下文当中的。
- 在ES3和ES5规范中this直接存在于执行上下文
- 在ES9规范中,this则被放入了执行上下文的词法环境中去
- this 是和执行上下文绑定的,也就是说每个执行上下文中都有一个 this。
this的指向
- 全局执行上下文的this指向window对象(非严格模式),严格模式为undefined
- 普通函数this的指向指向调用他的对象
- 箭头函数this的指向指向定义他的对象
- 构造函数中的this指向实例化后的对象
更改this的指向
- bind 返回函数体
- call 直接执行,但参数要一个一个传入
- apply 直接执行,参数可以为数组
- 对象调用的方式
⚠️:使用对象来调用其内部的一个方法,该方法的 this 是指向对象本身的。
var myObj = { name : "test", showThis: function(){ console.log(this) } } myObj.showThis()
- 通过构造函数中设置
缺陷及如何避免
嵌套函数中的 this 不会从外层函数中继承
var myObj = { name : "test", showThis: function(){ console.log(this) var self = this function bar(){ self.name = "极客邦" } bar() } } myObj.showThis() console.log(myObj.name) console.log(window.name)
解决方案
- 可以声明一个变量 self 用来保存 this
- 使用ES6箭头函数来解决
普通函数中的 this 默认指向全局对象 window
原因在于在非严格模式下调用普通函数时,其实相当于用window调用
function test(){ console.log(this) } test() // 在非严格模式下,其实相当于window.test()
通过设置 JavaScript 的“严格模式”来解决。在严格模式下,默认执行一个函数,其函数的执行上下文中的 this 值是 undefined
参考
https://baijiahao.baidu.com/s?id=1654439123803195885&wfr=spider&for=pc
浏览器原理与实践