关于函数 call() bind() apply()

写过一点关于call函数的认识,但隔了一段时间后感觉不是很详尽,再重新研究一下


call apply bind

  1. 注意,箭头函数的this指向是固定的,始终指向函数定义时的对象,而不是使用时的对象
    无法使用这三个函数来为其指定this的指向
  let a = {x:3};
  let func = ()=>{
    console.log(this); 
    //箭头函数没有自己的this,它的this是该函数外层代码块的this
    // 在此处是window对象
  }
  func(); //=> window

  //call()
  func.call(a); // =>window
  //apply
  func.apply(a); // => window
  // bind()
  let func2 = func.bind(a);
  console.log(func2);// => ()=>{console.log(this);}
  func2(); // window

  1. function.call(thisArg,arg1,arg2, ...)
    每个函数都有自己的this指向,使用call方法可以为我们调用的函数指定其this指向
  function con(x){
    console.log(this.a);
  }
  con(1);  //  => undefined
  
  //使用call函数为其指出this指向
  con.call({a:2},1); // => 2
  • 当处于非严格模式时,指定的thisArg为 null undefined时,this会自动指向
    全局对象(浏览器为window,node为global)
  function con(){
    console.log(this); // => Window对象
    return 1;
  }
  let a = con.call(null); 
  console.log(a); // 1
  • 我们可以使用call方法来实现继承
    在JAVA中,我们给出一个Product类,声明类Food继承该Product类
class Product{
  protected String name;
  protected String price;
  public Product(String name,String price){
    this.name = name;
    this.price = price;
  }
}
class Food extends Product{
  private String kind;
  public Food(String name,String price,String kind){
    super(name,price);
    this.kind = kind;
  }
}
Food apple = new Food("apple","15","friut");

在js中,我们可以借助call这样来写

  function Product(name,price){
    this.name = name;
    this.price = price;
  }
  function Food(name,price,kind){
    Product.call(this,name,price);
    this.kind = kind;
  }
  let apple = new Food('apple','15','friut');
  console.log(apple); // => Food{name:'apple',price:'15',kind:'friut'};

对比上面的写法,我们在js中使用了call来调用函数Product,类似与在java中使用super()
函数来调用父类的构造方法

  • call的一个比较常见的用法是在处理类数组对象时,我们可以通过call函数,让其调用
    数组的方法,完成我们需要的操作详细讲解
    例如将类数组对象arguments转化为数组:
  let argsArr = Array.prototype.slice.call(arguments);

使用forEach方法来遍历HTMl collection

  [].forEach.call(htmlCol,(val,index,arra=>{
    console.log(val);
  }))
  1. function.apply(thisArg,[args])
    apply的用法和call差不多,区别在与apply所调用函数的参数是以数组或者类数组方式提供的
    也就是说,call中能使用的地方,都可以使用apply来替代,有时apply写的还更简单
  • 上面的继承使用apply改写
  function Product(name,price){
    this.name = name;
    this.price = price;
  }
  function Food(name,price,kind){
    Product.apply(this,arguments); 
    //这里直接将Food函数的arguments对象传过去,虽然多传了一个参数kind,但在写法上更简单
    this.kind = kind;
  }
  let apple = new Food('apple','15','friut');
  console.log(apple); // => Food{name:'apple',price:'15',kind:'friut'};
  • 将一个数组push到另一个数组中去(使用concat会创建新数组,push不会)
  let a = [1,2,3];
  let b = [4,5,6];
  [].push.apply(a,b);
  console.log(a); // => [1,2,3,4,5,6]
  • 使用max函数找出一个数组中的最大值
  let a = [1,2,3,45,6,7];

  let res = Math.max.apply(null,a);
  console.log(res); // => 45

  //另一种简化写法 : es6
  Math.max(...a); // => 45
  1. function.bind(thisArg,arg1,arg2 ...)
    bind函数不是一次原函数的调用,它会返回一个新的函数,具有指定的this指向,并且在
    调用新函数时,在bind时指定的参数会作为新函数的前几项参数值
  let a = {x:3};
  function func(){
    console.log(this.x);
  }
  func(); //=> undefined

  let func2 = func.bind(a);
  console.log(func2);// => ()=>{console.log(this.x);}
  func2();  // =>3

猜你喜欢

转载自blog.csdn.net/weixin_34194379/article/details/87059145