玩转方法: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 Zifa FormValid 0.1表单验证 代码打包下载
Jun 08 Javascript
用JQuery模仿淘宝的图片放大镜显示效果
Sep 15 Javascript
js 火狐下取本地路径实现思路
Apr 02 Javascript
IE浏览器中图片onload事件无效的解决方法
Apr 29 Javascript
js实现遮罩层弹出框的方法
Jan 15 Javascript
表单验证正则表达式实例代码详解
Nov 09 Javascript
JS如何设置cookie有效期为当天24点并弹出欢迎登陆界面
Aug 04 Javascript
JavaScript通过改变文字透明度实现的文字闪烁效果实例
Apr 27 Javascript
vue router嵌套路由在history模式下刷新无法渲染页面问题的解决方法
Jan 25 Javascript
优雅的处理vue项目异常实战记录
Jun 05 Javascript
Vue状态模式实现窗口停靠功能(灵动、自由, 管理后台Admin界面)
Mar 06 Javascript
Postman无法正常返回结果问题解决
Aug 28 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中将数组转成字符串并保存到数据库中的函数代码
2013/09/29 PHP
php实现获取近几日、月时间示例
2019/07/06 PHP
动态控制Table的js代码
2007/03/07 Javascript
Javascript valueOf 使用方法
2008/12/28 Javascript
滚动条变色 隐藏滚动条与双击网页自动滚屏显示代码
2009/12/28 Javascript
js 禁用只读文本框获得焦点时的退格键
2010/04/25 Javascript
javascript cookie操作类的实现代码小结附使用方法
2010/06/02 Javascript
jQuery知识点整理
2015/01/30 Javascript
浅谈javascript中的DOM方法
2015/07/16 Javascript
JS实现IE状态栏文字缩放效果代码
2015/10/24 Javascript
JQuery 的跨域方法推荐_可跨任何网站
2016/05/18 Javascript
基于jQuery实现弹出可关闭遮罩提示框实例代码
2016/07/18 Javascript
JavaScript如何实现跨域请求
2016/08/05 Javascript
微信小程序 HTTPS报错整理常见问题及解决方案
2016/12/14 Javascript
Vue实现底部侧边工具栏的实例代码
2018/09/03 Javascript
JQuery中的常用事件、对象属性与使用方法分析
2019/12/23 jQuery
在antd中setFieldsValue和defaultVal的用法
2020/10/29 Javascript
[01:16]2014DOTA2 TI专访C9战队EE:中国五强中会占三席
2014/07/10 DOTA
[47:12]TFT vs Secret Supermajor小组赛C组 BO3 第三场 6.3
2018/06/04 DOTA
Python实现的批量下载RFC文档
2015/03/10 Python
在Python下尝试多线程编程
2015/04/28 Python
Python数据类型详解(三)元祖:tuple
2016/05/08 Python
Python函数参数操作详解
2018/08/03 Python
使用Python 正则匹配两个特定字符之间的字符方法
2018/12/24 Python
python实现维吉尼亚加密法
2019/03/20 Python
Python logging模块写入中文出现乱码
2020/05/21 Python
Python使用pyenv实现多环境管理
2021/02/05 Python
Can a struct inherit from another struct? (结构体能继承结构体吗)
2016/09/25 面试题
2014年毕业演讲稿范文
2014/05/13 职场文书
师范生见习报告
2014/10/31 职场文书
2014年度个人工作总结
2014/11/07 职场文书
2014年帮扶工作总结
2014/11/26 职场文书
医药公司开票员岗位职责
2015/04/15 职场文书
python爬虫--selenium模块
2021/03/31 Python
Go 语言中 20 个占位符的整理
2021/10/16 Golang
python机器学习创建基于规则聊天机器人过程示例详解
2021/11/02 Python