我应该在JavaScript中嵌套构造函数和原型吗?

时间:2017-06-11 21:32:05

标签: javascript prototype-chain

我正在处理的项目目前已经调用了一个对象类型Chain,它本身会生成一种只有它使用的对象类型Link。 在之前的项目中,我在Link的构造函数中嵌套了Chain的对象构造函数和原型,但是,我开始怀疑这次是否是最好的方法,因为我实际上是似乎每次都为Chain设置自己的Link定义。

为清楚起见,这是我原来的代码:

var Chain = function() {
    var self = this;

    var Link = function(key) {
        this.prop = key;
    };
    Link.prototype.attach = function(args) {
        for (let value of args) {
            this[value.prop] = value.value;
        }
    };

    self.links = [];

}
Chain.prototype.add = function(key) {
    this.links.push(new Link(key));
}

然后我开始想知道我是否应该将Link构造函数和原型存储在野外,就像我在Chain那样(为了记录,它实际上并不是在野外,它实际上是包含在一个对象中)或者我是否应该使用Chain的原型来定义Link并将其保留在那里。

在这种情况下,我没有找到关于最佳实践的大量信息,虽然我强烈怀疑我的第一种做事方式不是最佳/正确的方式;我不确定我的替代品是否也是。

所以我想问一下,这样做的最佳做法/最有效/最明智的方法是什么?

2 个答案:

答案 0 :(得分:5)

  

在以前的项目中,我已经在Link的构造函数中嵌套了Chain的对象构造函数和原型,但是,如果这是最好的方法,我开始怀疑这次......

     

然后我开始想知道我是否应该将Link构造函数和原型存储在野外,就像我Chain

一样

还有第三个选项:单LinkChain私有:

var Chain = (function() {
    function Link() {
        // ...
    }
    // Link.prototype stuff here

    function Chain() {
        // ...
    }
    // Chain.prototype stuff here

    return Chain;
})();

现在,Chain是公开的,Link是私有的,但只有一个Link,而不是为每个Chain创建一个新的class

这与ES2015 + const Chain = (function() { class Link { // ... } class Chain { // ... } return Chain; })(); 语法同样有效:

block=tbs:p

答案 1 :(得分:1)

  

这次我开始怀疑这是否是最好的方法,因为我实际上似乎要设置每个Chain的'每次都有Link的定义。

是的,这正是不这样做的原因。当您创建一千个链时,您不想创建数千个Link类。始终将类放在彼此旁边,而不是在另一个的构造函数中。

有时,特定于实例的辅助函数可能会有所帮助(设置属于该特定链的链接),但是可以将其作为工厂方法,并且仍然保持所有链的所有链接共享相同(基础)类。

  

我是否应该将Link构造函数和原型存储在野外,就像我使用Chain一样?

是的,就范围而言,这很好。除非"野外"是全球范围,这没有什么不妥。如果您想要进行封装,可以使用ES6模块仅导出" public"该范围的一部分,或使用IIFE(如@ T.J.Crowder的回答)。

将类保持在一起的另一种常用方法是将类作为名称空间对象使用:

var Chain = function() {
    this.links = [];
};
… // Chain.prototype

Chain.Link = function(key) {
    this.prop = key;
};
… // Chain.Link.prototype

相同的works with ES6 classes