javascript继承机制实例详解


Posted in Javascript onNovember 20, 2014

本文实例讲述了javascript继承机制。分享给大家供大家参考。具体分析如下:

初学javascript一般很难理解Javascript语言的继承机制它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(prototype chain)模式,来实现继承。

我花了很多时间,学习这个部分,还做了很多笔记。但是都属于强行记忆,无法从根本上理解。

一、如何创建一个类

假设有给叫Person的类如下:

var Person = function(name, age) {

    this.name = name;

    this.age = age;

}

Person.prototype.getName = function() {

    return this.name;

}

如上:Person代表地球上所有的人,每个人都有这两个基本属性:name和age;现在我们要实现一个学生类,然后我们知道了; 学生也是一个人,及学生也有name和age等属性;现在的问题是怎么能把这个关系给搭起来?
先来看看纯面向对象的语言是如何做到的(如:Actionscrpt3)
class Students extend Person {}; //很简单,一行代码;更确切的说是一个单词--extend

二、换成js如何能做到

在讲解js的继承机制实现之前,先了解一下js的原型链:

var person = new Person('Poised-flw', 21);

person.getName(); // "Poised-flw"

就上面的getName()方法来说,是如何执行的?首先会在Person这个函数里面找是否有getName()这个方法,发现没有;然后就转到 Person.prototype中寻找,发现有!然后就调用,若没有呢?继续按照相同的方法一直沿着prototype寻找下去,直到找到方法或者 达到原型链的顶端为止!

举例来说,现在有一个叫做DOG的构造函数,表示狗对象的原型。

function DOG(name){


this.name = name;

}

对这个构造函数使用new,就会生成一个狗对象的实例。
var dogA = new DOG('大毛');

alert(dogA.name); // 大毛

注意构造函数中的this关键字,它就代表了新创建的实例对象。

三、new运算符的缺点

用构造函数生成实例对象,有一个缺点,那就是无法共享属性和方法。
比如,在DOG对象的构造函数中,设置一个实例对象的共有属性species。

function DOG(name){


this.name = name;


this.species = '犬科';

}

然后,生成两个实例对象:
var dogA = new DOG('大毛');

var dogB = new DOG('二毛');

这两个对象的species属性是独立的,修改其中一个,不会影响到另一个。
dogA.species = '猫科';

alert(dogB.species); // 显示"犬科",不受dogA的影响

每一个实例对象,都有自己的属性和方法的副本。这不仅无法做到数据共享,也是极大的资源浪费。

所以:继承的思想: 通过js特有的原型链来实现继承机制!

四、基于原型链的继承

1.直接继承实现

var Students = function(name, age, sid) {

    Person.call(this, name, age);

    this.sid = sid;

}

Students.prototype = new Person(); //把Person放到Students的原型链上实现继承机制

Students.prototype.constructor = Students;

Students.prototype.getResults = function() {

    // 得到学生的成绩

}

一定不要少了Students.prototype.constructor = Students这一行!,定义一个构造函数的时候,它默认的prototype是一个Object实例,然后prototype的constructor属性自动被设置成该函数本身 !!!若手工将prototype设置为另一个对象的时候,则新对象自然不会具有原对象的contructor值,故需要重新设置其constructor属性。如:
var Test = function() {

    this.time = "now";

}

console.log(Test.prototype); // Object {} 一个空对象

console.log(Test.prototype.constructor); // function() {this.time = "now";},及函数本身

// 若手工改变Test的prototype属性

Test.prototype = {

    someFunc: function() {

        console.log('hello world!');

    }

};

console.log(Test.prototype.constructor); // function Object() { [native code] }

// 然后你会发现完全指错了,故手动更改prototype属性的时候需要更改它的constructor指向;

经过上面的测试就知道为什么要修改constructor值了。

2.封装继承的函数extend

function extend(subClass, superClass) {

    var F = function() {};

    F.prototype = superClass.prototype;

    subClass.prototype = new F();

    subClass.prototype.constructor = subClass;

}

其实这个函数的功能只是对上面继承过程的一个封装,不同的有:
只继承了superClass的prototype属性,并没有继承superClass构造函数中的属性;
这样做的优点在于:减少去new一个构造函数的开销!
当然随之的问题是不能单一的通过这个函数就能让subClass继承superClass的所有属性
改进:
// 在Students构造函数中继续添加一行代码:

Person.call(this, name, age);

五、小结

利用js的原型链原理,我们可以很容易的实现js的继承机制,尽管不是非常的严格,但是我的目的达到了: 重复的代码尽量出现一次!

希望本文所述对大家的javascript程序设计有所帮助。

Javascript 相关文章推荐
Prototype1.6 JS 官方下载地址
Nov 30 Javascript
使用Jquery打造最佳用户体验的登录页面的实现代码
Jul 08 Javascript
Js制作简单弹出层DIV在页面居中 中间显示遮罩的具体方法
Aug 08 Javascript
jquery 3D 标签云示例代码
Jun 12 Javascript
jQuery团购倒计时特效实现方法
May 07 Javascript
JS实现常见的TAB、弹出层效果(TAB标签,斑马线,遮罩层等)
Oct 08 Javascript
JavaScript测试工具之Karma-Jasmine的安装和使用详解
Dec 03 Javascript
JavaScript类型系统之基本数据类型与包装类型
Jan 06 Javascript
基于jQuery实现瀑布流页面
Apr 11 jQuery
Electron 如何调用本地模块的方法
Feb 01 Javascript
js取0-9随机取4个数不重复的数字代码实例
Mar 27 Javascript
TypeScript 内置高级类型编程示例
Sep 23 Javascript
jQuery验证插件 Validate详解
Nov 20 #Javascript
PHP中使用微秒计算脚本执行时间例子
Nov 19 #Javascript
jQuery中$.get、$.post、$.getJSON和$.ajax的用法详解
Nov 19 #Javascript
实现图片预加载的三大方法及优缺点分析
Nov 19 #Javascript
jQuery Ajax()方法使用指南
Nov 19 #Javascript
javascript匿名函数实例分析
Nov 18 #Javascript
Linux下使用jq友好的打印JSON技巧分享
Nov 18 #Javascript
You might like
人大复印资料处理程序_查询篇
2006/10/09 PHP
php自定义apk安装包实例
2014/10/20 PHP
Yii开启片段缓存的方法
2016/03/28 PHP
PHP+JQUERY操作JSON实例
2017/03/23 PHP
Yii框架组件的事件机制原理与用法分析
2020/04/07 PHP
判断对象是否Window的实现代码
2012/01/10 Javascript
javascript+xml实现简单图片轮换(只支持IE)
2012/12/23 Javascript
jquery自动填充勾选框即把勾选框打上true
2014/03/24 Javascript
jQuery实现返回顶部效果的方法
2015/05/29 Javascript
jquery获得当前html页面源码的方法
2015/07/14 Javascript
4种JavaScript实现简单tab选项卡切换的方法
2016/01/06 Javascript
BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟)
2016/08/17 Javascript
js替换字符串中所有指定的字符(实现代码)
2016/08/17 Javascript
对vue事件的延迟执行实例讲解
2018/08/28 Javascript
从零开始实现Vue简单的Toast插件
2018/12/03 Javascript
基于webpack4.X从零搭建React脚手架的方法步骤
2018/12/23 Javascript
JS重学系列之聊聊new操作符
2019/03/04 Javascript
[36:52]DOTA2真视界:基辅特锦赛总决赛
2017/05/21 DOTA
python修改字典内key对应值的方法
2015/07/11 Python
numpy的文件存储.npy .npz 文件详解
2018/07/09 Python
Django中的用户身份验证示例详解
2019/08/07 Python
利用Vscode进行Python开发环境配置的步骤
2020/06/22 Python
如何在scrapy中捕获并处理各种异常
2020/09/28 Python
python 实现批量图片识别并翻译
2020/11/02 Python
用 python 进行微信好友信息分析
2020/11/28 Python
python中PyQuery库用法分享
2021/01/15 Python
html5音频_动力节点Java学院整理
2018/08/22 HTML / CSS
英国最大的宠物食品和宠物用品网上零售商: Zooplus
2016/08/01 全球购物
终端业务员岗位职责
2013/11/27 职场文书
乡镇信息公开实施方案
2014/03/23 职场文书
2014年小学教研工作总结
2014/12/06 职场文书
法定代表人身份证明书
2015/06/18 职场文书
廉洁自律证明
2015/06/24 职场文书
小学数学教师研修感悟
2015/11/18 职场文书
Python中快速掌握Data Frame的常用操作
2021/03/31 Python
win10搭建配置ftp服务器的方法
2022/08/05 Servers