深度解析this关键字和this绑定

63 阅读2分钟

this是一个关键字,是一个引用,是一个变量,保存内存地址指向自身。

我们为什么要用this关键字

因为this以一个优雅的方式隐式传递了一个对象的引用,提高了代码的复用性。

this绑定

1.默认绑定

  • 函数在哪个词法环境中生效,函数的this就指向哪里。(词法环境就是当一个函数声明在哪里,它的词法环境就是哪里)
function foo(){
    console.log(this.a);
}
function bar(){
    var a = 1
    foo()
}
function baz(){
    var a = 2
    bar()
}
var a = 3
baz()

在这段代码中foo()函数在bar()函数中生效,因此它的词法环境就是bar()函数体中,bar()函数定义在全局中,因此console.log出来的a的值就是undefined。

  1. 隐式绑定
  • 当函数被某个对象拥有时,触发隐式绑定规则。会把函数中的this绑定到对象当中
<script>
    function foo(){
        console.log(this.a);
    }

    var obj = {
        a:2,
        foo:foo//foo的引用
    }

    var obj2 = {
        a:42,
        foo:foo//foo的引用
    }
    var obj1 = {
        a:2,
        obj2:obj2//foo的引用
    }
   obj.foo()//拿到的是2

</script>

在这段代码中foo函数被定义的对象所拥有,因此在这里触发this的隐式绑定规则,而不会触发默认绑定规则。就会将this绑定到对象中,最终拿到的就是对象中的对应值。

  1. 隐式丢失
  • 多次引用函数,最终函数调用前没有上下文对象,就会造成隐式丢失,从而走默认绑定
<script>
    function foo(){
        console.log(this.a);
    }
    var obj = {
        a:2,
        foo:foo
    }
    var bar = {
        a:3,
        bar:obj.foo//这样就没有隐式丢失
    }
    bar.bar()
</script>

bar.bar()//指向全局,引用关系多次引用,这个叫做隐式丢失,这里就要走默认绑定规则

  1. 显示绑定
  • call 修改函数的this指向,接收零散的参数
  • apply 修改函数的this指向,参数以数组形式接收
  • bind 修改函数的this指向,会返回一个新的函数,接收零散的参数
<script>
    function foo(x,y){
        console.log(this,x + y);
    }

    var obj = {
        a:2
    }

    // foo.call(obj ,1,2)//显式访问
    // foo.apply(obj,[2,3])//传参的方式不一样
    // var bar = foo.bind(obj,2,3)//返回的是函数体
    // bar(2,3)//2 3 放这里或者放上面

    foo.call()//window对象,如果什么都不传递,就算里面是null也是
</script>

箭头函数(特例)

  • 箭头函数本身没有this这个概念,没有这个关键字可用,写在其内部的this也是其外部的非箭头函数的this
<script>
    function foo(){}
    ()=>{}//箭头函数是这样写的

    var bar = (x,y)=>{
        return x +y;
    }
</script>

读到这里如果对您有点用的话希望给小白一个点赞!