首页前端开发JavaScript你能搞懂JS的this指向问题吗?看看这篇文章

你能搞懂JS的this指向问题吗?看看这篇文章

时间2024-01-31 09:40:03发布访客分类JavaScript浏览1090
导读:收集整理的这篇文章主要介绍了你能搞懂JS的this指向问题吗?看看这篇文章,觉得挺不错的,现在分享给大家,也给大家做个参考。你能搞懂JavaScript的this指向问题吗?下面本篇文章带大家聊聊这令人烦恼的this指向问题,希望对大家有所...
收集整理的这篇文章主要介绍了你能搞懂JS的this指向问题吗?看看这篇文章,觉得挺不错的,现在分享给大家,也给大家做个参考。你能搞懂JavaScript的this指向问题吗?下面本篇文章带大家聊聊这令人烦恼的this指向问题,希望对大家有所帮助!

this的指向

在我们看见的各种介绍如何判断this的指向方法中,"this的最终指向的是那个调用它的对象" 这句话被视作核心,但是面对多种多样的情况,我们容易搞混。针对针对多种情况结合我的理解,我提出了一句话 “箭头,定时和构造,特殊情况特殊看,普通调用看点号,后面有点不看前,然后就近原则判,最后剩下就是window”。【相关推荐:javascript学习教程】

箭头函数

箭头函数的本身没有this,所有不存在this改变,它捕获外层的this使用

VAR name = "windowsName";
var a = {
    name: "Cherry",    fn() {
          setTimeout(()=>
{
            console.LOG(this.name);
       }
,0)    }
}
    a.fn() //Cherry

解析: 首先对象a调用fn函数,所以fn函数的this指向对象a,然后箭头捕获外层this,那么就不是setTimeout里的this,而是fn函数的this,所以最后拿到对象a里的name

定时器

对于延时函数内部的回调函数的this指向全局对象window

var name = "windowsName";
var a = {
    name: "Cherry",    fn() {
      setTimeout(function (){
            console.log(this.name);
       }
,0)    }
}
    a.fn() //windowsName

解析: 首先对象a调用fn函数,然后这里setTimeout里的回调函数是匿名函数,为普通的函数,那么匿名函数中的this指向的就是window

var name = "windowsName";
var b={
  name: "setTimeoutName"}
var a = {
    name: "Cherry",    fn() {
      setTimeout((function (){
            console.log(this.name);
       }
).bind(b),0)    }
}
    a.fn() //setTimeoutName

解析:首先对象a调用fn函数,然后这里setTimeout里的回调函数是匿名函数,为普通的函数,那么匿名函数中的this指向的就是window,但使用bind改变匿名函数的this指向为对象b,所以最后对象b里的name

构造函数

构造函数中的this指向创建的实例对象,

注意:如果构造函数中返回一个对象,创建时不会有新的实例对象,而是这个返回的对象

function fn(){
      this.age = 37;
}
    var a = new fn();
    console.log(a.age);
     // 37a.age = 38;
    console.log(fn);
 // {
     this.age = 37;
 }
    console.log(a.age);
     // 38

解析:这里我们通过构造函数创建实例对象a,相当于开辟一个新地方将构造函数内容复制过来,就有了a对象,这时候this指向的就是对象a,我们修改对象a中内容不影响构造函数

点号判断

通过.判断this指向,遵循就近原则

var a = {
  age:10,  b: {
      age:12,      fn(){
              console.log(this.age);
       }
  }
}
    a.b.fn();
     //12

解析:对象a调用对象b的fn函数,fn函数前面有两个.,那么最近的是对象b,所以fn函数的this指向的就是对象b,最后拿到的就是对象b的age

var a = {
  age:10,  b: {
      age:12,      fn(){
              console.log(this.age);
 //undefined      }
  }
}
var c = {
  age:20,}
var d = {
  age:30,}
    a.b.fn.bind(c).bind(d)();
     //20

解析:对象a调用对象b的fn函数然后使用bind改变this的指向,这时候fn前后前后都有.,不看前面的.,只用看后面的,然后最近的bind改变this指向为c,那么此时fn函数的this指向的就是对象c,拿到的就是对象c的age

练习

function outerFunc() {
   console.log(this) // {
 x: 1 }
   function func() {
    console.log(this) // Window    }
   func()}
 outerFunc.bind({
 x: 1 }
    )()
obj = {
  func() {
        const arrowFunc = () =>
 {
      console.log(this._name)    }
    return arrowFunc  }
,  _name: "obj",}
obj.func()() //objfunc = obj.funcfunc()()  //undefinedobj.func.bind({
 _name: "newObj" }
)()() //newObjobj.func.bind()()() //undefinedobj.func.bind({
 _name: "bindObj" }
).apply({
 _name: "applyObj" }
    )() //bindObj

apply、call、bind

使用 apply、call、bind 函数可以改变this的指向,上面this的例子中使用到

区别

thisarg , [ argsArray] call(thisArg, arg1, arg2, ...)

apply和call函数区别在于this后面传入的参数,apply中传的是一个数组,而call中传入的是展开的参数

bind(thisArg[, arg1[, arg2[, ...]]])()

  • 然后bind函数创建的是一个新的函数,需要手动去调用
  • 这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用

如有错误,请大家指正!!感谢大家阅读!

参考资料

https://juejin.cn/post/6946021671656488991#comment

【相关视频教程推荐:web前端】

以上就是你能搞懂JS的this指向问题吗?看看这篇文章的详细内容,更多请关注其它相关文章!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

this指向"

若转载请注明出处: 你能搞懂JS的this指向问题吗?看看这篇文章
本文地址: https://pptw.com/jishu/593792.html
c程序怎么编写x的y次方 什么是事件循环?详解Node.js中的事件循环

游客 回复需填写必要信息