js call 和apply

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js call 和apply相关的知识,希望对你有一定的参考价值。

   ECMAScript3  给Function原型上定义了两个方法,他们是Function.prototype.call和Function.prototype.apply。

 

  • call和apply的区别
 1 var func =function(a,b,c){
 2     alert([a,b,c]);
 3 };
 4 func.apply(null,[1,2,3]);//apply
 5 
 6 
 7 var func =function(a,b,c){
 8     alert([a,b,c]);
 9 };
10 func.call(null,1,2,3);//call

  apply::两个参数,第一个参数:指定了函数体内this对象的指向;

          第二个参数:一个带下标的集合,可以为数组,也可以为伪数组

  call:多个参数:第一个参数:指定了函数体内this对象的指向;

          第二个参数开始往后,每一个参数被依次传入函数;

 

  call和apply传入的第一个参数为null,函数体内this会指向默认的宿主对象,在浏览器中则是window

  如果在严格模式下,函数体内的this还是为null 1 var func = function(a,b,c){

 2     alert(this === window);//true  
 3 };
 4 
 5 func.apply(null,[1,2,3])
 6 
 7 var func = function(a,b,c){
 8     "use stract";//如果在严格模式下,函数体内的this还是为null
 9     alert(this === null);//true  
10 };
11 func.apply(null,[1,2,3]);

  • call和apply的用途

    1.改变this的指向 

技术分享
 1 var obj1 = {
 2     name:"seven"
 3 };
 4 
 5 var oj2 = {
 6     name:"anne"
 7 };
 8 
 9 window.name = "window";
10 
11 var getName = function(){
12     alert(this.name)
13 };
14 
15 getName();//window
16 getName.call(obj1);//seven
17 getName.apply(obj2);//anne
View Code

在实际开发中,经常会遇到this指向被不经意改变的场景,比如,有一个div节点,div节点的onclick事件中的this本来指向这个div的:

 1 dcument.getElementById("div1").onclick=function(){
 2     alert(this.id);//div1
 3 }
 4 //加入改时间函数中有一个内部函数func,在实践内部调用func函数时,func函数体内的this就指向了window,而不是我们预期的div
 5 
 6 document.getElementById("div1").oonclick = function(){
 7     alert(this.id);//div1
 8     var func = function(){
 9         alert(this.id)  //undefined
10     };
11     func();
12 };
13 //这时候我们用call来修正func函数内的this,使其指向div
14 document.getElementById("div1").onclick=function(){
15     var func = function(){
16         alert(this.id);//div1
17     };
18     func.call(this);
19 }   

使用call来修正this的场景,我们并不是第一次遇到,

1 document.getElementById = (function(){
2     return function(){
3         return func.apply(document,arguments);
4     }
5 })(document.getElementById);
6 
7 var getId =document.getElementById;
8 var div = getId("div1");
9 alert(div.id);  //div1

    2.Function.prototype.bind

大部分浏览器都实现了内置的Function.prototype.bind,用来指定函数内部的this指向,即使没有原生的Function.prototype.bind实现。

 1 Function.prototype.bind= function(context){
 2     var self = this;//保存原函数
 3     return function(){//返回一个新函数
 4         return self.apply(context,arguments);//执行新的函数的时候,会把之前的context当做新函数体内的this
 5     };
 6 }
 7 
 8 var obj = {
 9     name:"seve"
10 };
11 
12 var a = function(){
13     alert(this.name);//seve
14 }.bind(obj);
15 
16 a();

我们通过Function.prototype.bind来“包装”func函数,并且传入一个对象context当作参数,这个context对象就是我们想修正的this对象。

在Function.prototype.bind的内部实现中,我们先把func函数的引用保存起来,然后返回一个新函数。当我们在将来执行a函数时,实际上先执行的是这个刚刚返回的新函数。在新函数内部,self.apply(context,arguments)这句话代码是执行原来的a函数,并且指定context对象为a函数体内的this.

下面是复杂一点的实现:

 

 

 

 

  



以上是关于js call 和apply的主要内容,如果未能解决你的问题,请参考以下文章

关于JS中apply和call详细解答

js中call和apply的区别

JS中 call和apply的区别和作用

js学习总结----call和apply和bind的区别

js中的call和apply简单演示

在JS中,call()方法和apply()方法到底该怎么应用?