实现类式继承的目标是通过构造函数Child()获取来自于另外一个构造函数Parent()的属性,从而创建对象。
1.类式继承模式#1 —— 默认方式(原型指向父函数实例)
function Parent(name) {
this.name = name || 'king';
}
Parent.prototype.say = function () {
return this.name;
}; function Child(name) {
this.name = name;
} function inherit(C, P) {
/**
* 1>该继承模式同时继承了两个对象的属性,即添加到this的属性以及原型属性。
* 在绝大多数的时候,并不需要这些自身的属性,因为它们很可能是指向一个特定的实例,而不是复用。
* 但是我们可以提供覆盖属性的方式进行实例化更新。
* 2>对于构造函数的一般经验法则是:应该将可服用的成员添加到原型中。
*/
C.prototype = new P();
}
inherit(Child, Parent); var child = new Child('kingChild');
console.log(child.say()); //king
2.类式继承模式#2 —— 借用构造函数
function Parent(name) {
this.name = name || 'king';
}
Parent.prototype.say = function () {
return this.name;
}; function Child(name) {
/**
* 1>优点:可以获得父对象自身成员的真实副本,不会存在子对象意外覆盖父对象属性的风险。
* 2>缺点:无法从原型中继承任何东西 ,它并不会为每个实例重新创建原型。
*/
Parent.apply(this, arguments);
} var child = new Child('kingChild');
console.log(child.say()); //Object #<Child> has no method 'say'
3.类式继承模式#3 —— 借用和设置原型(调用了两次父构造)
function Parent(name) {
this.name = name || 'king';
}
Parent.prototype.say = function () {
return this.name;
}; function Child(name) {
//1>先借用构造函数
Parent.apply(this, arguments);
}
//2>设置子构造函数的原型使其指向父构造函数创建的新实例
Child.prototype = new Parent(); var child = new Child('kingChild');
console.log(child.say()); //kingChild
4.类式继承模式#4 —— 共享原型
function Parent(name) {
this.name = name || 'king';
}
Parent.prototype.say = function () {
return this.name;
}; function Child(name) {
this.name = name;
}
/**
* 所以的对象实例实际上都共享了同一个原型。但是,这同时也是一个缺点,
* 因为如果在继承链下方的某处存在一个子对象或者孙子对象修改了原型,它将会影响到所有的父对象和祖先对象。
*/
function inherit(C, P) {
C.prototype = P.prototype;
}
inherit(Child, Parent); var child = new Child('kingChild');
console.log(child.say()); //kingChild
5.类式继承模式#5 —— 临时构造函数
function Parent(name) {
this.name = name || 'king';
}
Parent.prototype.say = function () {
return this.name;
}; function Child(name) {}
/**
* 这里的子对象仅仅继承了父对象的原型中的属性,这种方式是可取的,因为原型正是放置可复用功能的位置。
* 在这种模式中,父构造函数添加到this中的任何成员都不会被继承。
*/
function inherit(C, P) {
var F = function () {};
F.prototype = P.prototype;
C.prototype = new F();
}
inherit(Child, Parent); var child = new Child('kingChild');
console.log(child.name); //undefined
console.log(child.say); //function () {...}
类式继承模式 —— 总结
var inherit = (function () {
/**
* 应用闭包使得在每次需要继承时都创建临时(代理)构造函数。
*/
var F = function () {};
return function (C, P) {
F.prototype = P.prototype;
C.prototype = new F();
/**
* uber属性是指向超类的指针(不使用super仅仅是因为它是关键字),
* 这就像在其他编程语言中访问超类一样,这可以偶尔排上用场。
*/
C.uber = P.prototype;
/**
* 充值构造函数指针
* 如果不充值该构造函数指针,那么所有子对象将会报告Parent()是它们的构造函数,这是没有任何用处的。
* 重置constructor属性使其指向期望的构造函数且不会影响其功能,这是由于该属性主要是用于提供对象的信息。
*/
C.prototype.constructor = C;
}
})();
源自《JavaScript模式》
【读书笔记】读《JavaScript模式》 - 函数复用模式之类式继承模式的更多相关文章
-
《JavaScript 模式》读书笔记(6)— 代码复用模式2
上一篇讲了最简单的代码复用模式,也是最基础的,我们普遍知道的继承模式,但是这种继承模式却有不少缺点,我们下面再看看其它可以实现继承的模式. 四.类式继承模式#2——借用构造函数 本模式解决了从子构造函 ...
-
《JavaScript 模式》读书笔记(6)— 代码复用模式3
我们之前聊了聊基本的继承的概念,也聊了很多在JavaScript中模拟类的方法.这篇文章,我们主要来学习一下现代继承的一些方法. 九.原型继承 下面我们开始讨论一种称之为原型继承(prototype ...
-
精读JavaScript模式(八),JS类式继承
一.前言 这篇开始主要介绍代码复用模式(原书中的第六章),任何一位有理想的开发者都不愿意将同样的逻辑代码重写多次,复用也是提升自己开发能力中重要的一环,所以本篇也将从“继承”开始,聊聊开发中的各种代码 ...
-
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类式继承模式#2——借用构造函数
<!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/ ...
-
js类式继承模式学习心得
最近在学习<JavaScript模式>,感觉里面的5种继承模式写的很好,值得和大家分享. 类式继承模式#1--原型继承 方法 让子函数的原型来继承父函数实例出来的对象 <script ...
-
《JavaScript 模式》读书笔记(4)— 函数5
这一篇是函数部分的最后一篇.我们来聊聊Curry化. 十.Curry 这部分我们主要讨论Curry化和部分函数应用的内容.但是在深入讨论之前,我们需要先了解一下函数应用的含义. 函数应用 在一些纯粹的 ...
随机推荐
-
FAT32 FAT区__FAT表解析
一. FAT 表概述 位置: 紧跟在文件系统的“保留区”之后 : 有两个数据结构完全相同的FAT(FAT,File Allocation Tbale 文件分配表)组成. 作用: FAT表项,描述文件系 ...
-
Linux:返回上一次目录 / 返回上次命令目录
返回上一次目录命令: cd - 该命令等同于cd $OLDPWD,关于这一点在bash的手册页(可使用命令man bash访问其手册页)中有介绍:An argument of - is equiva ...
-
关于将客户端移植到Lua的解决方案设想。
现在发行商都需要cp们做热更新,而对于unity制作的游戏来讲,这个恐怕是个噩梦,而项目已经进行到中后期,确实很麻烦,有UniLua,但是如果全部手动解决恐怕上不了线了工作量太大,初步设想如果做一个基 ...
-
Android面试笔试集锦
前19题为常考题目 1. Android的四大组件是哪些,它们的作用? 答:Activity:Activity是Android程序与用户交互的窗口,是Android构造块中最基本的一种,它需要为保持各 ...
-
hdu 5438(拓扑+bfs)
题意:建图,删掉所有连接点小于2的点,直到不能删为止,问最后剩余的联通块中,点的数量是奇数的联通块中的点的权值和. 思路:拓扑删点,bfs计算 #include <iostream> #i ...
-
关于OSError: [WinError 10038] 在一个非套接字上尝试了一个操作。
在使用socket的时候,写了一个while循环,就报错了.结果如下: OSError: [WinError 10038] 在一个非套接字上尝试了一个操作. 代码 import socket impo ...
-
Android 引用库项目,Debug 库项目
转自:http://www.cnblogs.com/xitang/p/3615768.html#commentform 使用引用项目,无法追到源代码,无法Debug库项目The JAR of this ...
-
vue中mounted中无法获取到dom元素
一.解决方案: 加上异步setTimeout,延迟获取dom的代码的执行 mounted() { // debugger this.$nextTick(()=> { setTimeout(()= ...
-
03-03 java 顺序语句结构,选择结构if语句
顺序结构: /* 流程控制语句:可以控制程序的执行流程. 分类: 顺序结构 选择结构 循环结构 顺序结构: 从上往下,依次执行. */ class ShunXuJieGouDemo { public ...
-
USB速率识别
低速设备D-上有一个1.5k欧的上拉电阻.高速和全速设别在D+上有一1.5k欧上拉电阻.连接后通过检测电压变化来了解设备是否为低速设别. 低速下:D+为“0”,D-为“1”是为“J”状态,“K”状态相 ...