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调试工具(下载)
Jan 09 Javascript
js实现图片放大和拖拽特效代码分享
Sep 05 Javascript
JS实现超简单的鼠标拖动效果
Nov 02 Javascript
jQuery中inArray方法注意事项分析
Jan 25 Javascript
浅析函数声明和函数表达式——函数声明的声明提前
May 03 Javascript
基于BootStrap的文本编辑器组件Summernote
Oct 27 Javascript
layui表格分页 记录勾选的实例
Sep 02 Javascript
在Vue中使用this.$store或者是$route一直报错的解决
Nov 08 Javascript
VUE Elemen-ui之穿梭框使用方法详解
Jan 19 Javascript
three.js中多线程的使用及性能测试详解
Jan 07 Javascript
如何用JS实现简单的数据监听
May 06 Javascript
angular异步验证器防抖实例详解
Mar 31 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中的cookie
2006/11/26 PHP
eAccelerator的安装与使用详解
2013/06/13 PHP
php天翼开放平台短信发送接口实现方法
2014/12/22 PHP
PHP利用APC模块实现文件上传进度条的方法
2015/01/26 PHP
详解如何实现Laravel的服务容器的方法示例
2019/04/15 PHP
jQuery 表格工具集
2010/04/25 Javascript
将查询条件的input、select清空
2014/01/14 Javascript
javascript学习笔记(四)function函数部分
2014/09/30 Javascript
设置点击文本框或图片弹出日历控件的实现代码
2016/05/12 Javascript
懒加载实现的分页&&网站footer自适应
2016/12/21 Javascript
AngularJS实现的base64编码与解码功能示例
2018/05/17 Javascript
Vue 组件参数校验与非props特性的方法
2019/02/12 Javascript
在VUE中实现文件下载并判断状态的方法
2019/11/08 Javascript
Vue监听滚动实现锚点定位(双向)示例
2019/11/13 Javascript
vue-cli3访问public文件夹静态资源报错的解决方式
2020/09/02 Javascript
Openlayers+EasyUI Tree动态实现图层控制
2020/09/28 Javascript
python base64 decode incorrect padding错误解决方法
2015/01/08 Python
Python WSGI的深入理解
2018/08/01 Python
详解python3安装pillow后报错没有pillow模块以及没有PIL模块问题解决
2019/04/17 Python
解决python xx.py文件点击完之后一闪而过的问题
2019/06/24 Python
python爬取盘搜的有效链接实现代码
2019/07/20 Python
解决python3 requests headers参数不能有中文的问题
2019/08/21 Python
如何利用pygame实现简单的五子棋游戏
2019/12/29 Python
用sleep间隔进行python反爬虫的实例讲解
2020/11/30 Python
python多线程爬取西刺代理的示例代码
2021/01/30 Python
matplotlib 范围选区(SpanSelector)的使用
2021/02/24 Python
HTML5实现WebSocket协议原理浅析
2014/07/07 HTML / CSS
好莱坞百老汇御用王牌美妆:Koh Gen Do 江原道
2018/04/03 全球购物
设计部经理的岗位职责
2013/11/16 职场文书
金融管理专业毕业生求职信
2014/03/12 职场文书
工会优秀工作者事迹
2014/08/17 职场文书
金融专业银行实习证明模板
2014/11/28 职场文书
酒店收银员岗位职责
2015/04/07 职场文书
积极心理学课程心得体会
2016/01/22 职场文书
2016基督教会圣诞节开幕词
2016/03/04 职场文书
Python常遇到的错误和异常
2021/11/02 Python