js类式继承模式学习心得
最近在学习《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类式继承模式学习心得的更多相关文章
- javascript类式继承模式#2——借用构造函数
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- javascript类式继承模式#4——共享原型
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- javascript类式继承模式#3——借用和设置原型
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- javascript类式继承模式#1——默认模式
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 精读JavaScript模式(八),JS类式继承
一.前言 这篇开始主要介绍代码复用模式(原书中的第六章),任何一位有理想的开发者都不愿意将同样的逻辑代码重写多次,复用也是提升自己开发能力中重要的一环,所以本篇也将从“继承”开始,聊聊开发中的各种代码 ...
- js原生设计模式——2面向对象编程之继承—new类式继承
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- js原生继承之——类式继承实例(推荐使用)
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- 【读书笔记】读《JavaScript模式》 - 函数复用模式之类式继承模式
实现类式继承的目标是通过构造函数Child()获取来自于另外一个构造函数Parent()的属性,从而创建对象. 1.类式继承模式#1 —— 默认方式(原型指向父函数实例) function Paren ...
- JS原型继承和类式继承
前言 一个多月前,卤煮读了一篇翻译过来的外国人写的技术博客.此君在博客中将js中的类(构造)继承和原型继承做了一些比较,并且得出了结论:建议诸位在开发是用原型继承.文中提到了各种原型继承的优点,详细的 ...
随机推荐
- python socket
#!/usr/bin/env python import sys import time import socket s = socket.fromfd(sys.stdin.fileno(),sock ...
- yii2史上最简单式安装教程,没有之一
写一篇绝对堪称史上最easy的Yii2安装教程教你入门. 既然是安装Yii,我们先去官网下载一份Yii的高级模版,什么,你说打开页面乱七八糟的英文字母你看不懂?那这样大哥,你按照下面的截图进行操作好吧 ...
- Angular $scope和$rootScope事件机制之$emit、$broadcast和$on
Angular按照发布/订阅模式设计了其事件系统,使用时需要“发布”事件,并在适当的位置“订阅”或“退订”事件,就像邮箱里面大量的订阅邮件一样,当我们不需要时就可以将其退订了.具体到开发中,对应着$s ...
- C#读写锁ReaderWriterLockSlim的使用
读写锁的概念很简单,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁.在C#中,推荐使用ReaderWriterLockSlim类来完成读写锁的功能. 某些场合下,对 ...
- QQ通信原理及QQ是怎么穿透内网进行通信的? (转)
原:http://f543711700.iteye.com/blog/978044#bc2344608 QQ是一个基于TCP/UDP协议的通讯软件 发送消息的时候是UDP打洞,登陆的时候使用HTTP~ ...
- sql server2008 检查是否需要挂起计算机重新启动。挂起重新启动会导致安装程序失败。
解决方法: 1.如果重新启动后,一样无效, 2.那么就进入注册表编辑器,通过修改注册表的方法来解决.除了删除SQL安装时遗留下的LJ文件,还必须进行以下操作: 在"开始"-&quo ...
- bzoj1553: XOR网络
Description 计算给定范围内有多少种输入可以使输出为1. 我们假设3 < n < 100, 3 < m < 3000,而且网络中的门是用1到m之间的数任意编号的. ...
- 常见的HTTP返回码如4xx, 5xx
常见的HTTP返回码如4xx, 5xx Client Error =====================400 Bad Request 因为错误的语法导致服务器无法理解请求信息.401 Unaut ...
- 梦想还是要有的-纪念正式成为csdn博客专家暨年中总结
csdn博客:http://blog.csdn.net/tuzongxun 我的csdn历程(坚持总会有收获): 一年零三个月之前,2015年3月3日,我在csdn写下第一篇技术博客,只是记录了一 ...
- java基础-servlet-2:生命周期
1.加载(class load) 2.实例化 3.init() 4.doGet() 5.destroy 只有一个对象存在于服务端提供服务.再次访问,不会再起新对象.