美文网首页
JavaScript的this(三)call,apply,bin

JavaScript的this(三)call,apply,bin

作者: 踏莎行 | 来源:发表于2021-11-25 17:58 被阅读0次

    使用bind,apply,call改变函数中this的指向

    首先先举个例子

    var a = 20
    
    function test(){
      console.log(this.a); // 20
    }
    
    test()
    

    向上面这样直接执行函数,函数内部的this默认是指向全局的,在浏览器中这个this就指向window,所以this.a = 20

    通过call,apply,bind方法可以改变函数内部this的指向

    • call , apply
    var obj1 = {
      name: "obj1"
    }
    
    var obj2 = {
      name: "obj2"
    }
    
    var name = "全局的name"
    
    function printName(a, b) {
      console.log(this.name, a, b);
    }
    
    
    printName.call(obj1, 1, 2) // obj1 1 2
    printName.call(obj2, 3, 4) // obj2 3 4
    
    printName.apply(obj1, [5, 6]) // obj1 5 6
    printName.apply(obj2, [7, 8]) // obj2 7 8
    

    call和apply的区别就在于传递参数的形式不同,第一个参数都是你想为函数指定的this,call的参数就直接以逗号隔开的方法直接写参数,而apply是以数组的形式进行传参

    // call
    function.call(thisArg, arg1, arg2, ......)
    
    // apply
    function.apply(thisArg, [arg1, arg2, ......])
    

    两者的返回值都是调用call或者apply方法的函数的返回值结果,没有返回值那就是undefined

    function test(){
      return "哈哈哈"
    }
    
    function test1(){
      return true
    }
    
    console.log(test.apply()); // 哈哈哈
    console.log(test1.call()); // true
    

    不过在指定this的时候,也可以指定是null或者undefined,不过只有在严格模式下才是真正将this指定为null或者undefined,非严格模式下,自动替换成全局对象

    function test() {
      console.log(this);
    }
    
    test.call(null) // window
    
    var a = "haha"
    
    function test() {
      console.log(this.a); // haha
    }
    
    test.call(null)
    
    • bind 方法

    bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用 (mdn)

    它的参数同call方法

    function.bind(thisArg, arg1, arg2, ......)
    

    不同的就是返回值了,bind调用后返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。

    说白了,就是返回了一个新的函数,这个函数中才被绑定了你指定的this和参数,call和apply调用就执行了,bind需要手动调用返回的函数才行

    var name = "全局的"
    var obj = {
      name: "obj的"
    }
    
    function test(n, m) {
      console.log(this.name, n, m);
    }
    
    var newFn = test.bind(obj, 1, 4)
    
    console.log(newFn);
    // ƒ test(n, m) {
    //   console.log(this.name, n, m);
    // }
    
    newFn() // obj的 1 4
    

    注意:bind只能绑定一次,不能再给bind返回的函数再执行bind,结果始终是以第一次绑定为准

    var name = "全局的"
    var obj = {
      name: "obj的"
    }
    
    var obj2 = {
      name: "obj2的"
    }
    
    function test(n, m) {
      console.log(this.name, n, m);
    }
    
    var newFn = test.bind(obj, 1, 4)
    newFn() // obj的 1 4
    
    var newFn1 = newFn.bind(obj2, 2, 3)
    newFn1() // obj的 1 4
    

    this在箭头函数中的指向

    箭头函数比较特殊,其内部并没有this绑定,它能访问到的this其实是
    该函数所在的作用域指向的对象,所以大家要对作用域有所了解。箭头函数也不可以做构造函数

    • 全局下
    var test = () => {
      console.log(this); // window
    }
    
    test()
    
    function test() {
      var innerTest = () => {
        console.log(this); // window
       }
    
      innerTest()
    }
    
    test()
    
    • 对象
    var name = "全局下的name"
    var obj = {
      name: "obj的name",
      logName: function(){
         console.log(this.name); // obj的name
      },
      printName: () => {
        console.log(this.name); // 全局下的name
      }
    }
    obj.printName()
    

    看到这个结果,部分同学们是不是有点小意外,箭头函数printName的this还是指向window,不是谁绑定他就指向谁。现在改一下:

        var name = "全局下的name"
        var obj = {
          name: "obj的name",
          outFn: function () {
            console.log(this);  // {name: 'obj的name', outFn: ƒ}
            var printName = () => {
              console.log(this.name); // obj的name
            }
    
            printName()
          }
        }
    
        obj.outFn()
    

    此时箭头函数printName在普通函数outFn里面,outFn的作用域的this就是指向调用它的对象

    • 静态this指向
        var a = 1
        var obj = {
          a: 2
        }
    
        var test = () => {
          console.log(a);
        }
    
        test() // 1
        test.call(obj) // 1
        test.apply(obj) // 1
        test.bind(obj)() // 1
    

    箭头函数里面的this就是指向其当前作用域指向的this,不接受通过call等方法进行this修改。

    我觉得也可以这样理解,箭头函数它在找this的时候,从里向外找,找到非箭头函数的作用域

    若理解有误,希望大家批评指正

    相关文章

      网友评论

          本文标题:JavaScript的this(三)call,apply,bin

          本文链接:https://www.haomeiwen.com/subject/xaoxultx.html