这篇文章告诉你JavaScript中的this到底指向哪?

244 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

麻烦各位动动小手点个赞吧

相信和能多同学在学习JavaScript的过程中,对this的了解模模糊糊,了解12,不了解89,这篇文章是根据自己学习this,总结下来的关于this的一些知识,其中会带有代码示例,如有错误请指正。

this是什么?是关键词;也是对象

想要知道this的指向,首先得清楚this绑定对象的四个规则

this绑定的四个规则

1.默认绑定:this所处的词法作用域在哪生效了,this就绑定在哪里

var a = 1
function fn(){
    console.log(this.a);
}
fn()   // 1

因为这里函数在全局被调用,所以函数中的this指向全局window,所以 this.a能打印‘1’

微信图片_20220713131620.png

默认绑定也有一个需要注意的地方,就是this在严格模式下,无法进行默认绑定

2.隐式绑定:当函数引用有上下文对象时,隐式绑定中的规则就会把函数调用中的this绑定到这个上下文对象

var a = 1
function fn(){
    console.log(this.a);
}
var obj={
    a:2,
    fn:fn
}
obj.fn() // 2

此时函数在obj中被引用,this被隐式绑定到被引用的上下文对象,也就是obj,所以this.a==obj.a

3.隐式丢失:当隐式绑定的函数,丢失了绑定的对象,this就会默认绑定

function fn(){      
    console.log(this.a);    
}
function foo(fn){
    var a = 123
    fn()
}
var obj={
    a:2,
    fn:fn
}
var a = 'global'
foo(obj.fn) //  global

让我们来逐行分析代码:1.首先声明了一个函数fn ;2.声明一个函数foo ;3.声明一个对象obj{} ; 4.函数调用foo()

首先我们可以知道,fn在对象obj中引用,但是obj并没有 立即调用fn,而是作为形参传进一个新函数foo中调用,于是导致了隐式丢失,也就是this此时又恢复了默认绑定,绑定到全局,所以this.a会打印‘global’

在隐式绑定后,被绑定对象没有立即调用fn,而是再次发生多次引用或者传递会导致隐式丢失,恢复默认绑定

4.显示绑定:call,apply,bind可以强行指定函数的this指向

function fn(){
    console.log(this.a);
}
let obj1 = {
    a:'this被绑定到了obj1'
}
let obj2 = {
    a:'this被绑定到了obj2'
}
let obj3 = {
    a:'this被绑定到了obj3'
}
fn.call(obj1)       //this被绑定到了obj1
fn.apply(obj2)      //this被绑定到了obj2
fn.bind(obj3)()     //this被绑定到了obj3

可以看出我们也可以使用Js自带的this显示绑定方法 其次我们需要注意的是,这三个方法的传参也是有不同的

  • fn.call(obj1,parameter1,parameter2,parameter3...) call()第一个参数为this绑定对象,后面开始是形参

  • fn.apply(obj2,[parameter1,parameter2,parameter3...]) apply()只有两个参数,第一个是this的绑定对象,第二个数组,数组中包含了所有需要传的形参

  • fn.bind(obj3)(parameter1,parameter2,parameter3...) bind()方法返回的就是一个函数,所以参数传递与原函数相同

值得一提的是,es6中的箭头函数 fn(()=>{})是没有this的,箭头函数中的this并不是自己的this,是全局的this

微信图片_20220713142159.png 所以箭头函数无论在哪被调用,被引用,它本身并没有this,打印的this是全局