博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript实现继承机制(1)—— 构造函数方法对象冒充
阅读量:5332 次
发布时间:2019-06-14

本文共 1896 字,大约阅读时间需要 6 分钟。

我们知道JavaScript是面向对象的脚本语言,那么既然是面向对象,继承一定是必不可少的了。JavaScript的核心是ECMAScript,JavaScript继承机制的实现其实就是ECMAScript继承机制的实现。

继承的方式

ECMAScript 实现继承的方式不止一种。这是因为 JavaScript 中的继承机制并不是明确规定的,而是通过模仿实现的。这意味着所有的继承细节并非完全由解释程序处理。作为开发者,你有权决定最适用的继承方式。最原始的继承实现方式就是对象冒充,下面着重介绍该方法。

对象冒充

对象冒充实现继承的核心其实依赖于在函数环境中使用 this 关键字。其原理如下:构造函数使用 this 关键字给所有属性和方法赋值(即采用类声明的构造函数方式)。因为构造函数只是一个函数,所以可使 ClassA 构造函数成为 ClassB 的方法,然后调用它。ClassB 就会收到 ClassA 的构造函数中定义的属性和方法。例如,用下面的方式定义 ClassA 和 ClassB:

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

关键字 this 引用的是构造函数当前创建的对象。不过在这个方法中,this 指向的所属的对象。这个原理是把 ClassA 作为常规函数来建立继承机制,而不是作为构造函数。如下使用构造函数 ClassB 可以实现继承机制:

function ClassB(sColor) {    this.newMethod = ClassA;    this.newMethod(sColor);    delete this.newMethod;}

在这段代码中,为 ClassA 赋予了方法 newMethod(请记住,函数名只是指向它的指针)。然后调用该方法,传递给它的是 ClassB 构造函数的参数 sColor。最后一行代码删除了对 ClassA 的引用,这样以后就不能再调用它。

所有新属性和新方法都必须在删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法:

 

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

为证明前面的代码有效,可以运行下面的例子:

var objA = new ClassA("blue");var objB = new ClassB("red", "John");objA.sayColor();    //输出 "blue"objB.sayColor();    //输出 "red"objB.sayName();        //输出 "John"

对象冒充可以实现多重继承

有趣的是,对象冒充可以支持多重继承。例如,如果存在两个类 ClassX 和 ClassY,ClassZ 想继承这两个类,可以使用下面的代码:

function ClassZ() {    this.newMethod = ClassX;    this.newMethod();    delete this.newMethod;    this.newMethod = ClassY;    this.newMethod();    delete this.newMethod;}

这里存在一个弊端,如果存在两个类 ClassX 和 ClassY 具有同名的属性或方法,ClassY 具有高优先级。因为它从后面的类继承。除这点小问题之外,用对象冒充实现多重继承机制轻而易举。

由于这种继承方法的流行,ECMAScript 的第三版为 Function 对象加入了两个方法,即 call() 和 apply()。后来很多衍生出来的实现继承的方法其实也是基于call() 和 apply()来实现的。

转载于:https://www.cnblogs.com/CodeGuy/archive/2013/05/03/3056718.html

你可能感兴趣的文章
洛谷 3870 [TJOI2009]开关
查看>>
【牛客-16643】统计数字(简单排序)
查看>>
linux awk命令详解
查看>>
www.aaa.com/index.html跳转www.aaa.com设置
查看>>
mysql 分页offset过大性能问题解决思路
查看>>
MVC配置global无效
查看>>
H5之postMessage 。实现跨域
查看>>
Python档案袋( Json、pickle、加密与解密)
查看>>
正则表达式30分钟入门教程
查看>>
java集合知识点
查看>>
On-board diagnostics -- Standards documents
查看>>
Latest SQLite binary for January 2015
查看>>
《剑指offer》面试题1:为类CMyString添加赋值运算符函数——C++拷贝构造函数与赋值函数...
查看>>
[BZOJ3262]陌上花开
查看>>
[BZOJ2004][Hnoi2010]Bus 公交线路
查看>>
MongoDB与CouchDB全方位对比(转)
查看>>
md5加密解析
查看>>
第一个C#程序
查看>>
Windows(Win7)搭建RabbitMQ服务器
查看>>
arcgis server javascript api 唯一值渲染
查看>>