基于JavaScript实现继承机制之调用call()与apply()的方法详解


Posted in Javascript onMay 07, 2013

call() 方法

call() 方法是与经典的对象冒充方法最相似的方法。它的第一个参数用作 this 的对象。其他参数都直接传递给函数自身。例如:

function sayHello(sPrefix,sSuffix) {
    alert(this.name + ”says“ + sPrefix + sSuffix);
};
var obj = new Object();
obj.name = "Tom";
sayHello.call(obj, "Hello ", "World.");

在这个例子中,函数 sayHello() 在对象外定义,即使它不属于任何对象,也可以引用关键字 this。对象 obj 的 name属性等于 blue。调用 call() 方法时,第一个参数是 obj,说明应该赋予 sayHello() 函数中的 this 关键字值是 obj。第二个和第三个参数是字符串。它们与 sayHello() 函数中的参数 sPrefix 和 sSuffix 匹配,最后生成的消息 "Tom says Hello World." 将被显示出来。

要与继承机制的对象冒充方法一起使用该方法,只需将前三行的赋值、调用和删除代码替换即可:

function ClassA(sColor) {
    this.color = sColor;
    this.sayColor = function () {
        alert(this.color);
    };
}

function ClassB(sColor, sName) {
    //this.newMethod = ClassA;
    //this.newMethod(color);
    //delete this.newMethod;
    ClassA.call(this, sColor);
    this.name = sName;
    this.sayName = function () {
        alert(this.name);
    };
}

这里,我们需要让 ClassA 中的关键字 this 等于新创建的 ClassB 对象,因此 this 是第一个参数。第二个参数 sColor 对两个类来说都是唯一的参数。

apply() 方法

apply() 方法有两个参数,用作 this 的对象和要传递给函数的参数的数组。例如:

function sayColor(sPrefix,sSuffix) {
    alert(sPrefix + this.color + sSuffix);
};
var obj = new Object();
obj.color = "blue";
sayColor.apply(obj, new Array("The color is ", "a very nice color indeed."));

这个例子与前面的例子相同,只是现在调用的是 apply() 方法。调用 apply() 方法时,第一个参数仍是 obj,说明应该赋予 sayColor() 函数中的 this 关键字值是 obj。第二个参数是由两个字符串构成的数组,与 sayColor() 函数中的参数 sPrefix 和 sSuffix 匹配,最后生成的消息仍是 "The color is blue, a very nice color indeed.",将被显示出来。

该方法也用于替换前三行的赋值、调用和删除新方法的代码:

function ClassB(sColor, sName) {
    //this.newMethod = ClassA;
    //this.newMethod(color);
    //delete this.newMethod;
    ClassA.apply(this, new Array(sColor));
    this.name = sName;
    this.sayName = function () {
        alert(this.name);
    };
}

同样的,第一个参数仍是 this,第二个参数是只有一个值 color 的数组。可以把 ClassB 的整个 arguments 对象作为第二个参数传递给 apply() 方法:
function ClassB(sColor, sName) {
    //this.newMethod = ClassA;
    //this.newMethod(color);
    //delete this.newMethod;
    ClassA.apply(this, arguments);
    this.name = sName;
    this.sayName = function () {
        alert(this.name);
    };
}

当然,只有超类中的参数顺序与子类中的参数顺序完全一致时才可以传递参数对象。如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。此外,还可使用 call() 方法。

我们可以看到这两个方法能够很好的代替原始的对象冒充,使写法上变得稍微简单。但是这些方法的弊端是子类不能继承父类在原型链上声明的方法或属性,针对这个问题下一篇文章将会介绍JavaScript中另一种实现继承的方式—原型链继承。

Javascript 相关文章推荐
jquery 表单取值常用代码
Dec 22 Javascript
关于JS控制代码暂停的实现方法分享
Oct 11 Javascript
javascript 树形导航菜单实例代码
Aug 13 Javascript
Android中的jQuery:AQuery简介
May 06 Javascript
JavaScript获取URL汇总
Jun 08 Javascript
js实现的后台左侧管理菜单代码
Sep 11 Javascript
基于javascript实现窗口抖动效果
Jan 03 Javascript
Jquery EasyUI Datagrid右键菜单实现方法
Dec 30 Javascript
Angular中封装fancyBox(图片预览)遇到问题小结
Sep 01 Javascript
vue2.0+vuex+localStorage代办事项应用实现详解
May 31 Javascript
如何手动实现es5中的bind方法详解
Dec 07 Javascript
微信小程序在线客服自动回复功能(基于node)
Jul 03 Javascript
JS中的substring和substr函数的区别说明
May 07 #Javascript
js图片自动切换效果处理代码
May 07 #Javascript
JavaScript通过RegExp实现客户端验证处理程序
May 07 #Javascript
JS注册/移除事件处理程序(ExtJS应用程序设计实战)
May 07 #Javascript
使用Math.floor与Math.random取随机整数的方法详解
May 07 #Javascript
基于JavaScript 类的使用详解
May 07 #Javascript
解读JavaScript中 For, While与递归的用法
May 07 #Javascript
You might like
PHP基础之运算符的使用方法
2013/04/28 PHP
php递归json类实例
2014/12/02 PHP
Zend Studio使用技巧两则
2016/04/01 PHP
PHP内部实现打乱字符串顺序函数str_shuffle的方法
2019/02/14 PHP
JavaScript Event学习补遗 addEventSimple
2010/02/11 Javascript
JavaScript中__proto__与prototype的关系深入理解
2012/12/04 Javascript
Javascript脚本实现静态网页加密实例代码
2013/11/05 Javascript
js 调用百度地图api并在地图上进行打点添加标注
2014/05/13 Javascript
滚动条响应鼠标滑轮事件实现上下滚动的js代码
2014/06/30 Javascript
JavaScript中的类与实例实现方法
2015/01/23 Javascript
JavaScript实现点击按钮直接打印
2016/01/06 Javascript
JavaScript学习笔记之取数组中最大值和最小值
2016/03/23 Javascript
深入理解jQuery3.0的domManip函数
2016/09/01 Javascript
D3.js实现文本的换行详解
2016/10/14 Javascript
d3.js中冷门却实用的内置函数总结
2017/02/04 Javascript
Nodejs中获取当前函数被调用的行数及文件名详解
2018/12/12 NodeJs
mpvue全局引入sass文件的方法步骤
2019/03/06 Javascript
解决Vue动态加载本地图片问题
2019/10/09 Javascript
JavaScript forEach中return失效问题解决方案
2020/06/01 Javascript
[39:02]DOTA2亚洲邀请赛 3.31 小组赛 B组 Mineski vs VGJ.T
2018/04/01 DOTA
[02:42]岂曰无衣,与子同袍!DOTA2致敬每一位守护人
2020/02/17 DOTA
python常用知识梳理(必看篇)
2017/03/23 Python
itchat和matplotlib的结合使用爬取微信信息的实例
2017/08/25 Python
Python随机生成身份证号码及校验功能
2018/12/04 Python
python2.7使用plotly绘制本地散点图和折线图
2019/04/02 Python
PyTorch的torch.cat用法
2020/06/28 Python
Baracuta官方网站:Harrington夹克,G9,G4,G10等
2018/03/06 全球购物
一站式跨境收款解决方案:Payoneer(派安盈)
2018/09/06 全球购物
PHP中如何创建和修改数组
2012/05/02 面试题
纬创Java面试题笔试题
2014/10/02 面试题
会计职业生涯规划范文
2014/01/04 职场文书
导游个人求职信范文
2014/03/23 职场文书
党的群众路线教育实践活动查摆问题及整改措施
2014/10/10 职场文书
在 HTML 页面中使用 React的场景分析
2022/01/18 Javascript
Win11怎么把合并的任务栏分开 Win11任务栏合并分开教程
2022/04/06 数码科技
vue代码分块和懒加载非必要资源文件
2022/04/11 Vue.js