《JavaScript高级程序设计》--继承
来源:互联网 发布:毛昆仑 常凯申 知乎 编辑:程序博客网 时间:2024/05/29 20:01
最近看《JavaScript高级程序设计》看到了继承一章, 在JavaScript中也是非常重要的一个概念, 所以觉得需要在这里总结一下. 继承的方式一共有6种:1. 原型链 2.借用构造函数 3.组合继承 4.原型式继承 5.寄生式继承 6.寄生组合式继承
一. 原型链
其基本思想就是利用原型让一个引用类型继承另一个引用类型的属性和方法, 实现方法如下:
- function SuperType(){
- this.property = true;
- }
- SuperType.prototype.getSuperValue = function(){
- return this.property;
- };
- function SubType(){
- this.subproperty = false;
- }
- //继承了SuperType
SubType.prototype = new SuperType();
- SubType.prototype.getSubValue = function(){
- return this.subproperty;
- }
- var instance = new SubType();
- alert(instance.getSuperValue()); //true
缺点: 1. 通过原型链的话, 超类型的引用类型的属性会被子类型的所有实例共享, 那么改变其中一个子类型实例的属性就会使所有实例的属性都一起发生变化.
2. 在创建子类型的实例时, 无法向超类型的构造函数中传递参数, 因此在实践中很少会单独使用原型链
二. 借用构造函数
基本思想: 在子类型的构造函数的内部调用超类型构造函数, 实现方法如下:
- function SuperType(name){
- this.name = name;
- }
- function SubType(){
- //继承了SuperType, 同时传递了参数
- SuperType.call(this, "Nicholas");
- this.age = 29;
- this.sayName = function(){
- alert(this.name);
- }
- }
- var instance = new SubType();
- alert(instance.name); //Nicholas
- alert(instance.age); //29
- var sub1 = new SubType();
- var sub2 = new SubType();
- console.log(sub1.sayName === sub2.sayName); //false
缺点:方法都在构造函数中定义, 因此函数复用就无从谈起(17行的结果是false), 而且在超类型的原型中定义的方法, 对子类型而言也是不可见的, 结果所有的类型都只能使用构造函数模式, 因此借用构造函数的技术也是很少单独使用的.
三. 组合继承:
基本思路是: 使用原型链实现对原型属性和方法的继承, 而通过借用构造函数类实现对实例属性的继承, 实现方法如下:
- function SuperType(name){
- this.name = name;
- this.colors = ['red', 'blue', 'green'];
- }
- SuperType.prototype.sayName = function(){
- alert(this.name);
- }
- function SubType(name, age){
- SuperType.call(this, name);
- this.age = age;
- }
- SubType.prototype = new SuperType();
- SubType.prototype.constructor = SubType;
- SubType.prototype.sayAge = function(){
- alert(this.age);
- }
组合继承避免了原型链和借用构造函数的缺陷, 融合了他们的优点, 成为了JavaScript中最常用的继承模式, 而且, instanceof和isPrototypeOf也能够用于识别基于组合继承创建的对象
四. 原型式继承
思路:借助原型可以基于已有的对象创建新对象, 同时还不比因此创建自定义类型, 实现方法如下:
- function object(o){
- function F(){};
- F.prototype = o;
- return new F();
- }
- var person = {
- name: "Nicholas",
- friends: ["Shelby", "Court", "Van"]
- };
- var anotherPerson = object(person);
- anotherPerson.name = "Greg";
- anotherPerson.friends.push("Rob");
- alert(person.friends); //Shelby, Court, Van, Rob, Barbie
缺点:包含引用类型值的属性始终都会共享相应的值, 就像使用原型模式一样
五. 寄生式继承
基本思路:创建一个仅用于封装继承过程的函数, 该函数在内部以某种方式来增强对象,最后返回对象, 实现方式如下:
- function createAnother(original){
- var clone = object(original);
- clone.sayHi = function(){
- alert("hi");
- };
- return clone;
- }
缺点:由于不能做到函数复用而降低效率
六. 寄生组合式继承
前面说过, 组合继承是JavaScript中最常用的继承模式, 不过他也有自己的不足. 组合继承最大的问题就是无论什么情况下, 都会调用两次超类型构造函数, 而寄生组合式继承就要解决这个问题, 提高效率. 基本思路: 不必为了指定子类型的原型而调用超类型的构造函数, 我们所需要的无非就是超类型原型的一个副本而已. 本质上, 就是使用寄生式继承来继承超类型的原型, 然后将结果指定给子类型的原型. 实现方式如下:
- function inheritPrototype(subType, superType){
- var prototype = object(superType.prototype); //原型链方式
- prototype.constructor = subType;
- subType.prototype = prototype;
- }
- function SuperType(name){
- this.name = name;
- this.colors = ['red', 'blue', 'green'];
- }
- SuperType.prototype.sayName = function(){
- alert(this.name);
- }
- function SubType(name, age){
- SuperType.call(this, name);
- this.age = age;
- }
inheritPrototype(SubType, SuperType);
- SubType.prototype.sayAge = function(){
- alert(this.age);
- }
这个例子的高效率体现在它只调用了一次SuperType构造函数, 并且因此避免了在SubType.prototype上面创建不必要的, 多余的属性. 在此同时, 原型链还能保持不变. 开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式.
- 《JavaScript高级程序设计》--继承
- 《 JavaScript高级程序设计》第四章 继承
- 《JavaScript高级程序设计》学习笔记(继承)
- javascript高级程序设计学习(四)----------继承
- JavaScript高级程序设计 (6章 继承)---读书笔记
- JavaScript高级程序设计【面向对象-继承】
- Javascript高级程序设计读书笔记——继承
- 《JavaScript 高级程序设计》 继承有关的总结
- javascript高级程序设计笔记4-继承
- 【JavaScript高级程序设计】对象的创建与继承
- 《JavaScript高级程序设计》——对象与继承
- JavaScript高级程序设计-学习笔记5(继承)
- JavaScript高级程序设计一书中对组合继承的理解
- 读:JavaScript 高级程序设计
- 阅读“JavaScript高级程序设计”
- JavaScript高级程序设计
- JavaScript 高级程序设计
- dom javascript高级程序设计
- bzoj2594
- HTML ---表格
- POJ3254:Corn Fields(状压dp入门)
- 《JavaScript高级程序设计》--BOM
- Intellj Idea 2016 快速搭建javaweb,Tomcat项目
- 《JavaScript高级程序设计》--继承
- SSM框架注解整合
- 《JavaScript高级程序设计》--创建对象1
- 链表逆置
- 【Untiy&摄像机视角】
- ex44 继承还是组成
- Linux中常用操作命令
- 内核开发:实现切换窗口后的键盘输入
- 1112. Stucked Keyboard (20)