精通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
    };

}());
阅读 2.8k
1 个回答
  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();
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题