JS设计模式——4.继承(概念)

类式继承

0.构造函数

一个简单的Person类

function Person(name){
    this.name = name;
}
Person.prototype.getName = function(){
    return this.name;
}

1.原型链实现继承

未封装extend函数继承

继承步骤如下:

step 1:创建继承类的构造函数

step 2:设置继承类的原型链为父类构造函数。

step 3:调整继承类的构造函数。

step 4:创建继承类

function Author(name, books){
    Person.call(this, name); //step 1
    this.books = books;
}
Author.prototype = new Person(); //step 2
Author.prototype.constructor = Author; // step 3
Author.prototype.getBooks = function(){
    return this.books;
};
var author = new Author('ysy',['js desgin']); // step 4

简单封装extend函数继承

function extend(subClass, superClass){
    var F = function(){};
    F.prototype = superClass.prototype;
    subClass.prototype = new F(); // step 2
    subClass.prototype.constructor = subClass; // step3
}

这种展示了封装的原理,但是step1并没有封装进来,而最重要的是step1中会产生对Person的耦合。

高级封装extend函数继承

function extend(subClass, superClass){
    var F = function(){};
    F.prototype = superClass.prototype;
    subClass.prototype = new F();
    subClass.prototype.constructor = subClass;
    subClass.superclass = superClass.prototype;
    if(superClass.prototype.constructor == Object.prototype.constructor){
        superClass.prototype.constructor = superClass;
    }
}

这样在构建子类的构造函数时示例如下:

function Author(name, books){
    Author.superclass.constructor.call(this, name);
    this.books = books;
}
extend(Author, Person);

原型式继承

 0.原型对象

直接定义一个对象即可

var Person = {
    name: 'ysy',
    getName: function(){
        return this.name;
    }
}

1.对继承而来的成员的读和写的不对等性

这个其实很好理解,如果在读属性之前还未对继承而来的属性进行赋值操作,那么读的就是super中的属性,而此时写的话,却是对sub中的写。

当然,一旦写过之后,读和写就是对等的了。

这个简单问题就不再给出代码了。如果你不懂,就去彻底了解一下原型链。

2.clone函数

function clone(obj){
    function F(){}
    F.prototype = obj;
    return new F;
}

3.继承的实现

var Author = clone(Person);
Author.books = [];
Author.getBooks = function(){
    return this.books;
}

貌似这个继承的实现要简单好多哇。

继承与封装

只有公用和特权成员会被继承下来。

因此,门户大开型式最适合派生自雷的。它们的所有成员都是公开的,因此可以被遗传给子类。如果某个成员需要稍加隐藏,可以用下划线规范。

在派生具有真正的私有成员的类时,特权方法是公用的,可以被继承,因此也就可以访问父类的私有成员,但是我们不能在子类中添加能够直接访问他们的新的特权方法。

掺元类

有一种重用代码的方法不需要用到严格的继承。

他的做法是:先创建一个包含各种通用方法的类,然后再用他扩充其他类。

这种包含通用方法的类就是掺元类。

下面定义一个简单的掺元类:

var Mix = function(){};
Mix.prototype = {
    serialize: function(){
        var output = [];
        for(key in this){
            output.push(key+':'+this[key]);
        }
        return output.join(',');
    }
}
augment(Author, Mix);
var author = new Author('Ross', ['js desgin']);

augment其实很简单。他用一个for in将giving class的prototype中的每个成员都添加到receiving class中。

function augment(rclass, gclass){
    if(arguments[2]){ //giving more than 3 paras
        for(var i=2, len=arguments.length; i<len; i++){
            rclass.prototype[arguments[i]] = gclass.prototype[arguments[i]];
        }
    }else{
        for(methodName in gclass.prototype){
            if(!rclass.prototype[methodName]){
                rclass.prototype[methodName] = gclass.prototype[methodName];
            }
        }    
    }
}

上面的方法还可以指明只继承其中的部分成员。

 掺元类的重大有点就是可以实现多继承效果,其他的方法就没法了,因为一个对象只能有一个原型对象。

原文地址:https://www.cnblogs.com/JChen666/p/3597028.html