首页 >社区问答列表 >面向对象设计模式 - 精通Javascript中的一段代码不太懂,麻烦大神帮我看看

面向对象设计模式 - 精通Javascript中的一段代码不太懂,麻烦大神帮我看看

一段用于实现继承的代码,有两处不太明白, 不明白的地方我写在代码的注释中了
classDifination是一个对象直接量,该对象包含新对象的属性和方法, parentProto是要继承的父类对象原型

var Class = (function (){

    function create(classDifination, parentProto){

        var _NewClass = function (){

            if(this.initialize && typeof this.initialize === 'function'){
                this.initialize.call(this, arguments);
            }
        },
        _name;
        
        
        if(parentProto){
            //这里用了原型继承,下面为什么还要再拷贝一次?
            _NewClass.prototype = new parentProto.constructor();
            
            for(_name in parentProto){
                if(parentProto.hasOwnProperty[_name]){
                    _NewClass.prototype[_name] = parentProto[_name];
                }
            }
        }

        // 模拟多态
        function polymorph(thisFunction, parentFunction){

            return function (){
                var output;
                // 这个this.__parent在这里做了什么?
                this.__parent = parentFunction;
                output = thisFunction.apply(this, arguments);
                delete this.__parent;
                return output;
            };
        }

        for(_name in classDifination){
            if(classDifination.hasOwnProperty(_name)){

                if(parentProto[_name] && classDifination[_name] && typeof classDifination[_name] === 'function'){

                    _NewClass.prototype[_name] = polymorph(classDifination[_name], parentProto[_name]);
                }else{

                    _NewClass.prototype[_name] = classDifination[_name];
                }
            }
        }

        _NewClass.prototype.constructor = _NewClass;

        _NewClass.prototype.extend = extend;

        return _NewClass;

    }

    function extend(classDifination){
        return create(classDifination, this.prototype);
    }

    return {
        create: create
    };

}());

  • 伊谢尔伦
  • 伊谢尔伦    2017-04-10 16:11:551楼

    1. _NewClass的原型是用parentProto的构造函数创建的对象,不是parentProto对象,所以还要再把parentProto中的属性拷贝一次

    2. 就是让你在继承后的子类方法中可以用this.__parent()来访问父类的同名方法。这个this.__parent是每次调用子类的方法时自动创建的,方法执行完之后就删除,所以其他代码不能用这个属性(也就是说,仅在该子类的方法内部才能使用)


    给你一个简单的例子

    之前没有认真看,在写例子的过程中发现你给的那个代码里有不少问题,不知道是你贴错了还是原本就有问题。

    // 1.
    this.initialize.call(this, arguments); // 这里的call应该是apply
    
    // 2.
    if(parentProto.hasOwnProperty[_name]){ // 这里应该是(),方法调用

    下面是例子。具体参照里面的注释

    function Parent() {
    };
    function AnotherConstructor() {
    };
    Parent.prototype = {
        constructor : Parent, // 去掉这句,或者指定为AnotherConstructor试试
        hi   : function() {
            console.log('hi ' + this.him + ', this is parent');
        },
        parentFoo : function() {
            console.log('foo in parent');
        }
    };
    
    var Child = Class.create({
            // initialize相当于子类的构造方法,会在new Child的时候调用
            initialize : function(him) {
                this.him = him;
            },
            hi   : function() {
                this.__parent(); // call superclass method
                console.log('hi ' + this.him + ', this is child');
            },
            foo  : function() {
                console.log('foo in child');
            }
        }, new Parent());
    
    var child = new Child('tester');
    // hi方法在子类和父类中都有定义,可以this.__parent()调用父类的
    child.hi();
    // foo只在子类中定义
    child.foo();
    // parentFoo只在父类中定义
    // 单从constructor不一定能够继承到这个方法
    // 因为constructor既可以继承,也可以修改,未必一定是Parent
    // 可以把Parent.prototype中的constructor那句去掉试一试
    child.parentFoo();

    +0添加回复

  • 回复