JS继承--原型链继承和类式继承


Posted in Javascript onApril 08, 2013

什么是继承啊?答:别人白给你的过程就叫继承。

为什么要用继承呢?答:捡现成的呗。

好吧,既然大家都想捡现成的,那就要学会怎么继承!

在了解之前,你需要先了解构造函数对象原型链等概念......

JS里常用的两种继承方式

    原型链继承(对象间的继承)类式继承(构造函数间的继承)

原型链继承

//要继承的对象
var parent={
name : "baba"
  say : function(){ 
alert("I am baba");
}
}

//新对象
var child = proInherit(parent);
//测试
alert(child.name); //"baba"
child.say(); //"I am baba"

利用proInherit(obj)方法,传入对象,就能实现对象的属性及方法的继承,这个方法不是内置方法,所以要自己定义,非常简单:

function proInherit(obj){
function F () {}
F.prototype = obj;
return new F();
}

其中F()为一个临时的空的构造函数,然后将F()的原型设置为父对象,但是同时它又通过受益于_proto_链接而具有其父亲对象的全部功能。

链式图解:

         JS继承--原型链继承和类式继承

 

类式继承

//父类构造函数
function Parent() {
this.name = "baba";
}
//父类原型方法
Parent.prototype.getName = function () {
return this.name;
}
//子类构造函数
function Child() {
this.name = "cc";
}
//类式继承
classInherit(Parent, Child);
//实例
var child = new Child();
alert(child.getName()) //“baba”

下面我们来看看这个继承的关键方法:classInherit(Parent,Child)

var classInherit = (function () {
var F = function () { }
return function (P, C) {
F.prototype = P.prototype;
C.prototype = new F();
C.prototype.constructor = C;
}
}());

 分析一下这个方法:

    首先创建一个空的构造函数F(),用其实例的_proto_属性来构建父类与子类的原型链。起到一个代理的作用,目的是为了防止C.prototype = P.prototype,这样会在子类实例化后修改属性或方法时候,连同父类一起修改。整体采用即时函数并且在闭包中存储F(),防止多次继承时候创建大量的空的构造函数,从而减少消耗内存。最后一行的意思是,由于原型链的关系,C的实例对象的constructor会指向P,所以重新设置。

链式图解:

            JS继承--原型链继承和类式继承

这种方式虽然在实例的时候继承了原型方法,但是父类的属性无法继承,下面介绍一种复制继承,算是对类式继承的补充。

复制继承:

//复制继承
function copyInherit(p, c) {
var i,
toStr = Object.prototype.toString,
astr = "[object Array]";
c = c || {}; 
for (i in p) {
if (p.hasOwnProperty(i)) {
if (typeof p[i] === "object") {
c[i] = toStr.call(p[i]) == astr ? [] : {};
c[i] = copy(p[i], c[i]);
}
else {
c[i] = p[i];
}
}
}
return c;
}
//重写Parent
function Parent() {
this.name = "pp";
this.obj= {a:1,b:2};
this.arr= [1, 2]
}
//实例
var child = new Child();
var parent = new Parent();
copyInherit(parent, child);
alert(child.name) //"baba"
alert(child.arr) //1,2
alert(child.obj.a) //1

 分析下copyInherit(p,c)

当一个值赋予一个变量时候,分为传值和传引用两种方式,当你父对象内属性包含数组类型或是对象类型时候,  c[i] = toStr.call(p[i]) == astr ? [] : {};这一句会避免修改子对象属性而引起的父对象属性被篡改。

总结:

类式继承比较普遍,因为大家都比较熟悉这种构造函数方式,但是内存占用比较大。而原型式继承,占用内存比较小,但是包含数组,或者对象类型的克隆比较麻烦。复制继承简单,而且应用广泛。

 

Javascript 相关文章推荐
javascript window对象属性整理
Oct 24 Javascript
c#和Javascript操作同一json对象的实现代码
Jan 17 Javascript
解决jQuery动态获取手机屏幕高和宽的问题
May 07 Javascript
JavaScript保留关键字汇总
Dec 01 Javascript
正则表达式优化JSON字符串的技巧
Dec 24 Javascript
原生js配合cookie制作保存路径的拖拽
Dec 29 Javascript
基于jQuery Tipso插件实现消息提示框特效
Mar 16 Javascript
微信公众号 摇一摇周边功能开发
Dec 08 Javascript
jQuery实现搜索页面关键字的功能
Feb 16 Javascript
JavaScript数组迭代方法
Mar 03 Javascript
利用vue组件自定义v-model实现一个Tab组件方法示例
Dec 06 Javascript
详解swipe使用及竖屏页面滚动方法
Jun 28 Javascript
原生js实现shift/ctrl/alt按键的获取
Apr 08 #Javascript
原生js实现跨浏览器获取鼠标按键的值
Apr 08 #Javascript
纯js实现瀑布流展现照片(自动适应窗口大小)
Apr 08 #Javascript
javascript中常用编程知识
Apr 08 #Javascript
利用webqq协议使用python登录qq发消息源码参考
Apr 08 #Javascript
setInterval,setTimeout与jquery混用的问题
Apr 08 #Javascript
JQueryEasyUI Layout布局框架的使用
Apr 08 #Javascript
You might like
站长助手-网站web在线管理程序 v1.0 下载
2007/05/12 PHP
php 连接mssql数据库 初学php笔记
2010/03/01 PHP
php封装的数据库函数与用法示例【参考thinkPHP】
2016/11/08 PHP
php事务回滚简单实现方法示例
2017/03/28 PHP
php数组实现根据某个键值将相同键值合并生成新二维数组的方法
2017/04/26 PHP
Zend Framework框架中实现Ajax的方法示例
2017/06/27 PHP
Laravel学习教程之从入口到输出过程详解
2017/08/27 PHP
Laravel 5.5基于内置的Auth模块实现前后台登陆详解
2017/12/21 PHP
PHP实现的mysql读写分离操作示例
2018/05/22 PHP
用javascript获得地址栏参数的两种方法
2006/11/08 Javascript
javascript+iframe 实现无刷新载入整页的代码
2010/03/17 Javascript
jquery延迟对象解析
2016/10/26 Javascript
jQuery的Read()方法代替原生JS详解
2016/11/08 Javascript
五步轻松实现JavaScript HTML时钟效果
2020/03/25 Javascript
vue+swiper实现侧滑菜单效果
2017/12/28 Javascript
Vue-cli3项目配置Vue.config.js实战记录
2018/07/29 Javascript
微信小程序实现两个页面传值的方法分析
2018/12/11 Javascript
bootstrap-paginator服务器端分页使用方法详解
2020/02/13 Javascript
python Django连接MySQL数据库做增删改查
2013/11/07 Python
python实现稀疏矩阵示例代码
2017/06/09 Python
老生常谈python之鸭子类和多态
2017/06/13 Python
Python使用装饰器进行django开发实例代码
2018/02/06 Python
opencv python 基于KNN的手写体识别的实例
2018/08/03 Python
uwsgi+nginx部署Django项目操作示例
2018/12/04 Python
Pythony运维入门之Socket网络编程详解
2019/04/15 Python
Python实战之制作天气查询软件
2019/05/14 Python
python-tkinter之按钮的使用,开关方法
2019/06/11 Python
Python如何调用JS文件中的函数
2019/08/16 Python
python中sys模块是做什么用的
2020/08/16 Python
H5离线存储Manifest原理及使用
2020/04/28 HTML / CSS
毕业设计计划书
2014/01/09 职场文书
学校节能减排倡议书
2014/05/16 职场文书
端午节演讲稿
2014/05/23 职场文书
烈士陵园观后感
2015/06/08 职场文书
Java由浅入深通关抽象类与接口(上篇)
2022/04/26 Java/Android
MYSQL事务的隔离级别与MVCC
2022/05/25 MySQL