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应该怎样学
Apr 16 Javascript
javascript奇异的arguments分析
Oct 20 Javascript
jQuery在vs2008及js文件中的无智能提示的解决方法
Dec 30 Javascript
JQuery文本框高亮显示插件代码
Apr 02 Javascript
div模拟选择框示例代码
Nov 03 Javascript
jQuery实现统计复选框选中数量
Nov 24 Javascript
javascript实现获取浏览器版本、浏览器类型
Dec 02 Javascript
jQuery通过ajax快速批量提交表单数据
Oct 25 Javascript
详解javascript获取url信息的常见方法
Dec 19 Javascript
详解vue2.0+axios+mock+axios-mock+adapter实现登陆
Jul 19 Javascript
React通过redux-persist持久化数据存储的方法示例
Feb 14 Javascript
JavaScript 函数用法详解【函数定义、参数、绑定、作用域、闭包等】
May 12 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
简单的php数据库操作类代码(增,删,改,查)
2013/04/08 PHP
PHP使用strstr()函数获取指定字符串后所有字符的方法
2016/01/07 PHP
给PHP开发者的编程指南 第一部分降低复杂程度
2016/01/18 PHP
php使用pclzip类实现文件压缩的方法(附pclzip类下载地址)
2016/04/30 PHP
深入分析PHP优化及注意事项
2016/07/04 PHP
Ajax PHP JavaScript MySQL实现简易无刷新在线聊天室
2016/08/17 PHP
用php定义一个数组最简单的方法
2019/10/04 PHP
jQuery中hover方法和toggle方法使用指南
2015/02/27 Javascript
关于function类中定义变量this的简单说明
2016/05/28 Javascript
深入理解js函数的作用域与this指向
2016/05/28 Javascript
Javascript中arguments对象的详解与使用方法
2016/10/04 Javascript
详解Weex基于Vue2.0开发模板搭建
2017/03/20 Javascript
基于es6三点运算符的使用方法(实例讲解)
2017/10/12 Javascript
react build 后打包发布总结
2018/08/24 Javascript
vue填坑之webpack run build 静态资源找不到的解决方法
2018/09/03 Javascript
微信小程序实现收货地址左滑删除
2020/11/18 Javascript
详解微信小程序之提高应用速度小技巧
2020/01/07 Javascript
使用Python程序抓取新浪在国内的所有IP的教程
2015/05/04 Python
python matplotlib 注释文本箭头简单代码示例
2018/01/08 Python
解决matplotlib.pyplot在Jupyter notebook中不显示图像问题
2020/04/22 Python
django rest framework serializers序列化实例
2020/05/13 Python
Python爬虫基于lxml解决数据编码乱码问题
2020/07/31 Python
使用bandit对目标python代码进行安全函数扫描的案例分析
2021/01/27 Python
pycharm最新激活码有效期至2100年(亲测可用)
2021/02/05 Python
浅谈Python xlwings 读取Excel文件的正确姿势
2021/02/26 Python
HTML5跳转小程序wx-open-launch-weapp的示例代码
2020/07/16 HTML / CSS
西班牙灯具网上商店:Lampara.es
2018/06/05 全球购物
Kingsoft金山公司C/C++笔试题
2016/05/10 面试题
信息管理员岗位职责
2013/12/01 职场文书
少先队入队活动方案
2014/02/08 职场文书
春风行动实施方案
2014/03/28 职场文书
护士上岗前培训自我鉴定
2014/04/20 职场文书
美术教师个人工作总结
2015/02/06 职场文书
世界地球日活动总结
2015/02/09 职场文书
英文导游词
2015/02/13 职场文书
大学生党员暑假实践(活动总结)
2019/08/21 职场文书