原型模式(三)

参考:

前面两节主要学习javascript原型的基本语法和理论,这一章主要来聊聊,其他组件是怎么使用原型的

原生继承

    var Window = function () {
        this.init.apply(this, arguments);
    }

    Window.prototype = {
        init: function (name) {
            this.type = this.getConstructor();
            this.name = name
        },
        getType: function () {
            return this.type;
        },
        getConstructor: function () {
            return 'Window';
        }
    }

    var Dialog = function () {
        Window.apply(this, arguments);//继承构造器
    };
    Dialog.prototype = new Window();//继承原型
    Dialog.prototype.getConstructor = function () {//扩展父类方法
        return 'Dialog';
    };
    var _window = new Window('window1');
    var _dialog = new Dialog('dialog2');

使用的是组合继承,只不过多了一个init方法,在构造函数中调用调用init方法,实现构造函数的功能。

jquery中的原型使用

    function deepcopy(p, c) {
        var c = c || {};

        for (var i in p) {
            if (typeof p[i] == 'object') {
                c[i] = (p[i].constructor === Array ? [] : {});
                deepcopy(p[i], c[i]);
            } else {
                c[i] = p[i];
            }
        }
        return c;
    }

    function Super(){
    }
    Super.friends = ['小明'];

    var sub1= deepcopy(Super);
    var sub2= deepcopy(Super);

    sub1.friends.push('小华');
    console.log(sub1.friends);//[ '小明', '小华' ]
    console.log(sub2.friends);//[ '小明' ]

jquery采用的时深复制,来实现继承

源码:

    jQuery.extend = jQuery.fn.extend = function() {
        var options, name, src, copy, copyIsArray, clone,
            target = arguments[ 0 ] || {},
            i = 1,
            length = arguments.length,
            deep = false;

        // Handle a deep copy situation
        if ( typeof target === "boolean" ) {
            deep = target;

            // Skip the boolean and the target
            target = arguments[ i ] || {};
            i++;
        }

        // Handle case when target is a string or something (possible in deep copy)
        if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
            target = {};
        }

        // Extend jQuery itself if only one argument is passed
        if ( i === length ) {
            target = this;
            i--;
        }

        for ( ; i < length; i++ ) {

            // Only deal with non-null/undefined values
            if ( ( options = arguments[ i ] ) != null ) {

                // Extend the base object
                for ( name in options ) {
                    src = target[ name ];
                    copy = options[ name ];

                    // Prevent never-ending loop
                    if ( target === copy ) {
                        continue;
                    }

                    // Recurse if we're merging plain objects or arrays
                    if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
                        ( copyIsArray = jQuery.isArray( copy ) ) ) ) {

                        if ( copyIsArray ) {
                            copyIsArray = false;
                            clone = src && jQuery.isArray( src ) ? src : [];

                        } else {
                            clone = src && jQuery.isPlainObject( src ) ? src : {};
                        }

                        // Never move original objects, clone them
                        target[ name ] = jQuery.extend( deep, clone, copy );

                    // Don't bring in undefined values
                    } else if ( copy !== undefined ) {
                        target[ name ] = copy;
                    }
                }
            }
        }

        // Return the modified object
        return target;
    };

YUI继承实现

    function extend(Child, Parent) {
        function F() {
        }

        F.prototype = Parent.prototype;
        Child.prototype = new F();
        Child.prototype.constructor.constructor = Child;
        return Child;
    }


    function Super() {
    }

    Super.prototype.type = "超类";

    function Sub(name) {
        this.name = name;
    }

    extend(Sub, Super);

    var sub = new Sub("sub");
    console.log(sub.name);//sub
    console.log(sub.type);//超类

Nodejs 继承实现

示例

    var utils= require('util');

    function Animal(){}

    Animal.prototype.type ="动物";
    function Cat(){}
    utils.inherits(Cat,Animal);
    var cat1 = new Cat();
    var cat2 = new Cat();
    console.log(cat1.type);//动物
    cat2.__proto__.type = "猫";
    console.log(cat1.type);//猫

源码

    exports.inherits = function(ctor, superCtor) {

      if (ctor === undefined || ctor === null)
        throw new TypeError('The constructor to `inherits` must not be ' +
                            'null or undefined.');

      if (superCtor === undefined || superCtor === null)
        throw new TypeError('The super constructor to `inherits` must not ' +
                            'be null or undefined.');

      if (superCtor.prototype === undefined)
        throw new TypeError('The super constructor to `inherits` must ' +
                            'have a prototype.');

      ctor.super_ = superCtor;
      ctor.prototype = Object.create(superCtor.prototype, {
        constructor: {
          value: ctor,
          enumerable: false,
          writable: true,
          configurable: true
        }
      });
    };

object.create用法

推荐阅读更多精彩内容

  • 在线阅读 http://blog.poetries.top/FE-Interview-Questions 目录 $...
    poetries阅读 46,158评论 14 380
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 135,448评论 17 574
  • (自传自文,本文首发于LOL大咖) 导语: 文森特解约事件在LOL圈内掀起轰然大波,不仅仅是文森特的极高人气和巨额...
    晚甘侯阅读 15,686评论 2 9
  • 故乡,就是那个 你回来时种种的嫌弃,但是却能带给你一种久违的亲切感 虽然物是人非,自己也不在是那个小女孩,但是它带...
    大树与洞阅读 45评论 0 2
  • // 使用Proxy实现propotypal inheritancefunction MultiPrototype...
    coldtiger阅读 74评论 0 1