玩转方法: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 相关文章推荐
模拟用户操作Input元素,不会触发相应事件
May 11 Javascript
js GridView 实现自动计算操作代码
Mar 25 Javascript
jMessageBox 基于jQuery的窗口插件
Dec 09 Javascript
xss文件页面内容读取(解决)
Nov 28 Javascript
JavaScript高级程序设计阅读笔记(五) ECMAScript中的运算符(一)
Feb 27 Javascript
javascript实现数字+字母验证码的简单实例
Feb 10 Javascript
JavaScript编程中容易出BUG的几点小知识
Jan 31 Javascript
js+css实现导航效果实例
Feb 10 Javascript
JS获取年月日时分秒的方法分析
Nov 28 Javascript
浅谈vuex 闲置状态重置方案
Jan 04 Javascript
使用async await 封装 axios的方法
Jul 09 Javascript
Bootstrap 实现表格样式、表单布局的实例代码
Dec 09 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+MYSQL的文章管理系统(一)
2006/10/09 PHP
PHP和Mysqlweb应用开发核心技术-第1部分 Php基础-2 php语言介绍
2011/07/03 PHP
总结一些PHP中好用但又容易忽略的小知识
2017/06/02 PHP
js玩一玩WSH吧
2007/02/23 Javascript
js 3种归并操作的实例代码
2013/10/30 Javascript
给文字加上着重号的JS代码
2013/11/12 Javascript
用js正确判断用户名cookie是否存在的方法
2014/01/28 Javascript
推荐6款基于jQuery实现图片效果插件
2014/12/07 Javascript
jQuery经过一段时间自动隐藏指定元素的方法
2015/03/17 Javascript
js操作css属性实现div层展开关闭效果的方法
2015/05/11 Javascript
js实现仿微博滚动显示信息的效果
2015/12/21 Javascript
js中利用tagname和id获取元素的方法
2016/01/03 Javascript
javascript的 {} 语句块详解
2016/02/27 Javascript
javascript 四十条常用技巧大全
2016/09/09 Javascript
老生常谈Javascript中的原型和this指针
2016/10/09 Javascript
Jquery Easyui自定义下拉框组件使用详解(21)
2020/12/31 Javascript
ajax与json 获取数据并在前台使用简单实例
2017/01/19 Javascript
vue+vux实现移动端文件上传样式
2017/07/28 Javascript
浅谈SpringMVC中post checkbox 多选框value的值(隐藏域方式)
2018/01/08 Javascript
vue .sync修饰符的使用详解
2018/06/15 Javascript
Vue form表单动态添加组件实战案例
2019/09/02 Javascript
Vue自定义组件双向绑定实现原理及方法详解
2020/09/03 Javascript
在antd中setFieldsValue和defaultVal的用法
2020/10/29 Javascript
分享6个隐藏的python功能
2017/12/07 Python
详解Python 多线程 Timer定时器/延迟执行、Event事件
2019/06/27 Python
python numpy生成等差数列、等比数列的实例
2020/02/25 Python
Windows下Anaconda和PyCharm的安装与使用详解
2020/04/23 Python
使用Django搭建网站实现商品分页功能
2020/05/22 Python
Python常用base64 md5 aes des crc32加密解密方法汇总
2020/11/06 Python
经典婚礼主持开场白
2014/03/13 职场文书
县政协领导班子群众路线教育实践活动四风问题整改方案
2014/10/26 职场文书
2015年电厂工作总结范文
2015/05/13 职场文书
烈士陵园扫墓感想
2015/08/07 职场文书
机械原理课程设计心得体会
2016/01/15 职场文书
2016年学校“6﹒26国际禁毒日”宣传活动总结
2016/04/05 职场文书
HTML5中 rem适配方案与 viewport 适配问题详解
2021/04/27 HTML / CSS