一起走走this关键字走过的路——this的指向问题

文摘   2024-06-25 09:51   上海  

小美是一个白富美,她想在代码美如画的程序员小金面前介绍自己——你好,我叫小美,我今年十八岁,上得厅堂下得厨房,能当爸也能当妈,会赚钱也很顾家。这样小金就被深深吸引,然后嫁入豪门......小红也是白富美,但是她是这样介绍自己的——小红,小红十八岁,小红会做饭,小红很会赚钱......小金听完就回答小红:你是一个好人,但是我们不适合......

同样是白富美,为何小金喜欢小美,因为小金的代码美如画,他熟练的运用this关键字。接下来,让我们一起学习this的指向问题。

一、this的使用场景

- 在全局中

在全局作用域中,this指向全局对象。在浏览器环境中,全局对象是window,Node.js中则是global。

image.png

- 在函数作用域中

函数中的this指向取决于函数的调用方式

1、函数的独立调用,触发的是默认绑定规则,该函数的this指向window/全局(global)。

image.png

2、函数被某个对象所拥有,或者函数被某个上下文对象调用时,触发隐式绑定规则,该函数中的this指向该上下文对象。

image.png

下面的情况有所不同,这是将函数调用返回的结果赋值给foo,然后访问对象的属性foo,此时foo并不是一个函数。在非严格模式下,this指向了全局

image.png

3、函数被多个对象链式调用时,this指向最近的那个对象(隐式丢失)

 function foo(){
     console.log(this.a);
 }

 var obj ={
     :1,
     foo:foo
 }
 var obj2 ={
     :2,
     obj:obj
 }
 obj2.obj.foo()
image.png

4、箭头函数:箭头函数不绑定自己的this,它会捕获其所在上下文的this值作为自己的this值。这意味着在箭头函数中,this的值是在定义函数时确定的,而非调用时。

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

5、显示绑定: 通过call,apply,bind方法,将函数的this“强行掰弯”到一个对象中。

var obj ={
    a:1
}
function foo(){
    console.log(this.a);
}
foo.call(obj)
image.png

注: 下面代码是call方法的实现原理,感兴趣的小伙伴可以提前了解一下。

var obj ={
    a:1
}
function foo(){
    console.log(this.a);
}
Function.prototype.mycall = function(){
    //拿到foo
    //将foo引用到obj上
    //让obj触发foo
    //移除掉obj身上的foo
    //arguments
    const context = arguments[0]
    const args = Array.from(arguments).slice(1//[]
    
    context.fn=this
    context.fn()   
    const res = context.fn(...args)
    delete context.fn
    return res
}

let res =foo.mycall(obj,4,5)
console.log(res);

其内部的核心还是通过隐式绑定规则来实现的。

6、new绑定:this指向实例对象

function Person(){
//new的实现过程
    // let obj ={
    //     name:'平平'
    // }
    // Person.call(obj)
    // // obj_proto_ = Person.prototype
    // return obj
    this.name ='平平'
    return 'hello'
}
let p = new Person() //{name:'平平'}
console.log(p.name);
image.png

如果你明白了new的实现过程,就很轻松的理解上面的绑定规则了

原文: https://juejin.cn/post/7377694677275344896



web前端进阶
坚持原创,分享前端技术文章。
 最新文章