javascript中的继承[四] 总结(《ObjectOriented JavaScript》第六章)

前面两章中提到的实现继承的方法,都是《Object-Oriented JavaScript》第六章提及的,书中最后也做了总结:

In this chapter you learned quite a few ways (patterns) for implementing inheritance.

The different types can roughly be divided into:

  1. Patterns that work with constructors
  2. Patterns that work with objects

You can also classify the patterns based on whether they:

  1. Use the prototype
  2. Copy properties
  3. Do both (copy properties of the prototype)

     第六章介绍了一些继承的方法,分为两模式:

        基于构造函数生成对象的模式

        直接继承对象的模式

    也可以按照另一种思路分类:

        使用了原型prototype

        复制属性

        复制原型的属性

可以说,这是实现继承的最核心的内容,实践中常常交错在一起。回顾下前文介绍的基本继承方式:

//构造函数 使用原型链
Coder.prototype = new Person("无名");
//构造函数 共享原型链 Coder.prototype
= Person.prototype;
//构造函数 使用原型链 只继承原型属性方法 function extend(Child,Parent){
var F = function(){}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; }
//构造函数 使用原型链 复制原型属性 function extend2(Child,Parent){
var p = Parent.prototype; var c = Child.prototype; for(var i in p){ c[i] = p[i]; } }
//继承对象 复制属性 function extendCopy(p, c){
var c = c || {}; for(var i in p){ c[i]=p[i]; } return c; }
//继承对象 深复制 function deepCopy(){}
//继承对象 使用原型链 function
object(o){ function F(){}; F.prototype = o; return new F(); }
//继承对象 使用原型链 复制属性 function objectPlus(o, stuff){}
//继承对象 复制属性 function multi(){}

遗留的一些事情

1.之前的文章中出现以下代码

function Person(name){
    this.name = name;
}
Person.prototype.sayHello = function(){
    alert(this.name);
};

function Coder(name,language){
   this.language = language;
       this.name = name;
}

Coder.prototype = new Person("无名");
Coder.prototype.constructor = Coder;
Coder.prototype.code = function(){
    alert("i am a "+this.language+" coder");
};

我们改造下这段代码,主要解决子类调用父类的构造函数中初始化代码,自行对比优缺点:

function Person(name){
    this.name = name;
}
Person.prototype.sayHello = function(){
    alert(this.name);
};

function Coder(name,language){
       Person.apply(this,arguments);
   this.language = language;
}

extend2(Coder,Person);
Coder.prototype.code = function(){
    alert("i am a "+this.language+" coder");
};

通过 Person.apply(this,arguments)调用父类的构造方法,extend2继承父类的原型方法,最后再扩展原型方法。

如果扩展的原型方法很多,我想你一定有办法知道如果通过之前的基础方法,写出一个新的符合你自己要求的继承机制。

我们完全可以写一个 extend3(Coder,Person,stuff)的方法~如果你有需要这么做的话。

2.几个函数操作

obj instanceof F // 判断对象obj是否是F的实例

F.prototype.isPrototypeOf(obj)//作用同上

obj.constructor // 返回obj的构造函数 

obj.hasOwnProperty('属性名') // 判断obj是否有属于自己的属性,而不是他所指原型的属性

这几个操作帮助理解原型链、继承过程,在实践中也有很重要的作用。

3.关于 子“类”调用父"类"的方法、属性

有三个类 Shape TwoDShape Triangle 形状、2D形状、三角形,他们继承关系。

对象实例需要实现一种方法:toString() 不仅要输出自己的类名,还要输出祖辈的类名。

如何实现呢?

由于继承的实现方式挺多的,而且子“类”的这种需求千变万化,如何有效控制,文章(本人能力有限)一句话说不清楚,《o-o》中也只是穿插地说了一下。

基本的一种思路是 在 Parent加一个静态属性uber指向Child.prototype


function extend(Child,Parent){
    var F = function(){};
    F.prototype = Parent.prototype;
    Child.prototype = new F();
Child.prototype.constructor
= Child;

Child.uber = Parent.prototype;
}


function
Shape(){}; Shape.ptototype.name = "shape"; Shape.prototype.toString = function(){ var result = []; if(this.constructor.uber){ result[result.length] = this.constructor.uber.toString(); } result[result.length] = this.name; return result.join(', '); }; function TwoDShape(){}; extend(TwoDShape,Shape); TwoDshape.prototype.name = "2dShape"; function Triangle(side, height){ this.side = side; this.height = height; }; extend(Triangle, TwoDShape); Triangle.prototype.name = "triangle"; Triangle.prototype.getArea = function(){return this.side*this.height/2;}; var my = new Triangle(3,4); my.toString();

复制原型属性的时候

function extend2(Child,Parent){
    var p = Parent.prototype;
    var c = Child.prototype;
    for(var i in p){
        c[i] = p[i];
    }
    c.uber = p;
}

对象直接继承的时候

function object(o){
    var n;
    function F(){}
    F.prototype = o;
    n = new F();
    n.uber = o;
    return n;

}

上面的实现 都是 《o-o》第六章中提及的

实例、原型、构造函数  谁可以最直接地调用方法uber ,以及要产生什么效果,按需实现。

uber 是源于德语,super是js中的一个关键词,因此建议使用uber

到此,《o-o》第六章的内容都介绍完毕,内容基于自己的梳理,增加了自己的理解,难免有疏漏之处,请指正。

欢迎大家看原著,国内也出了翻译版~




苦逼码农一个,
人力资源管理专业本科毕业,
懂点c#,
懂点javascript,
懂点sql,
懂点设计模式
...

@我是赵六六

q:329952402

原文地址:https://www.cnblogs.com/acjialiren/p/2984258.html