【问题标题】:How to extends a javascript object?如何扩展 javascript 对象?
【发布时间】:2011-12-04 07:59:17
【问题描述】:

我用 babel 对象做了一个简单的例子:

function babel(){
    this.english = {
        hello: function () { alert('hello'); },
        goodbye: function () { alert('goodbye'); }
        teeshirt: function () { alert('T-shirt'); }
    }
}

现在,我想扩展这个对象:

babel.prototype.french = {
    bonjour: function () { alert('bonjour'); },
    aurevoir: function () { alert('au revoir'); }
}

但是如果我需要使用之前定义的现有函数呢?

babel.prototype.french = {
    bonjour: function () { alert('bonjour'); },
    aurevoir: function () { alert('aurevoir'); },
    teeshirt: function () { this.english.teeshirt(); }
}

我能做的是:

var say = new babel();

(function (_this) {
    babel.prototype.french = {
    bonjour: function () { alert('bonjour'); },
    aurevoir: function () { alert('aurevoir'); },
    hello: function () { _this.english.hello(); }
    }
})(say);

但在这种情况下,我将始终使用 say 对象的上下文,不是吗?

【问题讨论】:

  • 您想让var b = new babel(); b.french.teeshirt(); 提醒“T 恤”吗?还是其他一些行为?
  • 是的,这是我想要的行为,但此外,我想使用我的对象的上下文。

标签: javascript


【解决方案1】:

问题是,在 teeshirt 函数中调用 this 指向的是 french 对象,而不是 babel 对象。如果您必须访问父对象,您应该在某处存储对它的引用。例如,您可以像这样更改构造函数:

function babel(){
    this.english = {
        parent: this,
        hello: function () { alert('hello'); },
        goodbye: function () { alert('goodbye'); }
        teeshirt: function () { this.parent.french.something(); }
    }
}

但是正如你所看到的,如果你不在构造函数中创建对象,就会出现问题。我没有看到任何“好”的方法,但你可以这样做:

function babel(){
    this.english = {
        parent: this,
        hello: function () { alert('hello'); },
        goodbye: function () { alert('goodbye'); }
        teeshirt: function () { this.parent.french.something(); }
    };
    for (var i in babel.prototype) {
        this[i].parent = this;
    }
}

那么你的法语会是这样的:

babel.prototype.french = {
    bonjour: function () { alert('bonjour'); },
    aurevoir: function () { alert('aurevoir'); },
    teeshirt: function () { this.parent.english.teeshirt(); }
}

【讨论】:

    【解决方案2】:

    虽然所问的问题确实提出了 JavaScript 的 this 和原型继承的所有迷人问题,但我建议简化整个问题并重构您的对象。有几种方法可以做到这一点。

    如果默认是英文版的teeshirt,应该在原型链end的对象中。也就是说,一个法语对象的原型是一个英语对象。法国对象根本不会包含 T 恤成员。这类似于资源包的工作方式。

    现在这个想法可能不适合你,因为不同包之间的关系可能很复杂:也许有时英语是一个后备有时,但有时不是。在这种情况下,看看你是否可以让你的 babel 对象都是单例(即,只是普通的对象)。

    var babel = {}
    
    babel.english = {
        hello: function () { alert('hello'); },
        goodbye: function () { alert('goodbye'); },
        teeshirt: function () { alert('T-shirt'); }
    }
    
    babel.french = {
        bonjour: function () { alert('bonjour'); },
        aurevoir: function () { alert('aurevoir'); },
        teeshirt: function () { babel.english.teeshirt(); }
    }
    
    babel.english.teeshirt();
    babel.french.teeshirt();
    

    试试http://jsfiddle.net/yRnLj/

    我意识到这看起来完全回避了您的有趣问题。但是,如果您只需要每个语言包的一份副本,则 要简单得多。 :-)

    【讨论】:

    • 这对这个例子很有意义,但我对这个概念很感兴趣。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2013-08-03
    • 2011-08-29
    • 2017-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 2012-05-12
    相关资源
    最近更新 更多