玩转方法:call和apply


Posted in Javascript onMay 08, 2014

在ECMAScript v3中,给Function原型定义了这两个方法,这两个方法的作用都是一样的:使用这两个方法可以像调用其他对象方法一样调用函数,这句话是从书上抄的,至少我是没读明白这是什么意思。
下面说简单易懂的,先看段代码:

function Introduce(name,age) 
{ 
    document.write("My name is "+name+".I am "+age); 
} 
var p=new People(); 
Introduce.call(p,"Windking",20);

就说上面的这段代码,用了call之后,Introduce就成了p的方法,不知道这样说你明白了么?使用了call方法,上述的代码就等同于了这个代码:

function People(name,age) 
{ 
    this.name=name; 
    this.age=age; 
    this.Introduce=function(){ 
document.write("My name is "+name+".I am "+age); 
}; 
}

明白意思了么?apply也是一样的作用。
好,我们不管这个方法到底能在实际中用到什么,先讲语法。
call接受至少一个参数,call的第一个参数是指你所需要的对象,比如说上面的那个例子,Introduce方法希望他能够被对象p所调用,那么就把p作为call的第一个参数。剩余的参数个数是任意的,作用是作为Introduce方法的参数。顺序按照Introduce参数声明的顺序。比如Introduce.call(p,"Windking",20),假如Introduce是p的一个实例方法,那么也就是这样的:p.Introduce("Windking",20)。明白了么?记住,传入参数的顺序要与函数声明参数的顺序保持一致。
了解了call,apply方法就容易理解了,apply和call唯一的区别是call接受至少一个参数,而apply只接受两个参数,第一个参数与call一样,第二个参数是一个带下标的集合,比如说Introduce.call(p,"Windking",20)就可以改写成Introduce.apply(p,["Windking",20])了。这次明白了么?
那究竟这两个方法有什么用呢?如果我们只是为了实现上面的那个功能,把Introduce实现为People的方法不是更好么?

我把应用总结为两条:

1.共享方法。先看代码:

function Introduce(name,age) 
{ 
        document.write("My name is "+name+".I am "+age); 
}

这是一个自我介绍的方法,现在假设我们有一个男孩的类,和一个女孩的类(在这里我只是为了演示,在实际中,会用一个People的父类),因为他们的Introduce都是一样的,于是我们就可以共享这个方法。

function Boy() 
{ 
        this.BoyIntroduce=function(){ 
Introduce.call(this,name,age); 
}; 
}

同理,Girl中也是一样,这样的话,我们就可以避免写代码了。其实这个有些牵强,因为我们完全也可以写成:

function Boy() 
{ 
        this.BoyIntroduce=function(){ 
            Introduce(name,age); 
} 
}

但是这个时候,我们如果用Apply的话,就看上去简单多了:

function Boy() 
{ 
        this.BoyIntroduce=function(){ 
Introduce.apply(this,arguments); 
}; 
}

是不是简单了很多呢?如果参数很多的话,那么是不是不用再写那么一场串密密麻麻的参数了呢!

2.跨域调用

看一个简单的例子(仅为演示,无任何价值):

function Boy(name,age) 
{ 
        this.BoyIntroduce=function(){ 
            document.write("My name is "+name+".I am "+age); 
} 
} 
function Girl(name,age) 
{ }

这是一个Boy和一个Girl类,然后我们写如下的代码:

var b=new Boy("Windking",20);
b.BoyIntroduce();

这没有任何异议。假设有一天有一个女孩也希望做一下自我介绍,只是偶然用一下,那么我就没有必要修改Girl类,因为其他的女孩比较害羞,不喜欢自我介绍。那么这个时候我就可以这样。

var g=new Girl("Xuan",22);
Introduce.call(g,"Xuan",22);

3.真正用处——继承

好了,上面都是雕虫小技,不登大雅之堂,下面才是call和apply最广泛的应用,就是用于构造继承。

Javascript 相关文章推荐
Javascript下的keyCode键码值表
Apr 10 Javascript
CSS+Jquery实现页面圆角框方法大全
Dec 24 Javascript
js 全兼容可高亮二级缓冲折叠菜单
Jun 04 Javascript
JavaScript实现页面实时显示当前时间的简单实例
Jul 20 Javascript
js获取多个tagname的节点数组
Sep 22 Javascript
juery框架写的弹窗效果适合新手
Nov 27 Javascript
javascript实现简单的贪吃蛇游戏
Mar 31 Javascript
jquery遍历json对象集合详解
May 18 Javascript
微信小程序 数据绑定详解及实例
Oct 25 Javascript
详解nuxt sass全局变量(公共scss解决方案)
Jun 27 Javascript
Windows下安装 node 的版本控制工具 nvm
Feb 06 Javascript
Vue看了就会的8个小技巧
Jan 21 Vue.js
jQuery产品间断向下滚动效果核心代码
May 08 #Javascript
jQuery.extend()、jQuery.fn.extend()扩展方法示例详解
May 08 #Javascript
jquery通过visible来判断标签是否显示或隐藏
May 08 #Javascript
setInterval计时器不准的问题解决方法
May 08 #Javascript
Js Jquery创建一个弹出层可加载一个页面
May 08 #Javascript
一个html5播放视频的video控件只支持android的默认格式mp4和3gp
May 08 #Javascript
js 设置缓存及获取设置的缓存
May 08 #Javascript
You might like
一首老MP3,致敬WAR3经典
2021/03/08 魔兽争霸
php dirname(__FILE__) 获取当前文件的绝对路径
2011/06/28 PHP
PHP下载远程图片并保存到本地方法总结
2016/01/22 PHP
PHP数学运算与数据处理实例分析
2016/04/01 PHP
PHP基于自定义函数生成笛卡尔积的方法示例
2017/09/30 PHP
PHP中PCRE正则解析代码详解
2019/04/26 PHP
用javascript实现兼容IE7的类库 IE7_0_9.zip提供下载
2007/08/08 Javascript
js正文内容高亮效果的实现方法
2013/06/30 Javascript
简单的ajax连接库分享(不用jquery的ajax)
2014/01/19 Javascript
JQuery获取表格数据示例代码
2014/05/26 Javascript
可编辑下拉框的2种实现方式
2014/06/13 Javascript
JQuery显示隐藏页面元素的方法总结
2015/04/16 Javascript
js获取鼠标位置实例详解
2015/12/09 Javascript
Bootstrap每天必学之附加导航(Affix)插件
2016/04/25 Javascript
原生js实现addClass,removeClass,hasClass方法
2016/04/27 Javascript
node.js文件上传处理示例
2016/10/27 Javascript
微信小程序 实现tabs选项卡效果实例代码
2016/10/31 Javascript
利用Node.js批量抓取高清妹子图片实例教程
2018/08/02 Javascript
react native 原生模块桥接的简单说明小结
2019/02/26 Javascript
JavaScript计算正方形面积
2019/11/26 Javascript
Element Cascader 级联选择器的使用示例
2020/07/27 Javascript
javascript canvas封装动态时钟
2020/09/30 Javascript
python发送邮件示例(支持中文邮件标题)
2014/02/16 Python
利用pyinstaller或virtualenv将python程序打包详解
2017/03/22 Python
Python列表删除的三种方法代码分享
2017/10/31 Python
Python遍历pandas数据方法总结
2018/02/09 Python
Python3实现爬虫爬取赶集网列表功能【基于request和BeautifulSoup模块】
2018/12/05 Python
详解Python打包分发工具setuptools
2019/08/05 Python
Python爬虫HTPP请求方法有哪些
2020/06/03 Python
requests在python中发送请求的实例讲解
2021/02/17 Python
2015年大学生社会实践评语
2015/03/26 职场文书
师德师风培训感言
2015/08/03 职场文书
浅谈JS的原型和原型链
2021/06/04 Javascript
Java 深入探究讲解简单工厂模式
2022/04/07 Java/Android
Golang MatrixOne使用介绍和汇编语法
2022/04/19 Golang
苹果的回收机器人可以通过拆解iPhone获取大量的金和铜并外公布了环境保护最新进展
2022/04/21 数码科技