玩转方法: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 相关文章推荐
Jquery写一个鼠标拖动效果实现原理与代码
Dec 24 Javascript
JavaScript使用setTimeout实现延迟弹出警告框的方法
Apr 07 Javascript
jQuery实现右侧显示可向左滑动展示的深色QQ客服效果代码
Oct 23 Javascript
jQuery EasyUi实战教程之布局篇
Jan 26 Javascript
jQuery时间日期三级联动(推荐)
Nov 27 Javascript
JS实现复制功能
Mar 01 Javascript
JS设计模式之数据访问对象模式的实例讲解
Sep 30 Javascript
jQuery动态添加li标签并添加属性和绑定事件方法
Feb 24 jQuery
浅谈Javascript常用正则表达式应用
Mar 08 Javascript
详解vue 2.6 中 slot 的新用法
Jul 09 Javascript
JavaScript eval()函数定义及使用方法详解
Jul 07 Javascript
js+canvas实现刮刮奖功能
Sep 13 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
oracle资料库函式库
2006/10/09 PHP
php结合md5实现的加密解密方法
2016/01/25 PHP
php通过curl添加cookie伪造登陆抓取数据的方法
2016/04/02 PHP
Centos PHP 扩展Xchche的安装教程
2016/07/09 PHP
百度 popup.js 完美修正版非常的不错 脚本之家推荐
2009/04/17 Javascript
js用正则表达式来验证表单(比较齐全的资源)
2013/11/17 Javascript
Javascript基础教程之switch语句
2015/01/18 Javascript
JQuery遍历DOM节点的方法
2015/06/11 Javascript
如何使用jQuery技术开发ios风格的页面导航菜单
2015/07/29 Javascript
javascript伸缩菜单栏实现代码分享
2015/11/12 Javascript
利用JQuery写一个简单的异步分页插件
2016/03/07 Javascript
浅析JavaScript的几种Math函数,random(),ceil(),round(),floor()
2016/12/22 Javascript
详解vue.js全局组件和局部组件
2017/04/10 Javascript
vuejs2.0子组件改变父组件的数据实例
2017/05/10 Javascript
基于vue实现swipe轮播组件实例代码
2017/05/24 Javascript
微信小程序Getuserinfo解决方案图解
2018/08/24 Javascript
JavaScript常用数组操作方法,包含ES6方法
2020/05/10 Javascript
微信小程序实现星级评价
2019/11/20 Javascript
[01:02:45]完美世界DOTA2联赛 LBZS vs Forest 第三场 11.07
2020/11/09 DOTA
Python深入学习之闭包
2014/08/31 Python
python中 logging的使用详解
2017/10/25 Python
python学生管理系统代码实现
2020/04/05 Python
Python如何爬取实时变化的WebSocket数据的方法
2019/03/09 Python
Django app配置多个数据库代码实例
2019/12/17 Python
python离线安装外部依赖包的实现
2020/02/13 Python
pycharm如何实现跨目录调用文件
2020/02/28 Python
实列教程 一款基于jquery和css3的响应式二级导航菜单
2014/11/13 HTML / CSS
美国指甲油品牌:Deco Miami
2017/01/30 全球购物
澳大利亚拥有最好的家具和家居用品在线目的地:Nestz
2019/02/23 全球购物
Lookfantastic阿联酋官网:英国知名美妆护肤购物网站
2020/05/26 全球购物
材料会计岗位职责
2014/03/06 职场文书
2015年安全保卫工作总结
2015/05/14 职场文书
2015年客房服务员工作总结
2015/05/15 职场文书
2016年百日安全生产活动总结
2016/04/06 职场文书
SQL基础查询和LINQ集成化查询
2022/01/18 MySQL
Docker与K8s关系介绍不会Docker也可以使用K8s
2022/06/25 Servers