bind,call,以及apply的理解与使用

bind的理解:

Function.prototype.bind()

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

返回值:返回一个原函数的"拷贝",并拥有指定的 this 值和初始参数。

   //例子
   function demoBind(x){
     console.log('我是第一个demoBind===>',this,x.into);
   }
   demoBind({into:"未绑定bind"}); //window,未绑定bind
   console.log('-------------------->分割线');

   /*
      利用bind创建一个“新的函数”
      const newBind = demoBind.bind("这个新函数的 this 被指定为 bind() 的第一个参数","其余参数将作为新函数的参数,供调用时使用")
      # 这里也就是说bind的第一个参数将作为新函数的this指向,而bind的其他参数将是新函数的其他参数、
      下方例子(拷贝场景):
   */
   const newBind = demoBind.bind({_this:1},{into:"绑定bind"});
   newBind();  //{_this:1},绑定bind
   
   

   /*
     应用场景:需要让this指定自己需要对象的this就可以使用bind方法
   */
   var application = {
    b: function() {
      console.log('b的this指向不出意外是application===>',this); // {c: "hello", b: ƒ}
      const func =function(){
        /*
          在不使用bind的情况下,函数在独立调用时,函数内部的this是指向window的
          console.log(this); // window
        */
        
        /*
          假设我在func里面需要得到c定义的hello,那么在这里就能使用bind来指定this
        */
        console.log(this); //使用了bind之后这里的this就指向了{c: "hello", b: ƒ}
      }.bind(this)  //bind的第一个参数将作为新函数的this指向,我这里传入b的this指向也就是application,所以func的this也就指向了application
      func();
    },
    c: 'hello'
  }
  application.b();
  /*
     -  引用与拷贝的区别
     引用:二者的引用是同一个对象,并没有创建出一个新的对象
          因为是同一个对象的引用,所以两者改一个,另一个对象的值也随之改变

     拷贝:简单来讲就是会创建一个新的对象,改变新的对象的值并不会影响到原对象
   */

call的理解:

Function.prototype.call()

作用:
call() 可以允许为不同的对象分配和调用属于一个对象的函数/方法/属性。
call() 提供新的 this 值给当前调用的函数/方法。你可以使用 call 来实现继承:写一个方法,然后 让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)。

官方原话:
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数

语法参数:function.call(thisArg, arg1, arg2, …)

thisArg:
可选的。在 function 函数运行时使用的 this 值。
请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,
则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。

arg1, arg2, …:
指定的参数列表。

返回值: 得到使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined

    //'use strict';  开启严格模式
    //例子
    function Person(...x) {
      console.log(this,x);
    }
    Person("张三","张三"); //window,["张三","张三"]


    //在thisArg指定为null或undefined的情况下会自动替换为指向全局对象也就是window
    const _call = Person.call(null,"张三","张三","张三")  //window,["张三","张三","张三"]
    //person函数没有返回值,_call为undefined
    console.log(_call); 
      
      //应用例子
	 //调用父构造函数的 call 方法来实现继承
     //假设这是一个父对象
     function Product(name, price) {
        console.log('Product====>',this); //Food
        this.name = name;
        this.price = price;
      }

      function Food(name, price) {
        /*
          这里把this分配到Product里面之后,Product的this就指向了Food
        */
        Product.call(this, name, price); //call() 可以允许为不同的对象分配和调用属于一个对象的函数/方法/属性。
        this.category = 'food';
        this.log =function(){
          console.log(this);//Food {name: "feta", price: 5, category: "food", log: ƒ}
          console.log(name,price,this.category); //feta 5 food
        }
      }

      function Toy(name, price) {
        Product.call(this, name, price);
        this.category = 'toy';
      }

      var cheese = new Food('feta', 5);
      cheese.log();
      var fun = new Toy('robot', 40);

      /*
        要知道如果这个函数处于非严格模式下,
        则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
        但是在严格模式下,this 的值将会是 undefined

        例子:
      */
      var sData = 'Wisen';

      function display() {
        console.log(this);// undefined
        console.log('sData value is %s ', this.sData);  //报错
      }

      display.call(); 

apply的理解:

Function.prototype.apply()

作用:
可以用 apply 将数组各项添加到另一个数组

官方原话:
apply() 方法调用一个具有给定this值的函数,以及以“一个数组(或类数组对象)”的形式提供的参数

thisArg:
同call()的thisArg
argsArray:
可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。
如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。
从ECMAScript 5 开始可以使用类数组对象。

返回值:调用有指定this值和参数的函数的结果 (大概意思同call()方法)

function PersonApply(...x) {
      console.log(this,x);
    }
    PersonApply("张三","张三"); //window,["张三","张三"]


    //在thisArg指定为null或undefined的情况下会自动替换为指向全局对象也就是window
    const _apply = PersonApply.apply({a:1},["张三","张三","张三"])//{a:1},["张三","张三","张三"]
    
    console.log(_apply); //没有返回值  返回undefined

    //作用同call
    //用 apply 将数组各项添加到另一个数组
   /*
     官方例子原话:
      我们可以使用push将元素追加到数组中。由于push接受可变数量的参数,所以也可以一次追加多个元素。

	  但是,如果push的参数是数组,它会将该数组作为单个元素添加,而不是将这个数组内的每个元素添加进去,
      因此我们最终会得到一个数组内的数组。如果不想这样呢?concat符合我们的需求,
      但它并不是将元素添加到现有数组,而是创建并返回一个新数组。
      然而我们需要将元素追加到现有数组......那么怎么做好?难道要写一个循环吗?别当然不是!

      apply正派上用场
      由于push可以一次追加多个元素然后在利用apply的特点:
      apply()会将参数数组转换为一个接一个的参数方式传递给方法
      类似一个循环,在循环apply的数组参数,把它拆成一个一个的item
   */
    var array = ['a', 'b'];
    var elements = [0, 1, 2];
    //array作为this的指向
    array.push.apply(array, elements);
    console.info(array); // ["a", "b", 0, 1, 2]
    /*
      concat也是可以将两个数组合并成为一个数组,但是它并不是将元素添加到现有数组,而是创建并返回一个新数组
    */

总结:

1,call方法和apply方法是函数的引用
2,bind方法是函数的拷贝

3this指向:
    - call,bind,apply的第一个参数都是this的指向,并且第一个参数如果为null或undefined的话都会默认指向全局对象

4,参数:
   - call()方法以及bind()接受的是参数列表,而apply()方法接受的是一个参数数组

5,返回值:
   - bind返回一个原函数的"拷贝",并拥有指定的 this 值和初始参数
   - call方法和apply方法得到使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined

6,call()和apply()会直接调用函数,bind()不会

7,apply()会将参数数组转换为一个接一个的参数方式传递给方法
   /*
     类似一个循环,在循环apply的数组参数,把它拆成一个一个的item
   */
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开发路上的AZhe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值