js的call和apply拾遗

一.产生背景

  1. JavaScript 的函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念

  2.正因为上下文的不同所以call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向。

二.定义

每个函数都包含两个非继承而来的方法:apply()和call().这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内的this对象的值.

首先apply

apply([thisObj[,argArray]])    应用某一对象的一个方法,用另一个对象替换当前对象。

方法接收两个参数:一个是其中运行的函数的作用域,拎一个是参数数组,其中第二个参数可以是Array的实例也可以是arguments对象,callee,caller;

 如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError

   可以用来代替另一个对象调用一个方法。apply方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

其次,call 

call([thisObj[,arg1[, arg2[, [,.argN]]]]])调用一个对象的一个方法,以另一个对象替换当前对象。

这两个方法,如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj

三.常用实例

<script>
    //1执行代码块
                   function add(a,b){
                       alert(a+b)
                   }
                   function sub(a,b){
                       alert(a-b)
                   }
                   sub.apply(add,[2,2])  //0  js 中的函数其实是对象,函数名是对 Function 对象的引用,add继承了sub的方法并执行
                   add.call(sub,2,2)//4  sub继承了add的方法并执行

             //2执行代码
             function Animal(){
                 this.name="Animal";
                 this.showName=function(){
                     alert(this.name)
                 }
             }
             function Cat(){
                 this.name="Cat"
             }
             var animal = new Animal();
             var cat = new Cat();
             animal.showName.call(Cat)//通过call或apply将animal的showName方法放到Cat上来执行,this指向Cat所以  this.name="Cat"
             //3实现继承js代码块
             function Animal(name){
                 this.name = name;
                 this.showName = function(){
                     alert(this.name);
                 }
             }

             function Cat(name){
                 Animal.call(this,name)
             }
             var cat = new Cat("Blace Cat")
             cat.showName();
             // Animal.call(this,name) 将Animal对象的方法放到this对象环境下执行 ;那么this就有了Animal的方法和属性
             //4多重继承
             function Class10()  {  
            this.showSub = function(a,b) {  
                    alert(a-b);  
            }  
    }  
    function Class11() {  
            this.showAdd = function(a,b) {  
                    alert(a+b);  
            }  
    }  
     function Class2(){  
            Class10.call(this);  
            Class11.call(this);  
    } 

    var classTest=new Class2();
    classTest.showAdd(10,10);
         //Class2中使用了两个call实现了将Class10和Class11对象上的方法放到this即Class2环境下执行
    </script>
原文地址:https://www.cnblogs.com/lizhiwei8/p/7700227.html