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 相关文章推荐
UserData用法总结 lanyu出品
Jul 01 Javascript
js时间比较示例分享(日期比较)
Mar 05 Javascript
Javascript闭包(Closure)详解
May 05 Javascript
jQuery实现简易的天天爱消除小游戏
Oct 16 Javascript
jQuery实现瀑布流布局详解(PC和移动端)
Sep 01 Javascript
jquery判断当前浏览器的实现代码
Nov 07 Javascript
JavaScript中的Array 对象(数组对象)
Jun 02 Javascript
BootStrap导航栏问题记录
Jul 31 Javascript
Vue ElementUI之Form表单验证遇到的问题
Aug 21 Javascript
jquery 实现拖动文件上传加载进度条功能
Mar 18 jQuery
node.js中express模块创建服务器和http模块客户端发请求
Mar 06 Javascript
jquery实现图片放大镜效果
Dec 23 jQuery
原生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
PHP4之COOKIE支持详解
2006/10/09 PHP
全新的PDO数据库操作类php版(仅适用Mysql)
2012/07/22 PHP
PHP基于单例模式实现的数据库操作基类
2016/01/15 PHP
php ajax confirm 删除实例详解
2019/03/06 PHP
用于判断用户注册时,密码强度的JS代码
2009/01/01 Javascript
javascript中innerText和innerHTML属性用法实例分析
2015/05/13 Javascript
javascript中一些util方法汇总
2015/06/10 Javascript
JavaScript数据类型判定的总结笔记
2015/07/31 Javascript
jQuery实现的AJAX简单弹出层效果代码
2015/11/26 Javascript
jquery中取消和绑定hover事件的实现代码
2016/06/02 Javascript
wap手机端解决返回上一页的js实例
2016/12/08 Javascript
解决AjaxFileupload 上传时会出现连接重置的问题
2017/07/07 Javascript
微信小程序数字滚动插件使用详解
2018/02/02 Javascript
基于vue-cli vue-router搭建底部导航栏移动前端项目
2018/02/28 Javascript
在vue中使用vue-echarts-v3的实例代码
2018/09/13 Javascript
vue中filters 传入两个参数 / 使用两个filters的实现方法
2019/07/15 Javascript
vuecli3.x中轻松4步带你使用tinymce的步骤
2020/06/25 Javascript
[53:18]Spirit vs Liquid Supermajor小组赛A组 BO3 第三场 6.2
2018/06/03 DOTA
python实现问号表达式(?)的方法
2013/11/27 Python
python使用any判断一个对象是否为空的方法
2014/11/19 Python
Python单元测试框架unittest使用方法讲解
2015/04/13 Python
浅谈Python实现贪心算法与活动安排问题
2017/12/19 Python
JSON文件及Python对JSON文件的读写操作
2018/10/07 Python
python多线程下信号处理程序示例
2019/05/31 Python
python numpy之np.random的随机数函数使用介绍
2019/10/06 Python
Python telnet登陆功能实现代码
2020/04/16 Python
Pandas DataFrame求差集的示例代码
2020/12/13 Python
HelloFresh奥地利:立即订购烹饪盒
2019/02/22 全球购物
北美女性服装零售连锁店:maurices
2019/06/12 全球购物
求职信的最佳写作思路
2014/02/01 职场文书
应聘医药销售自荐书范文
2014/02/08 职场文书
公司管理建议书范文
2014/03/12 职场文书
中学生期中自我鉴定
2014/04/20 职场文书
2015入党个人自传范文
2015/06/26 职场文书
SQL注入的实现以及防范示例详解
2021/06/02 MySQL
详解CSS3.0(Cascading Style Sheet) 层叠级联样式表
2021/07/16 HTML / CSS