前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >疯了!js中this到底指向什么?

疯了!js中this到底指向什么?

作者头像
半月无霜
发布2023-03-03 14:28:40
9140
发布2023-03-03 14:28:40
举报
文章被收录于专栏:半月无霜半月无霜

疯了!js中this到底指向什么?

一、前言

前段时间,公司让我改一个界面,我心想改个界面还不简单吗?结果呃,我低估了这颗炸弹的威力。

好吧是我太菜,总结一下,这个this的指向问题。

二、测试例子

首先说明一点。在js中,this的指向在定义函数的时候是确定不了的,只有在使用这个函数的时候才能确定this的指向。

一般来说在使用时,谁调用的这个函数,函数中的this就指向它。

2.1)普通函数

代码语言:javascript
复制
var username = "BANMOON";
let age = 18;
function showInfo(){
    console.log(username);// BANMOON
    console.log(this.username);// BANMOON

    console.log(age);// 18
    console.log(this.age);// undefined
}
showInfo();
// window.showInfo();
image-20220228170121758
image-20220228170121758

这里还涉及到varlet的区别,

  • let的作用域是在当前的代码块中,且它挂载的对象是script,而不是window
  • var的作用域是在全局,且挂载与window

由于上面两个区别,所以可以看到直接运行普通函数,其中的this是指向window的。

你可以把11行放开,这是一样的效果

2.2)对象函数

代码语言:javascript
复制
let me = {
    username: "BANMOON",
    age: 18,
    showName: function(){
        console.log(this.username);
    }
}
me.showName();// BANMOON
image-20220228171047113
image-20220228171047113

好的,和上面的呈现了不一样的效果。对象中的函数,在运行时this指向了me这个对象。

我们可以再加点料

代码语言:javascript
复制
var showName = me.showName;
showName();// undefined
image-20220228171425765
image-20220228171425765

这次又变成了undefined,我们现在再回去看看刚刚解释的那句话。

在js中,this的指向在定义函数的时候是确定不了的,只有在使用这个函数的时候才能确定this的指向。

这样,我稍微能理解点了,简单的来说就是谁调用的这个函数,函数里面的this就指向谁。

image-20220228172502346
image-20220228172502346

如果真的这么简单就好了,别急还有

2.3)构造函数

代码语言:javascript
复制
var Person = function(name, age){
    this.name = name;
    this.age = age;

    this.getName = function(){
        return this.name;
    }

    this.getFirendName = function(){
        return this.firend.getName();
    }
}

let me = new Person("BANMOON", 18)
    me.firend = new Person("阿超", 18);

console.log(`我的名字:${me.getName()}`);// BANMOON
console.log(`朋友的名字:${me.getFirendName()}`);// 阿超
image-20220228173338770
image-20220228173338770

这里没有什么好说的,同样查看谁起调的函数就好了。谁调用的那个函数,函数中的this就指向它

代码语言:javascript
复制
var User = function(username){
    this.username = username;
    this.getName = function(){
        return this.name;
    }
    return new Person("阿超", 18);
}
let user = new User("BANMOON");
console.log(user.getName());// 阿超
image-20220228173805575
image-20220228173805575

这段代码,为什么又会变成阿超呢?主要是这段函数出现了返回值,它把Person对象返回了。

所以在外部看来,user是User这个函数创建的一个对象,但实际上已经被掉包成了Person的一个对象。所以这时候,this的真正指向就是返回的那个对象。

2.4)setTimeout,apply等方法

代码语言:javascript
复制
var username = "九月";
let me = {
    username: "BANMOON",
    showName: function(){
        console.log(this.username);
    }
}
me.showName();// BANMOON

setTimeout(me.showName, 0);// undefined
image-20220228224723702
image-20220228224723702

第八行大家都知道,适应上面的逻辑,没有什么问题。可就是这个第十行,怎么就输出了九月了呢。

为什么this会指向window,请注意第10行,传入的是一个函数,me.showName没有括号。如此,这段的解释就是,在window环境下启用这个定时器,将立刻执行me.showName这个函数。

由此来看,定时器启动的函数中的this都是指向与window。我们再来看这个

代码语言:javascript
复制
var username = "九月";
let me = {
    username: "BANMOON",
    showName: function(){
        console.log(this.username);
    },
    showName2: function(){
        setTimeout(this.showName, 0)
    }
}
me.showName();// BANMOON
me.showName2();// 九月
image-20220228224723702
image-20220228224723702

如果一定要使用定时器,又不想它指向window,那该怎么办呢?

applycallbind可以解决this指向的问题

代码语言:javascript
复制
var username = "九月";
let me = {
    username: "BANMOON",
    showName: function(){
        console.log(this.username);
    },
}

let showName = me.showName;
setTimeout(function(){
    showName.apply(me);
}, 0);// BANMOON

setTimeout(function(){
    showName.call(me);
}, 0);// BANMOON

setTimeout(function(){
    let show = showName.bind(me);
    show();
}, 0);// BANMOON
image-20220228230640516
image-20220228230640516

关于他们的具体使用,本文不做详述。只是将this想指向的对象作为上面函数的参数即可。

2.5)箭头函数

代码语言:javascript
复制
var username = "阿超";
let me = {
    username: "BANMOON",
    showName: () => {
        console.log(this.username);
    },
}
me.showName();// 阿超

let aother = {
    username: "BANMOON",
    showName: function(){
        console.log(this.username);
    }
}
aother.showName();// BANMOON
image-20220228231715405
image-20220228231715405

下面那个很好理解,this指向的就是aother

那么上面的箭头函数该如何理解呢。其实是这样,箭头函数没有this,它的this来源于上一个,是继承于外面的环境。

所以me.showName()调用时,me不再生效,this将指向于window

你说箭头函数套娃?那么遇到一个往上找一个环境,直到不是箭头函数为止。

三、结语

上面的this指向,网上很有多,但我平常没有在意。用到的时候,发现储备不足。

就这样吧,我整理了一下,希望可以帮到自己。

我是半月,祝你们幸福!!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 疯了!js中this到底指向什么?
    • 一、前言
      • 二、测试例子
        • 2.1)普通函数
        • 2.2)对象函数
        • 2.3)构造函数
        • 2.4)setTimeout,apply等方法
        • 2.5)箭头函数
      • 三、结语
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档