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

我应该在JavaScript中嵌套构造函数和原型吗?,javascript,prototype-chain,Javascript,Prototype Chain,我目前正在处理的一个项目需要一个对象类型链,它本身会生成一种仅由它使用的对象类型链接。 在以前的项目中,我将对象构造函数和Link的原型嵌套在Chain的构造函数中,但是,这次我开始怀疑这是否是最好的方法,因为每次我都会用自己的Link定义来设置每个链 为清楚起见,这是我的原始代码: var Chain = function() { var self = this; var Link = function(key) { this.prop = key;

我目前正在处理的一个项目需要一个对象类型
,它本身会生成一种仅由它使用的对象类型
链接
。 在以前的项目中,我将对象构造函数和
Link
的原型嵌套在
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));
}
然后,我开始考虑是否应该像在
链中一样将
链接
构造函数和原型存储在野外(记录在案,它不是野外的,它实际上包含在一个对象中)或者我是否应该使用
Chain
的原型来定义
Link
,并将其保留在那里

在这种情况下,我没有找到很多关于最佳实践的信息,尽管我强烈怀疑我的第一种做事方式不是最佳/正确的方式;我不确定我的选择是否是这样

所以我问,做这件事的最佳实践/最有效/最明智的方法是什么

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

然后,我开始想我是否应该像存储
链那样,将
链接
构造函数和原型存储在野外

还有第三个选项:单个
链接
,它是
链的私有链接

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

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

    return Chain;
})();
现在,
是公共的,
链接
是私有的,但是只有一个
链接
,而不是为每个
创建一个新的链接

这同样适用于ES2015+
语法:

const Chain = (function() {
    class Link {
        // ...
    }

    class Chain {
        // ...
    }

    return Chain;
})();
这一次我开始怀疑这是否是最好的方法,因为我每次都会用自己的
链接定义来设置每个

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

有时,特定于实例的帮助函数可能会有所帮助(用于设置属于该特定链的链接),但可以将其作为工厂方法来执行,并且仍然可以使来自所有链的所有链接共享同一(基类)类

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

是的,就范围而言,那很好。除非“野生”是全球范围,否则这没有错。如果您想进行一些封装,可以使用ES6模块仅导出该范围的“公共”部分,或者使用IIFE(如@T.J.Crowder的回答)

另一种将类保持在一起(其中一个属于另一个)的常用方法是将该类用作命名空间对象:

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

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

同样的。

现在这是一个我没有考虑过的有趣的方法,也是我喜欢的方法。奇怪的是,您还假设回答了我的第二个问题,这是定义对象构造函数及其原型的最整洁的方法。非常感谢。永远不要把它们放在窝里。把它们拴起来,是的,但永远不要把它们筑巢。