继承在JavaScript中是一种“奇葩”的存在,因为其本身并没有类(class)的概念(ES5),所以只能用其他方式(原型链、构造函数、对象实例)来模拟继承的行为。既然是模拟,那就应该是想办法实现继承的行为特点,个人认为继承的核心就是:能复用就复用,不能复用的就复制

     写在前面:
  方法是属性的特殊形式,这里就用属性全权代表。
     函数构造器里的属性是实例属性,每个实例都有自己的一份,实例之间互不影响。
     原型对象里的属性为每个实例共享,一旦改变,所有实例的原型属性都改变。
  以下的父类(SuperType)和子类(SubType)都有自己的实例属性和原型属性,各自的构造函数就不重复了,只列出继承核心步骤以突出重点。

     1.原型链继承:

 SubType.prototype = new SuperType();
     特点:父类的所有属性(包括实例属性和原型属性)都作为了子类的原型属性。
     说明:纳尼?!一下都弄到原型属性里这样合适么,你考虑过实例属性的感受么?在父级既然是每个实例独享一份,到了子类却变成共享的了,这样使用限制很大哟!
 
     2.借用构造函数继承:
     克服原型链的不足:实例属性用构造器继承。
 
 function SubType(){
  SuperType.call(this);
}
     特点:父类的实例属性在子类还是实例属性,每个实例独一份互不干扰;另外,还可以利用call方法的特性给父类的构造函数传递参数。
     说明:原型链的问题克服了,复用呢?父类的原型属性根本就没有在子类中体现啊!这样也没法用呢。
 
     3.组合继承:
     综合一下前两种继承的优点吧,上帝的归上帝,凯撒的归凯撒。
 
function SubType(){
//继承实例属性
SuperType.call(this);
}
//继承原型属性
SubType.prototype = new SuperType();
     特点:这样比较完美了,父类的实例属性在子类中单独继承,原型属性也有了复用的特点;并且保留了传参数的优点。
     说明:但是处女座的朋友会发现,这关键的两步都调用了父类的构造函数,直接结果就是子类继承父类的实例属性会存在两份,一份在子类的原型对象中,一份在子类实例中,只不过原型属性被实例属性覆盖罢了。这是多么可耻的浪费啊!
 
     4.寄生组合式继承:
     请先不要问我“寄生”是什么意思~~组合继承的“浪费”主要是在原型链继承的过程中发生的,所以我们现在不借助父级实例重写子类原型对象,单独给子类一个只包括父类原型对象属性的对象即可。
     首先来个用于复制父类原型对象的工具函数:    

 function copy(uber){//工具函数
  var F = function(){};
  F.prototype = uber;
  return new F();
}
//继承实例属性
function SubType(){
  SuperType.call(this);
}
//继承原型属性
SubType.prototype = copy(SubType.prototype);
SubType.prototype.constructor = SubType; //不要忘记修正constructor
     特点:完美实现了继承,而且没有浪费内存空间,还能传参;就是写起来有点儿麻烦
 
     5.原型式继承
     好吧回过头来说一下这个寄生,在讲寄生前允许我啰嗦一下“原型式继承”:

 function copy(obj){
var F = function(){};
F.prototype = obj;
return new F();
}
     特点:这种继承基于实例,只需给一个父类的实例对象就“还”一个子类实例对象,直接绕过构造函数,很简单吧。
     说明:与其说是继承,其实这种方式更像是一种对象的“浅复制”,而且还有两个缺陷:1.不同子对象之间根本就没有函数的复用,2.由于是浅复制不同子对象之间会共用引用类型的属性,不能随意改动。但作者尼古拉斯说是,那就是吧。
     
     6.寄生式继承
     寄生式继承是对原型式继承的一种加强:
 
 function createAnother(original){
var clone = object(original); //不一定必须用object方法,基于original复制新创建的即可
clone.sayHi = funciton(){ …… } // 增强
return clone;
}
     特点:这里返回的clone不仅有original的所有属性,还有自己的方法。
     说明:寄生组合式继承的两个缺陷没有修复,所以我觉得这个继承方式依然很牵强;个人感觉“寄生”的由来就是将自己sayHi放在了original上面,额……回到第四种继承方式,我想体现寄生的地方就在于SubType.prototype.constructor = SubType(个人观点)
 
     总结:最常用的继承方式应该是组合式继承  和  寄生组合式继承
     
     以上是基于JS红宝书6.3继承章节的一些读书心得,欢迎吐槽。
 
 

《JavaScript高级程序设计》笔记——关于继承的更多相关文章

  1. JavaScript高级程序设计笔记之面向对象

    说起面向对象,大部分程序员首先会想到 类 .通过类可以创建许多具有共同属性以及方法的实例或者说对象.但是JavaScript并没有类的概念,而且在JavaScript中几乎一切皆对象,问题来了,Jav ...

  2. Javascript高级程序设计笔记(很重要尤其是对象的设计模式与继承)

    var obj = {'a':'a'}; var fun = function (){} console.log(typeof obj);//object console.log(typeof fun ...

  3. javascript高级程序设计--笔记01

    概述 JavaScript的实现包含三个部分: 1  核心(ECMAScript)   提供核心语言功能 2  文档对象模型(DOM)  一套提供了访问以及操作网页内容的API 3  浏览器对象模型( ...

  4. javascript事件小结(事件处理程序方式)--javascript高级程序设计笔记

    1.事件流:描述的是从页面中接收事件的顺序. 2.事件冒泡:IE的事件流叫做事件冒泡,即事件开始从具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到不具体的节点(文档). 3.事件捕获 ...

  5. JavaScript高级程序设计笔记(一)

    ---恢复内容开始--- 前三章为基础知识,为了方便以后查看,所以比较啰嗦.这里对函数的基本操作没有记录. 1.JavaScript的实现 虽然 JavaScript 和 ECMAScript 通常都 ...

  6. JavaScript高级程序设计笔记 事件冒泡和事件捕获

    1.事件冒泡 要理解事件冒泡,就得先知道事件流.事件流描述的是从页面接收事件的顺序,比如如下的代码: <body> <div> click me! </div> & ...

  7. <javascript高级程序设计>笔记

    1.要讲一个值转换成其对应的Boolean类型 ,可以调用转型函数Boolean(). var message=“hello world!”; var messageAsBoolean=Boolean ...

  8. javaScript高级程序设计笔记 2

    Undefinde Null Boolean Number String    基本类型 Object    引用类型 只有引用类型才能动态的添加属性 赋值基本类型和引用类型也不相同,复制的基本类型的 ...

  9. javaScript高级程序设计笔记 1

    核心  ECMAScript 文档对象模型  DOM 浏览器对象模型 BOM 延迟脚本  defer typeof操作符      判断字符类型  返回   undefined  boolean  s ...

  10. Javascript高级程序设计笔记 <第五章> 引用类型

    一.object类型 创建object实例的方式有两种: //第一种使用new操作符跟构造函数 var person= new Object(); person.name="小王" ...

随机推荐

  1. 关于.NET邮件的收发问题总结

    转载:http://www.cnblogs.com/ustbwuyi/archive/2007/05/28/762581.html //取数据库中邮件信息中的最大发送时间,即最近接收到的一封邮件的时间 ...

  2. HDU 4099 Revenge of Fibonacci(高精度+字典树)

    题意:对给定前缀(长度不超过40),找到一个最小的n,使得Fibonacci(n)前缀与给定前缀相同,如果在[0,99999]内找不到解,输出-1. 思路:用高精度加法计算斐波那契数列,因为给定前缀长 ...

  3. (hdu step 8.1.1)ACboy needs your help again!(STL中栈和队列的基本使用)

    题目: ACboy needs your help again! Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ...

  4. 大话数据结构—平衡二叉树(AVL树)

    平衡二叉树(Self-Balancing Binary Search Tree/Height-Balanced Binary Search Tree),是一种二叉排序树,当中每个节点的左子树和右子树的 ...

  5. hdu1050 Moving Tables

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1050 求区间上点的最大重叠次数. #include <stdio.h> #include &l ...

  6. 在vim中设置将tab自动转化为4个空格

    在vim中,我们只需要简单配置一下就ok了,打开~/.vimrc加上下面的几行(如果已经有了,修改一下数值就行了). set tabstop=4set softtabstop=4set shiftwi ...

  7. java 数组初始化

    一维数组 1)   int[] a;   //声明,没有初始化 2)   int[] a=new int[5];   //初始化为默认值,int型为0 3)   int[] a={1,2,3,4,5} ...

  8. WEB免费打印控件推荐

    在WEB系统中,打印的确是个烦人的问题. 要么自己开发打印控件,如果项目时间紧,肯定来不及. 要么购买成熟的打印控件,如果是大项目可以考虑,但如果项目只有几K到1.2W之间,这就麻烦了. 前段时间有机 ...

  9. UML 之 各种视图简介

    统一建模语言(Unified Modeling Language,UML)中各种视图并没有明显的概念区别. 在最上一层,视图被划分为三个视图域:结构,动态行为,模型管理. 结构主要描述了系统中的结构成 ...

  10. 1.7.1 solr Searching概述

    1. Overview of Searching in Solr 在用户运行一个solr搜索时,搜索查询会被request handler处理.一个request handler就是一个请求处理插件, ...