【Javascript 拾遗之一】apply 和 call 函数

本文详细解析了JavaScript中的apply和call函数的定义、应用,包括指定对象调用方法、继承、多继承、方法参数转数组等场景。通过实例代码帮助读者深入理解并灵活运用这些函数特性。
  说到Web前端开发,很多工程师都觉得没什么可以深究,无非Html/Css/Javascript,然而在Javascript语言里,我们还有很多不了解和不熟悉的问题,三年前端开发的我在最近的面试中就遇到了很多薄弱点。因此,下定决心要深究前端核心知识,达到神一般的境界。我们先从Javascript说起,HTML和Css算是标记语言,但也不乏很多特色,以后会慢慢讨论。

apply 和 call 函数

1、定义

我们先看一下这两个函数在Javascript中的API,

void apply([thisObj[,argArray]])

调用一个对象的方法,把当前对象的所有方法属性赋予参数1所指向的对象(如有重名属性或方法直接覆盖。),并且以参数2作为多个参数输入。

thisObj的缺省值是全局对象window

void call([thisObj[,arg1[, arg2[,[,argN]]]]])

call与apply区别在于apply的参数2的数组分为多个输入参数了。

 

试着理解以下代码的执行结果,深入理解定义。

var person_no1 = {
        name : 'Jiminy',
        age : 30,
        phone : 123,
        fun : function(){
            alert(this.name);
        }
}

var person_no2 = {
        name : 'John',
        age : 25,
        phone : 123
}
person_no1.fun.call(this);//undefined
person_no1.fun.call(person_no1);//Jiminy
person_no1.fun.call(person_no2);//John

 

2、应用

-指定对象调用方法

我们在封装一些控件的时候,通常需要一些方法在某些操作之后执行,可以用call或者apply来回调另一个方法。

 1 function A(name){      
 2     this.name = name;      
 3     this.showName = function(a){      
 4         alert(this.name);
 5         alert(a);
 6     }      
 7 }      
 8     
 9 function B(name){
10     console.warn(this);
11     this.name = 'CCCCC';
12     this.alertName = function(){
13         alert(this.name);
14     }
15     this.showName = function(){
16         alert('TTTTT');
17     }
18     var a = new A('QQQ');
19     //call back
20     a.showName.call(this, 'x');
21     // equal => a.showName.apply(this, ['x']);
22 }      
23 B("I'm B");
24 //CCCCC
25 //x

代码示例中:

把a.showName这个对象替换给当前对象window,并直接调用匿名函数,alert(window.name) //CCCCC

function A, B 都是 window 对象的函数。

-继承
 1 function A(name){      
 2     this.name = name;  3 this.showName = function(){  4 alert(this.name);  5  }  6 }  7  8 function B(name){  9 this.name = 'CCCCC'; 10 this.alertName = function(){ 11 alert(this.name); 12  } 13 this.showName = function(){ 14 alert('TTTTT'); 15  } 16 //执行这条语句之后 17 //函数B就变成了function B(){ 18 // this.name = name; 19 // this.showName = function(){ 20 // alert(this.name); 21 // } 22 // this.alertName = function(){ 23 // alert(this.name); 24 // } 25 //} 26 A.call(this, name); 27 // equal => A.apply(this, [name]); 28 } 29 30 var a = new A("I'm A"); 31 a.showName(); //I'm A 32 var b = new B("I'm B"); 33 b.showName(); //I'm B 34 b.alertName(); //I'm B

代码示例中:

B通过A.call(this, name)继承了A的所有属性和方法,并且覆盖了相同的属性和方法!

 

-多继承

和单继承类似,大家可以尝试着写一下。

 

-方法参数转数组

我们经常在一些开源的框架里看到Array.prototype.slice.call(arguments)这样的代码,arguments就是方法内部的一个默认属性,是对象类型,包含参数列表

如{

  0 : param1,

  1 : param2,

  ....

  length : N

}

这样通过调用Array.prototype.slice.call()方法可以把这个对象赋予array.slice方法,由于js调用数组和对象时候array[index]和object[index]结果是一样的,所以输入包含length属性的对象也可以使用这个方法。

 

function test(a, b, c){
    alert(Array.prototype.slice.call(arguments));
}
Array.prototype.slice = function(start,end){
    var result = new Array();
    start = start || 0;
    end = end || this.length;
    for(var i = start; i < end; i++){
         result.push(this[i]);
    }
    return result;
}
test('x', 'y', 'z');//对象数组 arguments 用法
alert(Array.prototype.slice.call(['x', 'y', 'z']));//源生数组
alert(Array.prototype.slice.call('xyz'));//字符串数组
alert(Array.prototype.slice.call({0:'x',1:'y',2:'z',length:3}));//对象数组
//x,y,z
//x,y,z
//x,y,z
//x,y,z

 

 

 

 3、总结

本文简单介绍了几种apply和call的应用,是本人的经验和参考其他资料所得,在实际开发中,还有很多技巧,需要灵活应用,希望大家能通过本文彻底理解函数的定义,融汇贯通,在结构化代码的同时巧妙地使用这些方法使得代码优美简洁。

 

4、参考资料

http://uule.iteye.com/blog/1158829

 

转载于:https://www.cnblogs.com/keaixiaoye/p/4171157.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值