一个例子看懂 apply 和 call 的作用

513 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

 apply的使用语法

  • 函数名字.apply(对象,[参数1,参数2,...]);
  • 方法名字.apply(对象,[参数1,参数2,...]);

call的使用语法  

  • 函数名字.call(对象,参数1,参数2,...);
  • 方法名字.call(对象,参数1,参数2,...);

作用

  • 作用:都可以改变this的指向
  • 不同点:参数传递的方式是不一样的

只要是想使用别的对象的方法,并且希望这个方法是当前对象的,那么就可以使用apply或者是call的方法改变this的指向

1、函数的正常调用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
  <script>

    //apply和call的使用
    //作用:可以改变this的指向
    // 定义一个函数,正常调用
    function lt1(x,y) {
      console.log("DAY1:"+(x+','+y)+this);
      return "1122";
    }
    lt1(4,10);//函数的调用,当前的this是Window,等同于Window.lt(4,10)


  </script>
</head>
<body>


</body>
</html>

 

2、apply 和 call 的简单调用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
  <script>

  
    //以下lt当成对象来使用的,对象可以调用方法
    //apply和call方法也是函数的调用的方式
    function lt2(x,y) {
        console.log("DAY2:"+(x+','+y)+this);
        return "0409";
    }
    lt2.apply();
    lt2.call();
    lt2.apply(null);
    lt2.call(null);


  </script>
</head>
<body>
</body>
</html>

通过结果可以看出,不传参数和传null时,this的指向没有改变,还是Window

3、apply和call都可以让函数或者方法来调用,传入参数和函数自己调用的写法不一样,但是效果是一样的

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
  <script>

    //apply和call方法中如果没有传入参数,或者是传入的是null,那么调用该方法的函数对象中的this就是默认的window
    function lt3(x,y) {
        console.log("DAY3:"+(x+','+y)+this);
        return "1122";
    }
    lt3.apply(null,[11,22]);
    lt3.call(null,11,22);

    //apply和call都可以让函数或者方法来调用,传入参数和函数自己调用的写法不一样,但是效果是一样的
    var lzp1=lt3.apply(null,[04,09]);
    var lzp2=lt3.call(null,07,27);
    console.log(lzp1);
    console.log(lzp2);
   
  </script>
</head>
<body>
</body>
</html>

4、传入参数改变指向

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
  <script>

    function lt4(x,y) {
      console.log("这个函数是window对象的方法:"+(x+','+y)+this.date);
    }
    //lzpObj是一个对象
    var lzpObj={
      addr:'xianCityWall',
      date:"2016/11/22"
    };

    // 在这里通过window调用,因为当前的对象没有date这个属性,输出undefined
    window.lt4(11,22);

    // window调用,正常情况this指的是window,
    // 通过以下的方法传入了lzpObj这个对象,则this的指向改变成了object,即指向该对象
    // 该对象存在date这个属性,因此输出的this.date 的值为 "2016/11/22"
    window.lt4.apply(lzpObj,[11,22]);
    window.lt4.call(lzpObj,11,22);

  </script>
</head>
<body>
</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
  <script>

    //另外一个例子解释 apply和call可以改变this的指向
    function Person(name,hobby) {
      this.name=name;
      this.hobby=hobby;
    }
    //通过原型添加方法
    Person.prototype.play=function (x,y) {
      console.log("走啊,一起玩:"+this.hobby);
      return 20100901633;
    };
    // 定义一个实例对象
    var leiSen=new Person('雷胖子',"打篮球");
    // 实例对象调用构造函数原型的方法
    leiSen.play();

    console.log("定义另外一个构造函数,改变this指向这个对象");
    // 定义另外一个构造函数
    function Student(name,hobby) {
      this.name=name;
      this.hobby=hobby;
    }
    // 实例化对象niuniu
    var niuniu=new Student("刘老大","勇气");
    // 加入niuniu这个对象作为参数,this的指向改变了,调用的该对象的值,hobby值变为‘勇气’
    var makang=leiSen.play.apply(niuniu,[10,20]);
    var jinlong=leiSen.play.call(niuniu,10,20);

    console.log(makang);
    console.log(jinlong);

  </script>
</head>
<body>
</body>
</html>