前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript中的this(保证学会)

JavaScript中的this(保证学会)

作者头像
一行舟
发布2022-08-25 14:00:23
2510
发布2022-08-25 14:00:23
举报
文章被收录于专栏:一行舟

虽然this在JavaScript中是一个老生常谈的问题,但实际场景中还是很容易出错。主要原因是this对象在JavaScript中和其他语言相比表现不太一致,而且在不同的运行环境中表现也不一致。今天我们就把浏览器中的this对象彻底聊明白,记清楚。

本文我们只讨论JavaScript在浏览器、非严格模式下this表现,在其他执行环境(比如Node.js)this的表现又不太一样了。

我们分几种情况来看

普通的函数调用

代码语言:javascript
复制
function f(){
    console.log(this === window) // 打印:true
}
f();

普通的函数调用this就是window对象,我们可以这样理解 f() 就等价于window.f()。

我们修改一下上面的例子

代码语言:javascript
复制
function f(){
    console.log(this === window) // 打印:true
}

function f1(){
    f()
}
f1()

此时仍然打印true,因为虽然f方法在f1方法中调用,但是调用f()方法的前面仍然是省略的Window对象,所以this还是Window。

函数赋予某个自变量

代码语言:javascript
复制
function f(){
    console.log(this) // 打印:{fun: ƒ}
}
obj={
    fun: f
}
obj.fun();

此时this输出的是obj对象,即调用f方法的对象。

通过以上两种情况你肯定感觉自己已经完全理解this对象了。那我们把上面的例子稍微改造一下。

代码语言:javascript
复制
function f(){
    console.log(this) // 打印:Window对象
}
obj={
    fun: f
}
let objf = obj.fun;
objf();

此时this打印出来又成了Window对象,是不是让你大跌眼镜。我们可以这样去理解,objf()就等价于window.objf(),调用上下文自然就变成了Window, 和前两个例子的表现并不冲突。this要看最终调用方法的对象。

原型链中的this

代码语言:javascript
复制
let obj = {
    f : function(){
        console.log(this)  
    }
}
let obj1 = Object.create(obj);
obj1.s = 100;
obj1.f(); // 打印obj1对象

原型链中,this是调用方法的对象,和前面几个例子的表现一致。

多层级调用时的this

代码语言:javascript
复制
let obj = {
    s: 200,
    f : function(){
        console.log(this)  
    }
}
let obj1 = {
    obj: obj,
    s: 100
}
obj1.obj.f() // 打印obj对象

通过打印结果可以看出,this是obj对象。「存在多层调用时,this是最靠近f()方法的对象」

使用new实例化对象

代码语言:javascript
复制
function f(){
    console.log(this) // 打印:f方法对象
}

let obj=new f();

使用new实例化对象时,this代表被实例化的对象。

bind、apply和call方法

代码语言:javascript
复制
function f(){
    console.log(this) // 打印:f方法对象
}
f(); // 打印Window对象
let obj={a:10};
let r = f.bind(obj); 
f(); // 打印Window对象
r(); // 打印obj对象
f.apply(obj,[]); // 打印obj对象

bind方法会返回一个和f方法有相同函数体和作用域的函数,同时this对象永久的绑定在obj对象上。不管任何调用方式,this都是obj对象。但是这并不会对f方法本身产生影响,所以f()方法直接调用时,还是返回了Window对象。

apply方法也有改变执行上下文的作用,apply的第一个参数就是函数的执行上下文,所以打印了obj对象。call方法和apply雷同就不赘述了。

箭头函数

箭头函数的作用非常简单,就是让箭头函数内的this对象和箭头函数外面的上下文保持一致。

总结

上面场景看起来很多,其实总结起来很简单。「不显式指定调用对象时,相当于调用省略了window,this都是window对象;当显式指定调用对象时,this是最靠近调用函数的对象」。当然对于bind、apply、call方法单独记忆就好了,因为这三个函数本身就是为了改变this指向。箭头函数就是为了不改变this指向。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一行舟 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 普通的函数调用
  • 函数赋予某个自变量
  • 原型链中的this
  • 多层级调用时的this
  • 使用new实例化对象
  • bind、apply和call方法
  • 箭头函数
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档