玩转方法: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的eval()中使用函数的进一步讨论
Jul 26 Javascript
关于JavaScript的一些看法
May 27 Javascript
JavaScript 对象链式操作测试代码
Apr 25 Javascript
JS自动缩小超出大小的图片
Oct 12 Javascript
js借助ActiveXObject实现创建文件
Sep 29 Javascript
jQuery选择器源码解读(四):tokenize方法的Expr.preFilter
Mar 31 Javascript
JavaScript实现仿网易通行证表单验证
May 25 Javascript
使用JS批量选中功能实现更改数据库中的status状态值(批量展示)
Nov 22 Javascript
微信小程序 使用canvas制作K线实例详解
Jan 12 Javascript
基于JavaScript实现图片连播和联级菜单实例代码
Jul 28 Javascript
Vue自定义指令实现checkbox全选功能的方法
Feb 28 Javascript
详解jQuery如何实现模糊搜索
May 10 jQuery
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
php基础知识:控制结构
2006/12/13 PHP
php 动态执行带有参数的类方法
2009/04/10 PHP
yii操作session实例简介
2014/07/31 PHP
php实现的替换敏感字符串类实例
2014/09/22 PHP
PHP使用strtotime获取上个月、下个月、本月的日期
2015/12/30 PHP
php简单处理XML数据的方法示例
2017/05/19 PHP
javascript 图片上传预览-兼容标准
2009/06/01 Javascript
表单切换,用回车键替换Tab健(不支持IE)
2011/07/20 Javascript
javascript框架设计读书笔记之种子模块
2014/12/02 Javascript
JavaScript中的console.dir()函数介绍
2014/12/29 Javascript
jQuery插件multiScroll实现全屏鼠标滚动切换页面特效
2015/04/12 Javascript
jquery实现图片水平滚动效果代码分享
2015/08/26 Javascript
JS实现的自定义右键菜单实例二则
2015/09/01 Javascript
Bootstrap3制作图片轮播效果
2016/05/12 Javascript
js和jq使用submit方法无法提交表单的快速解决方法
2016/05/17 Javascript
一句jQuery代码实现返回顶部效果(简单实用)
2016/12/28 Javascript
ionic2 tabs 图标自定义实例
2017/03/08 Javascript
简单谈谈关于Angular Cli打包的事
2017/09/05 Javascript
Vue-cli 使用json server在本地模拟请求数据的示例代码
2017/11/02 Javascript
使用webpack4编译并压缩ES6代码的方法示例
2019/04/24 Javascript
JS异步处理的进化史深入讲解
2019/08/25 Javascript
原生js+css实现tab切换功能
2020/09/17 Javascript
python比较2个xml内容的方法
2015/05/11 Python
对Python3 goto 语句的使用方法详解
2019/02/16 Python
在windows下使用python进行串口通讯的方法
2019/07/02 Python
用python解压分析jar包实例
2020/01/16 Python
Python代码覆盖率统计工具coverage.py用法详解
2020/11/25 Python
UGG雪地靴德国官网:UGG德国
2016/11/19 全球购物
巴西食品补充剂在线零售商:Músculos na Web
2017/08/07 全球购物
Clos19英国:高档香槟、葡萄酒和烈酒在线购物平台
2020/07/10 全球购物
《月光启蒙》教学反思
2014/03/01 职场文书
党员目标管理责任书
2014/07/25 职场文书
学生违纪检讨书200字
2014/10/21 职场文书
2016关于军训的心得体会
2016/01/11 职场文书
护理专业毕业自我鉴定
2019/08/12 职场文书
Python趣味挑战之给幼儿园弟弟生成1000道算术题
2021/05/28 Python