• 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];
                }
            }    
        }
    }

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

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

  • 相关阅读:
    GIS的核心价值——服务
    Arcgis Add-In开发入门实例
    Arcgis for Androd API开发系列教程(一)——地图显示与GPS定位
    Spring
    字体大小对照换算表
    属性和字段的区别
    sqlDataAdapter和SqlCommand的区别
    C# 连接SQL Server数据库的几种方式--server+data source等方式
    c# using的作用
    random
  • 原文地址:https://www.cnblogs.com/JChen666/p/3597028.html
Copyright © 2020-2023  润新知