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 相关文章推荐
javascript 一个自定义长度的文本自动换行的函数
Aug 19 Javascript
JavaScript数组函数unshift、shift、pop、push使用实例
Aug 27 Javascript
jQuery实现鼠标滑向当前图片高亮显示并且其它图片变灰的方法
Jul 27 Javascript
javascript基于prototype实现类似OOP继承的方法
Dec 16 Javascript
详解jQuery中ajax.load()方法
Jan 25 Javascript
Vue.js实战之组件之间的数据传递
Apr 01 Javascript
jquery.masonry瀑布流效果
May 25 jQuery
JavaScript EventEmitter 背后的秘密 完整版
Mar 29 Javascript
解决layui前端框架 form表单,table表等内置控件不显示的问题
Aug 19 Javascript
vue动态删除从数据库倒入列表的某一条方法
Sep 29 Javascript
微信小程序中遇到的iOS兼容性问题小结
Nov 14 Javascript
node.js如何根据URL返回指定的图片详解
Oct 21 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
PHP5.3新特性小结
2016/02/14 PHP
PHP+JS三级菜单联动菜单实现方法
2016/02/24 PHP
thinkphp5 + ajax 使用formdata提交数据(包括文件上传) 后台返回json完整实例
2020/03/02 PHP
JavaScript中访问节点对象的方法有哪些如何使用
2013/09/24 Javascript
jQuery实现鼠标滑过Div层背景变颜色的方法
2015/02/17 Javascript
jQuery事件绑定用法详解(附bind和live的区别)
2016/01/19 Javascript
关于获取DIV内部内容报错的原因分析及解决办法
2016/01/29 Javascript
基于js里调用函数时,函数名带括号和不带括号的区别
2016/07/28 Javascript
JavaScript简单下拉菜单特效
2016/09/13 Javascript
js运动事件函数详解
2016/10/21 Javascript
js获取时间函数及扩展函数的方法
2016/10/30 Javascript
jQuery EasyUI Panel面板组件使用详解
2017/02/28 Javascript
JavaScript验证知识整理
2017/03/24 Javascript
js中字符型和数值型数字的互相转化方法(必看)
2017/04/25 Javascript
js求数组中全部数字可拼接出的最大整数示例代码
2017/08/25 Javascript
jsTree事件和交互以及插件plugins详解
2017/08/29 Javascript
JS代码实现电脑配置检测功能
2018/03/21 Javascript
mpvue 如何使用腾讯视频插件的方法
2018/07/16 Javascript
微信小程序实现的一键连接wifi功能示例
2019/04/24 Javascript
javascript设计模式 ? 解释器模式原理与用法实例分析
2020/04/17 Javascript
javascript 使用sleep函数的常见方法详解
2020/04/26 Javascript
Python变量和字符串详解
2017/04/29 Python
python实现求解列表中元素的排列和组合问题
2018/03/15 Python
Python3实现的字典、列表和json对象互转功能示例
2018/05/22 Python
解决Pycharm出现的部分快捷键无效问题
2018/10/22 Python
python实现图片九宫格分割
2021/03/07 Python
Django3.0 异步通信初体验(小结)
2019/12/04 Python
pycharm通过ssh连接远程服务器教程
2020/02/12 Python
python数据预处理 :数据抽样解析
2020/02/24 Python
Python中os模块功能与用法详解
2020/02/26 Python
CSS3效果:自定义“W”形运行轨迹实例
2017/03/29 HTML / CSS
牵手50新加坡:专为黄金岁月的单身人士而设的交友网站
2020/08/16 全球购物
超市开学活动方案
2014/03/01 职场文书
2015年转正工作总结范文
2015/04/02 职场文书
2015年新农村建设指导员工作总结
2015/07/24 职场文书
公司财务管理制度
2015/08/04 职场文书