javascript中超出了最大调用堆栈大小

时间:2013-08-21 10:22:55

标签: javascript inheritance scope

我编写了一个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方法导致问题,callSuper调用initinit调用callSuper,两者都具有相同的上下文。

但我不知道如何解决它!

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

1 个答案:

答案 0 :(得分: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();
}

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

的jsfiddle