JavaScript中的call、apply、bind

简介: JavaScript中的call、apply、bind

call、apply、bind


那了解了函数 this 指向的不同场景之后,我们知道有些情况下我们为了使用某种特定环境的 this 引用,这时候时候我们就需要采用一些特殊手段来处理了,例如我们经常在定时器外部备份 this 引用,然后在定时器函数内部使用外部 this 的引用。


然而实际上对于这种做法我们的 JavaScript 为我们专门提供了一些函数方法用来帮我们更优雅的处理函数内部 this 指向问题。


那就是 call、apply、bind 三个函数方法。


  • 作用:可以改变this的指向


call


call() 方法调用一个函数, 其具有一个指定的 this 值和分别地提供的参数(参数的列表)。


注意:该方法的作用和 apply()方法类似,只有一个区别,就是 call() 方法接受的是若干个参数的列表,而 apply() 方法接受的是一个包含多个参数的数组。


语法:


fun.call(thisArg[, arg1[, arg2[, ...]]])


参数:


  • thisArg


在 fun 函数运行时指定的 this 值


如果指定了 null 或者 undefined 则内部 this 指向 window


  • arg1, arg2, ...


指定的参数列表


apply


apply() 方法调用一个函数, 其具有一个指定的 this 值,以及作为一个数组(或类似数组的对象)提供的参数。


注意:该方法的作用和 call() 方法类似,只有一个区别,就是 call() 方法接受的是若干个参数的列表,而 apply() 方法接受的是一个包含多个参数的数组。


语法:


fun.apply(thisArg, [argsArray])


参数:


  • thisArg


  • argsArray


apply() 与 call() 非常相似,不同之处在于提供参数的方式。


apply() 使用参数数组而不是一组参数列表。例如:


fun.apply(this, ['eat', 'bananas'])


apply和call的使用案例



<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
  <script>
    //apply和call的使用
    //作用:可以改变this的指向
   function f1(x,y) {
     console.log("结果是:"+(x+y)+this);
     return "10000";
   }
   f1(10,20);//函数的调用
    console.log("========");
    //此时的f1实际上是当成对象来使用的,对象可以调用方法
    //apply和call方法也是函数的调用的方式
    f1.apply();
    f1.call();
    console.log("==========");
    f1.apply(null);
    f1.call(null);
    //apply和call方法中如果没有传入参数,或者是传入的是null,那么调用该方法的函数对象中的this就是默认的window
    f1.apply(null,[100,200]);
    f1.call(null,100,200);
    //apply和call都可以让函数或者方法来调用,传入参数和函数自己调用的写法不一样,但是效果是一样的
   var result1=f1.apply(null,[10,20]);
   var result2=f1.call(null,10,20);
   console.log(result1);
   console.log(result2);
   console.log("==============================");
//    function f1(x,y) {
//      console.log("这个函数是window对象的一个方法:"+(x+y)+this.sex);
//    }
//    window.f1(10,20);
//    //obj是一个对象
//    var obj={
//      age:10,
//      sex:"男"
//    };
//
//    window.f1.apply(obj,[10,20]);
//    window.f1.call(obj,10,20);
//    console.dir(obj);
    //apply和call可以改变this的指向
    function Person(age,sex) {
      this.age=age;
      this.sex=sex;
    }
    //通过原型添加方法
    Person.prototype.sayHi=function (x,y) {
      console.log("您好啊:"+this.sex);
      return 1000;
    };
    var per=new Person(10,"男");
    per.sayHi();
    console.log("==============");
    function Student(name,sex) {
      this.name=name;
      this.sex=sex;
    }
    var stu=new Student("小明","女");
    var r1=per.sayHi.apply(stu);
    var r2=per.sayHi.call(stu);
    console.log(r1);
    console.log(r2);
  </script>
</head>
<body>
</body>
</html>


bind


bind() 函数会创建一个新函数(称为绑定函数),新函数与被调函数(绑定函数的目标函数)具有相同的函数体(在 ECMAScript 5 规范中内置的call属性)。


当目标函数被调用时 this 值绑定到 bind() 的第一个参数,该参数不能被重写。


绑定函数被调用时,bind() 也接受预设的参数提供给原函数。


一个绑定函数也能使用new操作符创建对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。


语法:


fun.bind(thisArg[, arg1[, arg2[, ...]]])


参数:


  • thisArg


当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用new 操作符调用绑定函数时,该参数无效。


  • arg1, arg2, …


当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。


返回值:


返回由指定的this值和初始化参数改造的原函数拷贝。


示例1:


this.x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};
module.getX(); // 返回 81
var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域
// 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81


示例2:


function LateBloomer() {
  this.petalCount = Math.ceil(Math.random() * 12) + 1;
}
// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
  window.setTimeout(this.declare.bind(this), 1000);
};
LateBloomer.prototype.declare = function() {
  console.log('I am a beautiful flower with ' +
    this.petalCount + ' petals!');
};
var flower = new LateBloomer();
flower.bloom();  // 一秒钟后, 调用'declare'方法


小结


  • call 和 apply 特性一样


都是用来调用函数,而且是立即调用


但是可以在调用函数的同时,通过第一个参数指定函数内部 this 的指向


call 调用的时候,参数必须以参数列表的形式进行传递,也就是以逗号分隔的方式依次传递即可


apply 调用的时候,参数必须是一个数组,然后在执行的时候,会将数组内部的元素一个一个拿出来,与形参一一对应进行传递


如果第一个参数指定了 null 或者 undefined 则内部 this 指向 window


  • bind


可以用来指定内部 this 的指向,然后生成一个改变了 this 指向的新的函数


它和 call、apply 最大的区别是:bind 不会调用


bind 支持传递参数,它的传参方式比较特殊,一共有两个位置可以传递


   在 bind 的同时,以参数列表的形式进行传递


   在调用的时候,以参数列表的形式进行传递

   那到底以谁 bind 的时候传递的参数为准呢还是以调用的时候传递的参数为准


   两者合并:bind 的时候传递的参数和调用的时候传递的参数会合并到一起,传递到函数内部


相关文章
|
1月前
|
JavaScript 前端开发
javascript中的call和apply
javascript中的call和apply
|
1月前
|
JavaScript
JS中call()、apply()、bind()改变this指向的原理
JS中call()、apply()、bind()改变this指向的原理
|
1月前
|
JavaScript 前端开发
javascript中的bind
javascript中的bind
|
3月前
|
JavaScript 前端开发 API
掌握apply和call,解密JavaScript的this指向
掌握apply和call,解密JavaScript的this指向
|
3月前
|
前端开发 JavaScript Java
【面试题】JavaScript 中 call()、apply()、bind() 的用法
【面试题】JavaScript 中 call()、apply()、bind() 的用法
|
3月前
|
前端开发 JavaScript
【面试题】 JavaScript 中 call()、apply()、bind() 的用法
【面试题】 JavaScript 中 call()、apply()、bind() 的用法
|
4月前
|
JavaScript 前端开发
JavaScript中call()与apply()的作用与区别?
JavaScript中call()与apply()的作用与区别?
|
9月前
|
JavaScript 前端开发
JavaScript call、apply 和 bind 的区别
JavaScript call、apply 和 bind 的区别
|
5月前
|
JavaScript 前端开发
js中call 和 apply的区别
js中call 和 apply的区别
33 0
|
JavaScript 前端开发
JavaScript中call与apply的区别
JavaScript中call与apply的区别
125 0