美文网首页
关于函数 call() bind() apply()

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

作者: Gaarahan | 来源:发表于2019-01-26 14:07 被阅读0次

    写过一点关于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
    

    相关文章

      网友评论

          本文标题:关于函数 call() bind() apply()

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