美文网首页
JS中call,apply和bind的用法

JS中call,apply和bind的用法

作者: 男人宫 | 来源:发表于2022-12-19 09:09 被阅读0次
        // call,apply和bind都可以改变函数的this指向
    let obj1 = {
      name:"obj1",
      fn1(param){
      console.log(this.name,param,"-----");
      }
    }
    
    let obj2 = {
      name:"obj2",
      fn1(param){
        console.log(this.name,param,"++++++");
      }
    }
    
    //call、apply、bind的作用是改变函数运行时this的指向
    
    //正常调用
    // obj1.fn1("param1") //输出obj1 param -----
    
    //call apply的第一参数都是this绑定的对象,如果第一个参数不传,或者传null,undefined.那么this的指向为window
    //区别点:call的第二个参数传入的是参数列表,而apply传入的是数组
    //参数列表:"param","param1","param2" 数组:["param","param1","param2"]
    //call apply则立即调用
    //bind会返回一个有this指向的新函数 用于后续调用
    obj1.fn1.call(obj2,"param") //输出obj2 param -----.是因为call把fn1里面的this指向指向了obj2
    
    
    // 错误Uncaught TypeError: obj1.call is not a function.调用call的是需要一个函数
    // obj1.call(obj2,"param")
    
    obj1.fn1.apply(obj2,["param3"]) //输出:obj2 param3 -----
    
    //bind
     let newFn =  obj1.fn1.bind(obj2,"param4")
     console.log(newFn); /*输出:f fn1(param){
      console.log(this.name,param,"-----");
      } 
      注意虽然看着和fn1的函数一样,但这个新函数的this指向已经发生了变化*/
      newFn() //输出: obj2 param4 -----
      obj1.fn1("param") //输出:obj1 param -----  可以看出原来的函数不受影响的
    

    练习

    function a(){
        console.log(this
        );
      }
      function b(){}
      var c = {name:"call"}
    
      a.call() //第一个参数不传 则指向window
      a.call(null) //指向window
      a.call(undefined) //指向window
      a.call(1) //Number {1}
      a.call("") //String {''}
      a.call(true) //Boolean {true}
      a.call(b)  //ƒ b(){}
      a.call(c) //{name: 'call'}
      
    
      // ------------------------
    
      function class1(){
        this.name = function(){
          console.log("我是class1的内部方法");
        }
      }
    
      function class2(){
        //此行代码执行后,当前的this指向了class1(也可以说class2继承了class1)
        //理解:class2中的this指向了class1,那么class2的实例可以用class1函数中的所有属性和方法
        //this的这个指向相当于oc中的isa指针
        class1.call(this)
      }
    
      var f = new class2()
      //class2自身没有这个方法.但this指向了class1,class1中有.就是用了class1中的
      f.name()  //我是class1的内部方法
    
    
      //-------------
      function eat(x,y){  
        console.log(this,"----"); 
        console.log(x+y);      
       }   
      function drink(x,y){   
        console.log(this,"++++"); 
        console.log(x-y);   
       }   
      eat.call(drink,3,2); //输出结果5.注意:调用eat.call(...)只是改变了函数内部的this指向.
    
      //----------------
    
      function Animal(){   
      this.name="animal";   
      this.showName=function(){   
        console.log(this.name);   
      }   
      }   
      function Dog(){   
      this.name="dog";   
      }   
      var animal=new Animal();   
      var dog=new Dog();       
    
      animal.showName.call(dog);
       //输出dog.把animal.showName()的内部this的指向指到了Dog这个对象
      //或者另外一种理解:animal把showName方法放到了dog对象内部
    
    // ---------------
    //类似这种否早函数中绑定this的,简单理解直接把调用这的属性好人方法复制拷贝到了当前对象中
    function Animal(name){  
      // 通过 Animal.call(this,name);之后,这里的this就指向了Dog.从此就有了dog.name,dogshowName()这些属性和方法   
      console.log(this,"----"); 
      this.name=name;   
      this.showName=function(){   
        console.log(this.name);   
      }   
    }   
    function Dog(name){   
       Animal.call(this,name);   
       /*
       Animal.call(this,name);
       也相当于把Animal中的这些放到这里
       this.name=name;   
       this.showName=function(){   
        console.log(this.name);   
      }   
       */
    }   
    var dog=new Dog("Crazy dog");   
    dog.showName(); ///Crazy dog
    
    //--------bind和call.apply的用法最大的区别是,bind是返回了一个新的函数
    var bar=function(){   
      console.log(this.x);   
    }
    var foo={ 
         x:3   
    }   
    bar();  
    bar.bind(foo)();
     /*或*/
    var func=bar.bind(foo);   
    func();
    
    //输出:
    //undefined
    //3
    

    相关文章

      网友评论

          本文标题:JS中call,apply和bind的用法

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