面向对象设计模式 - 精通Javascript中的一段代码不太懂,麻烦大神帮我看看
怪我咯
怪我咯 2017-04-10 16:09:55
[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
    };

}());
怪我咯
怪我咯

走同样的路,发现不同的人生

全部回复(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();
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号