Javascript apply - 继承类

时间:2011-08-18 16:19:24

标签: javascript

以下代码改编自this answer

    function MessageClass() {
        var self = this;
        this.clickHander = function(e) { self.someoneClickedMe = true; };

        var _private = 0;
        this.getPrivate = function() { return _private; };
        this.setPrivate = function(val) { _private = val; };
    }

    ErrorMessageClass.prototype = new MessageClass();
    function ErrorMessageClass() {
        MessageClass.apply(this, arguments);
    }

    var errorA = new ErrorMessageClass();
    var errorB = new ErrorMessageClass();
    errorA.setPrivate('A');
    errorB.setPrivate('B');
    console.log(errorA.getPrivate()); 
    console.log(errorB.getPrivate());

原始帖子没有MessageClass.apply(this, arguments);,因为目的是显示Javascript中的继承可能出错。

我的问题是,正在说:ErrorMessageClass.prototype = new MessageClass(); 之前 ErrorMessageClass构造函数甚至被宣布为不良做法?我的理解是,调用未声明的标识符会导致发生静默声明,结果放在全局窗口对象上,我理解这很糟糕。

是这种形式:

    function ErrorMessageClass() {
        MessageClass.apply(this, arguments);
    }
    ErrorMessageClass.prototype = new MessageClass();

被认为是更好的做法? This link显示了上面编写的代码,这就是我尝试它的原因。这个博客是否知道我不喜欢的东西(很可能)?

修改

下面的答案中有很多很棒的信息,但我确实想要突出显示this link,它真正解释了事情

2 个答案:

答案 0 :(得分:3)

通常,为了避免这种混淆,你只需要附上原型,但正如Adam Rackis指出的那样,函数声明被提升,就像var语句一样。

但是,您不应将基础对象实例化为原型。如果您的基础对象采用参数,您应该使用什么?使用空的“代理”构造函数

// Used to setup inheritance
function surrogate () {};


function MessageClass() {
    var self = this;
    this.clickHander = function(e) { self.someoneClickedMe = true; };

    var _private = 0;
    this.getPrivate = function() { return _private; };
    this.setPrivate = function(val) { _private = val; };
}

// The key steps to creating clean inheritance
surrogate.prototype = MessageClass;
// Sets up inheritance without instantiating a base class object
ErrorMessageClass.prototype = new surrogate();
// Fix the constructor property
ErrorMessageClass.prototype.constructor = ErrorMessageClass

function ErrorMessageClass() {
    MessageClass.apply(this, arguments);
}

还有更多要说的。 http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html

答案 1 :(得分:2)

它起作用,因为首先评估函数声明。如果您尝试在对象文字“命名空间”下移动这些类,则第一个版本将失败。

我个人觉得第二种方法更易于阅读 - 另外,不要忘记将子类'prototype.constructor属性设置回自身。就个人而言,我在Function原型上使用了inherits()方法,它基本上包含了你在这里使用的代码类型。