[浏览器工作原理]--JavaScript中的this指向

lxf2023-05-13 01:33:30

在之前的JavaScript执行机制文章中,提到了变量通过作用域链查找,学习this之前,需要清楚作用域链和this是两套不同的系统,它们之间基本没太多联系

var bar = {
    myName:"time.geekbang.com",
    printName: function () {
        console.log(myName)
        // console.log(this.myName)
    } 
}
function foo() {
    let myName = " foo函数 "
    return bar.printName
}
let myName = " 全局下 "
let _printName = foo()
//" 全局下 "

对象内部的方法中使用对象内部的属性是一个非常普遍的需求。但是 JavaScript 的作用域机制并不支持这一点,基于这个需求,JavaScript 引出另外一套this 机制。

this 是和执行上下文绑定的

执行上下文主要分为三种——全局执行上下文、函数执行上下文和 eval 执行上下文,所以对应的 this 也只有这三种——全局执行上下文中的 this、函数中的 this 和 eval 中的 this。

全局执行上下文

this 和作用域链的唯一交点,作用域链的最底端包含了 window 对象,全局执行上下文中的 this 也是指向 window 对象

函数执行上下文

普通函数中的this指向window,在严格模式下,this 值是 undefined;

对象中的方法this指向方法所属的对象;

构造函数中的this指向new创建的对象;

箭头函数中的 this 取决于它的外部函数(注意,回调函数是对象的方法则this指向全局,而不是对象)

设置上下文中的 this 值

1. 通过函数的 call 方法设置(bind/apply)

2. 通过对象调用方法设置

3. 通过构造函数中设置

this 设计缺陷

1. 嵌套函数中的 this 不会从外层函数中继承

var myObj = {
    name : " 极客时间 ", 
    showThis: function(){
        console.log(this)
        function bar(){console.log(this)}
        bar()
    }
}
myObj.showThis()

要解决这个问题,有两种思路:

第一种是把 this 保存为一个 self 变量,再利用变量的作用域机制传递给嵌套函数;

第二种是继续使用 this,把嵌套函数改为箭头函数,因为箭头函数没有自己的执行上下文,所以它会继承调用函数中的 this。

2. 普通函数中的 this 默认指向全局对象 window

默认指向全局对象会打破数据的边界,造成一些误操作。

如果要让函数执行上下文中的 this 指向某个对象,最好的方式是通过 call 方法来显示调用;

也可以通过设置 JavaScript 的“严格模式”来解决。在严格模式下,默认执行一个函数的执行上下文中 this 值是 undefined,这就解决上面的问题了。

本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!