最近在学习《JavaScript模式》,感觉里面的5种继承模式写的很好,值得和大家分享。

类式继承模式#1——原型继承

方法

让子函数的原型来继承父函数实例出来的对象

	<script type="text/javascript">
function SuperType(name) {
this.name = name || "john";
} SuperType.prototype.sayName = function() {
console.log(this.name);
}; function SubType(name,age) {
} // 继承方法
function inherit(C,P) {
C.prototype = new P();
} inherit(SubType,SuperType); var instance1 = new SubType("mo");
console.log(instance1.sayName()); // john
</script>

以上代码中通过关键字new操作符,操作子函数SubType创建一个新实例。以这种调用构造函数会经过四个步骤:

  • 创建新对象
  • 将构造函数的作用域赋给新对象(构造函数的this指针指向了这个新对象)
  • 执行构造函数中的代码,创建的属性与方法赋值给这个新对象
  • 返回新对象

缺点

  • 继承了两个对象的属性,即添加到this的属性及原型中的属性
  • 另外一个问题是不能将子函数的参数传递给父函数

类式继承模式#2——借用构造函数

方法

在子函数中访问父函数的作用域

<script type="text/javascript">
function SuperType(name) {
this.name = name || "mo";
}
}
SuperType.prototype.getName = function () {
return this.name;
}
function SubType() {
SuperType.call(this,"mo"); // 通过使用call方法,改变子构造函数的作用域的指向,此时this指向父函数的作用域。
} var ins1 = new SubType();
console.log(ins1.getName());
</script>

此方法的问题:子类不能访问父类原型中的属性与方法

因为子函数是通过call方法访问父函数的作用域,而不是访问父函数原型中的作用域。父函数与父函数原型是通过_proto_对象链接的。

类式继承模式#3——借用和设置原型

方法

先借用构造函数,然后设置子函数的原型使其指向父函数创建的实例

<script type="text/javascript">
function SuperType(name) {
this.name = name || "mo";
}
}
SuperType.prototype.getName = function () {
return this.name;
}
function SubType() {
SuperType.call(this,"mo");
} SubType.prototype = new SuperType();
// 此时SubType.prototype的constructor以改变,并且指向了SuperType var ins1 = new SubType();
console.log(ins1.getName()); // mo
</script>

注意:new SuperType()是创建了一个新对象出来,所以要赋值给SubType的原型prototype,不能赋给函数。利用子类的原型来实现继承。

这种模式的缺点

  • 父函数被调用了两次,因此导致了其效率十分低下的问题。
  • 自身的属性(name)也会被继承两次

类式继承模式#4——共享原型

方法

把可复用的成员转移到原型中而不是放在this对象中,即让子对象的原型等于父对象的原型

	<script type="text/javascript">
function Parent(name) {
this.name = name||"mo";
}
Parent.prototype.sayName = function() {
return this.name;
} function Child(name) {
Parent.call(this,name);
} function inherit (C,P) {
C.prototype = P.prototype;
}
inherit(Child,Parent);
var ins = new Child();
console.log(ins.name);
</script>

缺点

  • 如果继承下方的某处存在一个子对象或者孙对象修改了原型,它将会影响所用的父对象和祖先对象

类式继承模式#5——临时构造函数

方法

通过断开父对象与子对象原型之间的直接链接关系,从而解决共享同一个原型的问题,即构造一个新的空的构造函数做代理

	<script type="text/javascript">
function Parent(name) {
this.name = name||"mo";
}
Parent.prototype.sayName = function() {
return this.name;
} function Child(name) {
Parent.call(this,name);
} function inherit (C,P) {
var F = function() {};
F.prototype = P.prototype;
C.prototype = new F();
// 重置构造函数的指针
C.prototype.constructor = C;
// uber用来储存超类,uber可以指向原始父对象的引用。
C.uber = P.prototype;
}
inherit(Child,Parent);
var ins = new Child();
console.log(ins.name);
</script>

该模式也有一个缺点:

  • 每次继承时都会创建一个新的构造函数F()

改善临时构造函数模式

方法:使用即时函数,并且在闭包中储存代理函数

		var inherit = (function () {
var F = function() {};
return function (C,P) {
F.prototype = P.prototype;
C.prototype = new F();
// 重置构造函数的指针
C.prototype.constructor = C;
// uber用来储存超类,uber可以指向原始父对象的引用。
C.uber = P.prototype;
}
})();

总结:

这种方式相对来说是比较好的,可以不继承父函数中的成员,也不会多次调用父函数,自身的属性也不会被继承多次。但是如果需要继承父函数中的成员的时候则这种模式不可取,还是的使用组合继承(也称伪经典继承)。所以没有在用的时候要看哪种继承模式是最适合自己的。

以上有哪里写的不对的,或者表述不清除的地方,欢迎来指正。

js类式继承模式学习心得的更多相关文章

  1. javascript类式继承模式#2——借用构造函数

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. javascript类式继承模式#4——共享原型

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. javascript类式继承模式#3——借用和设置原型

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. javascript类式继承模式#1——默认模式

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 精读JavaScript模式(八),JS类式继承

    一.前言 这篇开始主要介绍代码复用模式(原书中的第六章),任何一位有理想的开发者都不愿意将同样的逻辑代码重写多次,复用也是提升自己开发能力中重要的一环,所以本篇也将从“继承”开始,聊聊开发中的各种代码 ...

  6. js原生设计模式——2面向对象编程之继承—new类式继承

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  7. js原生继承之——类式继承实例(推荐使用)

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  8. 【读书笔记】读《JavaScript模式》 - 函数复用模式之类式继承模式

    实现类式继承的目标是通过构造函数Child()获取来自于另外一个构造函数Parent()的属性,从而创建对象. 1.类式继承模式#1 —— 默认方式(原型指向父函数实例) function Paren ...

  9. JS原型继承和类式继承

    前言 一个多月前,卤煮读了一篇翻译过来的外国人写的技术博客.此君在博客中将js中的类(构造)继承和原型继承做了一些比较,并且得出了结论:建议诸位在开发是用原型继承.文中提到了各种原型继承的优点,详细的 ...

随机推荐

  1. 远程调试js注意事项

    1:使用host切换工具,先注释掉93服务器的地址,打开链接,点击高级选项,进去后登陆账号密码(如果不行重启浏览器): 2:进入后,增加93服务器上的host地址,重启浏览器,css样式生效: 3:使 ...

  2. Centos下安装和配置SVN

    1.安装SVN服务 #检查现有版本 rpm -qa subversion #如果存储旧版本,卸载旧版本SVN yum remove subversion #安装SVN yum install subv ...

  3. 关于Maven的一些记录

    Eclipse-Mars4.5自带Maven插件,自己重新下载之后将不兼容. 可以在图中位置设置jar包路径. 可以在Eclipse新建Dynamic Web Project项目,然后在项目上右键=& ...

  4. nodejs向远程服务器发送post请求----融云Web SDK/客户端获取token

    最近要用到一个叫融云的及时通讯的SDK,在获取token这个步骤的时候有点卡顿,以防以后碰到类似的问题,再此记录一下. 客户端通过融云 SDK 每次连接服务器时,都需要向服务器提供 Token,以便验 ...

  5. AIX上增加逻辑卷时报错误0516-787 extendlv: Maximum allocation for logical volume

    AIX上增加逻辑卷时报错误0516-787 extendlv: Maximum allocation for logical volume jdelv02 is 512. 在往aix使用chfs -a ...

  6. WEB页面采集器编写经验之一:静态页面采集器

    严格意义来说,采集器和爬虫不是一回事:采集器是对特定结构的数据来源进行解析.结构化,将所需的数据从中提取出来:而爬虫的主要目标更多的是页面里的链接和页面的TITLE. 采集器也写过不少了,随便写一点经 ...

  7. excel导出字符串

     "style", "vnd.ms-excel.numberformat: @;" 

  8. C程序与Lua脚本相互调用

    Lua脚本是一种可用于C程序开发/测试的工具,本篇介绍一下C程序与Lua脚本如何进行相互调用,更加详细的操作参见<Programing in Lua>.本文分为3个部分:1.Windows ...

  9. 如何去除My97 DatePicker控件上右键弹出官网的链接

    http://my97.net/dp/My97DatePicker/calendar.js?最后结尾处: 这个就是官网链接地址了. 然后查找 net,nte,ent,etn,ten,tne最终找到了“ ...

  10. 2、SIP

    1.初学者笔记:http://www.cnblogs.com/gnuhpc/archive/2012/01/16/2323637.html 2.SIP头字段解释:http://www.cnblogs. ...