this详解

 

原因

在对象内部的方法中使用对象内部的属性是一个非常普遍的需求。但是 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

浏览器原理与实践

原文地址:https://www.cnblogs.com/suihang/p/13395604.html