玩转方法: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打开word文档的方法
Apr 16 Javascript
Bootstrap Fileinput文件上传组件用法详解
May 10 Javascript
详解vue-cli中配置sass
Jun 21 Javascript
jQuery实现可编辑表格并生成json结果(实例代码)
Jul 19 jQuery
vue 下列表侧滑操作实例代码详解
Jul 24 Javascript
在vue项目中集成graphql(vue-ApolloClient)
Sep 08 Javascript
Vue一次性简洁明了引入所有公共组件的方法
Nov 28 Javascript
jQuery实现侧边栏隐藏与显示的方法详解
Dec 22 jQuery
layui使用数据表格实现购物车功能
Jul 26 Javascript
小程序实现锚点滑动效果
Sep 23 Javascript
webpack3升级到webpack4遇到问题总结
Sep 30 Javascript
如何通过JS实现日历简单算法
Oct 14 Javascript
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定时计划任务与fsockopen持续进程实例
2014/05/23 PHP
php中函数前加&符号的作用分解
2014/07/08 PHP
PHP的switch判断语句的“高级”用法详解
2014/10/01 PHP
PHP实现股票趋势图和柱形图
2015/02/07 PHP
详解WordPress中用于合成数组的wp_parse_args()函数
2015/12/18 PHP
php实现URL加密解密的方法
2016/11/17 PHP
PHP静态成员变量和非静态成员变量详解
2017/02/14 PHP
js加解密 脚本解密
2008/02/22 Javascript
javascript 关于# 和 void的区别分析
2009/10/26 Javascript
JS 树形递归实例代码
2010/05/18 Javascript
$.get获取一个文件的内容示例代码
2013/09/11 Javascript
JS delegate与live浅析
2013/12/21 Javascript
jQuery中:has选择器用法实例
2014/12/30 Javascript
js实现简洁大方的二级下拉菜单效果代码
2015/09/01 Javascript
使用bootstrap实现多窗口和拖动效果
2016/09/22 Javascript
Vue项目使用localStorage+Vuex保存用户登录信息
2019/05/27 Javascript
Vue 数据响应式相关总结
2021/01/28 Vue.js
python获得图片base64编码示例
2014/01/16 Python
Windows下安装python2和python3多版本教程
2017/03/30 Python
Python实现PS滤镜碎片特效功能示例
2018/01/24 Python
python学习笔记--将python源文件打包成exe文件(pyinstaller)
2018/05/26 Python
django 信号调度机制详解
2019/07/19 Python
win10子系统python开发环境准备及kenlm和nltk的使用教程
2019/10/14 Python
使用Python测试Ping主机IP和某端口是否开放的实例
2019/12/17 Python
pyinstaller打包单文件时--uac-admin选项不起作用怎么办
2020/04/15 Python
Python求解排列中的逆序数个数实例
2020/05/03 Python
python使用隐式循环快速求和的实现示例
2020/09/11 Python
Staples加拿大官方网站:办公用品一站式采购
2016/09/25 全球购物
KARATOV珠宝在线商店:俄罗斯珠宝品牌
2019/03/13 全球购物
中国跨镜手机配件批发在线商店:TVC-Mall
2019/08/20 全球购物
求职信范文怎么写
2015/03/19 职场文书
《岳阳楼记》原文、译文赏析
2019/09/10 职场文书
厉害!这是Redis可视化工具最全的横向评测
2021/07/15 Redis
Python学习之时间包使用教程详解
2022/03/21 Python
总结三种用 Python 作为小程序后端的方式
2022/05/02 Python
Go Grpc Gateway兼容HTTP协议文档自动生成网关
2022/06/16 Golang