2

我写了一个extend方法来实现javascript中的继承:

function Class() {}

Class.prototype.create = function () {
    var instance = new this();
    instance.init();
    return instance;
}


// extend method
Class.extend = Class.prototype.extend = function (props) {
    var SubClass = function () {};

    SubClass.prototype = Object.create(this.prototype);
    for (var name in props) {
        SubClass.prototype[name] = props[name];
    }
    SubClass.prototype.constructor = SubClass;

    if (this.prototype.init) {
        SubClass.prototype.callSuper = this.prototype.init; 
    }
    
    SubClass.extend = SubClass.prototype.extend;
    SubClass.create = SubClass.prototype.create;

    return SubClass;
}


// level 1 inheritance
var Human = Class.extend({
    init: function () {
    }
});

// level 2 inheritance
var Man = Human.extend({
    init: function () {
        this.callSuper();
    }
})

// level 3 inheritance
var American = Man.extend({
    init: function () {
        this.callSuper();
    }
})

// initilization 
American.create();

然后开发工具报告Maximum call stack size exceeded

我认为该callSuper方法会导致问题,callSupercallinitinitcallcallSuper都具有相同的上下文。

但我不知道如何修复它!

任何人都可以帮助我吗?如何设置正确的上下文?

4

1 回答 1

1

你有一个范围问题。这是解决方案:

function Class() {}

Class.prototype.create = function () {
    var instance = new this();
    instance.init();
    return instance;
}


// extend method
Class.extend = Class.prototype.extend = function (props) {
    var SubClass = function () {},
        self = this;

    SubClass.prototype = Object.create(this.prototype);
    for (var name in props) {
        SubClass.prototype[name] = props[name];
    }
    SubClass.prototype.constructor = SubClass;

    if (this.prototype.init) {
        SubClass.prototype.callSuper = function() {
            self.prototype.init();
        }
    }

    SubClass.extend = SubClass.prototype.extend;
    SubClass.create = SubClass.prototype.create;

    return SubClass;
}


// level 1 inheritance
var Human = Class.extend({
    init: function () {
        console.log("Human");
    }
});

// level 2 inheritance
var Man = Human.extend({
    init: function () {
        console.log("Man");
        this.callSuper();
    }
})

// level 3 inheritance
var American = Man.extend({
    init: function () {
        console.log("American");
        this.callSuper();
    }
})

// initilization 
American.create();

关键时刻是将init方法包装在一个闭包中:

SubClass.prototype.callSuper = function() {
    self.prototype.init();
}

这是一个包含解决方案的 jsfiddle http://jsfiddle.net/krasimir/vGHUg/6/

于 2013-08-21T10:54:40.290 回答