javaScript中的call,apply函数

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

这两个方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数。

function.call(thisobj, args...)

示例如下:

   /*function add(a){
       alert(a+b);
   }

   function sub(){
       alert(a-b);
   }
   add.call(sub,3,1); 

解释:这里add执行的上下文由window切换为sub,即this指向是从window变为sub,仅此而已,并非add替换sub。还是调用的add(3, 1); 但是,在add这个函数执行的时候,当前的上下文this已经不是add对象的了,而是sub对象的。

示例二:

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,",");     //执行的结果为 Cat
//animal.showName.apply(cat,[]);     

解释:“call 的意思是把 animal 的方法放到cat上执行”这个应该是animal.showName调用时候,
将animal中的this对象转变为cat,alert(this.name);这时候的this是cat,因此this.name==cat.name,所以输出是Cat

function
Animal(){ this.name = "Animal"; this.showName = function(){ alert(this.name); } } function Cat(name){ Animal.call(this,name); } var cat = new Cat("Black Cat"); cat.showName(); //结果为Animal

解释:首先执行var cat = new Cat("Black Cat");进入function Cat(name){  
     Animal.call(this, name);  
}
这时候的this为Cat{}对象,并非Animal再接执行function Animal(name){    
     this.name = name;    
     this.showName = function(){    
         alert(this.name);    
     }    
}
此时的this对象绑定为Cat{},因此是Cat对象获得了两个属性为:Cat{name:"Black Cat",showName:function(){    
         alert(this.name);    
     }},回到var cat=Cat{name:"Black Cat",showName:function(){    
         alert(this.name);    
     }}最后才是cat.showName();

 

function Animal(name){      
    this.name = name;      
    this.showName = function(){      
        alert(this.name);      
    }      
}      
    
function Cat(name){    
    Animal.call(this, name);    
}      
    
var cat = new Cat("Black Cat");     
cat.showName();   //得出的结果是Black Cat

JS apply的应用

 var data = [1,2,3,4,5,6,7,8];

  alert(Math.max.apply(null, data));

 

 call和apply存在的原因:

 function cat(){}
   cat.prototype={
       food:"fish",
       say: function(){
           alert("I love "+this.food);
       }
   };
   var blackCat =new cat();
   blackCat.say();    // I love fish
   
   var whiteDog ={food:"bone"};
   blackCat.say.call(whiteDog);   //I love bone

如果我们有一个对象,whiteDog = {food:"bone"},我们不想对它重新定义say方法,那么我们可以通过call或apply用blackCat的say方法:blackCat.say.call(whiteDog);

所以,当一个object没有某个方法,但是其他的有,我们可以借助call或apply用其它对象的方法来操作

 

用的比较多的,通过document.getElementsByTagName选择的dom 节点是一种类似array的array。
它不能应用Array下的push,pop等方法。
我们可以通过:var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));这样domNodes就可以应用Array下的所有方法了。 链接:https://www.zhihu.com/question/20289071/answer/14644278 来源:知乎

 

例子二:

function changeStyle(attr, value){
    this.style[attr] = value;
}
var box = document.getElementById('box');
window.changeStyle.call(box, "height", "200px");

changeStyle函数将被box对象调用,this指向了box对象,如果不用call的话,程序报错,因为window对象中没有style属性。
apply的用法:

window.changeStyle.apply(box, ['height', '200px']);

如果call或apply的第一个参数是null的话,this指向window

 

 

 

 

posted @ 2017-07-03 15:34  千寻的天空之城  阅读(175)  评论(0编辑  收藏  举报