玩转方法: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 相关文章推荐
关于Blog顶部的滚动导航条代码
Sep 25 Javascript
js实现广告漂浮效果的小例子
Jul 02 Javascript
jquery中交替点击事件toggle方法的使用示例
Dec 08 Javascript
js实现仿百度汽车频道选择汽车图片展示实例
May 06 Javascript
javascript点击按钮实现隐藏显示切换效果
Feb 03 Javascript
简单实现js页面切换功能
Jan 10 Javascript
浅谈js函数中的实例对象、类对象、局部变量(局部函数)
Nov 20 Javascript
js 判断登录界面的账号密码是否为空
Feb 08 Javascript
ES6中箭头函数的定义与调用方式详解
Jun 02 Javascript
JS判断一个数是否是水仙花数
Jun 11 Javascript
IE11下CKEditor在Bootstrap Modal中下拉问题的解决
Sep 25 Javascript
浅谈React中组件逻辑复用的那些事儿
May 21 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
PHP5在Apache下的两种模式的安装
2006/09/05 PHP
php Memcache 中实现消息队列
2009/11/24 PHP
PHP 时间转换Unix时间戳代码
2010/01/22 PHP
PHP引用(&)各种使用方法实例详解
2014/03/20 PHP
微信公众号开发之微信公共平台消息回复类实例
2014/11/14 PHP
通过修改配置真正解决php文件上传大小限制问题(nginx+php)
2015/09/23 PHP
PHP引用的调用方法分析
2016/04/25 PHP
PHP parse_ini_file函数的应用与扩展操作示例
2019/01/07 PHP
获取Javscript执行函数名称的方法
2006/12/22 Javascript
javascript的onchange事件与jQuery的change()方法比较
2009/09/28 Javascript
jquery trim() 功能源代码
2011/02/14 Javascript
js表头排序实现方法
2015/01/16 Javascript
使用JavaScript脚本无法直接改变Asp.net中Checkbox控件的Enable属性的解决方法
2015/09/16 Javascript
表单验证正则表达式实例代码详解
2015/11/09 Javascript
jQuery判断checkbox选中状态
2016/05/12 Javascript
jquery组件WebUploader文件上传用法详解
2020/10/23 Javascript
基于JavaScript实现全选、不选和反选效果
2017/02/15 Javascript
AngularJS使用ng-repeat遍历二维数组元素的方法详解
2017/11/11 Javascript
javascript实现文件拖拽事件
2018/03/29 Javascript
浅谈vue方法内的方法使用this的问题
2018/09/15 Javascript
Vue.js 中的 v-model 指令及绑定表单元素的方法
2018/12/03 Javascript
JavaScript类型相关的常用操作总结
2019/02/14 Javascript
vue-cli3+ts+webpack实现多入口多出口功能
2019/05/30 Javascript
jQuery实现点击滚动到指定元素上的方法分析
2020/03/19 jQuery
下载安装setuptool和pip linux安装pip    
2014/01/24 Python
详解python里使用正则表达式的全匹配功能
2017/10/19 Python
基于windows下pip安装python模块时报错总结
2018/06/12 Python
python3.6.3安装图文教程 TensorFlow安装配置方法
2020/06/24 Python
提升Python程序性能的7个习惯
2019/04/14 Python
Python3.5以上版本lxml导入etree报错的解决方案
2019/06/26 Python
PyCharm-错误-找不到指定文件python.exe的解决方法
2019/07/01 Python
春节到了 教你使用python来抢票回家
2020/01/06 Python
在Python中使用K-Means聚类和PCA主成分分析进行图像压缩
2020/04/10 Python
电子商务专业在校生实习自我鉴定
2013/09/29 职场文书
机械制造专业大学生自我鉴定
2014/09/19 职场文书
三十年同学聚会感言
2015/07/30 职场文书