美文网首页
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