我应该在 JavaScript 中嵌套构造函数和原型吗?
Should I nest constructors and prototypes in JavaScript?
我目前正在处理的一个项目需要一种对象类型 Chain
,它本身会生成一种仅由它使用的对象类型 Link
。
在以前的项目中,我将 Link
的对象构造函数和原型嵌套在 Chain
的构造函数中,但是,这次我开始怀疑这是否是最好的方法,因为我实际上会这样做似乎每次都用自己对 Link
的定义来设置每个 Chain
。
为清楚起见,这是我的原始代码:
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
构造函数和原型存储在野外(为了记录,它不是在野外,它实际上包含在一个对象中)或者我是否应该使用 Chain
的原型来定义 Link
并将其保留在那里。
我没能找到很多关于这种情况下最佳实践的信息,虽然我强烈怀疑我的第一种做事方式不是 best/right 方式;我不确定我的替代方案是否也是。
所以我问,什么是最好的 practice/most efficient/sensible 方法?
In previous projects, I had nested the object constructor and prototype of Link
inside the constructor for Chain
, however, I began to wonder this time if this was the best way...
I have then begun wondering if I should just store the Link
constructor and prototype out in the wild like I have with Chain
还有第三种选择:Link
是 Chain
私有的:
var Chain = (function() {
function Link() {
// ...
}
// Link.prototype stuff here
function Chain() {
// ...
}
// Chain.prototype stuff here
return Chain;
})();
现在,Chain
是 public,Link
是私有的,但是只有一个 Link
而不是为每个 Chain
创建一个新的。
这同样适用于 ES2015+ class
语法:
const Chain = (function() {
class Link {
// ...
}
class Chain {
// ...
}
return Chain;
})();
I began to wonder this time if this the best way to do this as I would actually be appearing to set up each Chain
with its' own definition of Link
every time.
是的,这正是不这样做的原因。当你创建一千个链时,你不想创建数千个 Link
classes。始终将 class 彼此相邻放置,永远不要将一个放在另一个的构造函数中。
有时,特定于实例的辅助函数可能会有所帮助(设置属于该特定链的 link),但可以将其作为工厂方法来实现,并且仍然保留所有 link 来自所有链的共享相同的(基数)class.
Should I just store the Link constructor and prototype out in the wild like I have with Chain
?
是的,就范围而言,这很好。除非 "the wild" 是全局范围,否则这没有错。如果您想进行一些封装,可以使用 ES6 模块仅导出该范围的 "public" 部分,或者使用 IIFE(如@T.J.Crowder 的回答)。
另一种将 class 保持在一起的常用方法是将 class 用作命名空间对象:
var Chain = function() {
this.links = [];
};
… // Chain.prototype
Chain.Link = function(key) {
this.prop = key;
};
… // Chain.Link.prototype
相同.
我目前正在处理的一个项目需要一种对象类型 Chain
,它本身会生成一种仅由它使用的对象类型 Link
。
在以前的项目中,我将 Link
的对象构造函数和原型嵌套在 Chain
的构造函数中,但是,这次我开始怀疑这是否是最好的方法,因为我实际上会这样做似乎每次都用自己对 Link
的定义来设置每个 Chain
。
为清楚起见,这是我的原始代码:
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
构造函数和原型存储在野外(为了记录,它不是在野外,它实际上包含在一个对象中)或者我是否应该使用 Chain
的原型来定义 Link
并将其保留在那里。
我没能找到很多关于这种情况下最佳实践的信息,虽然我强烈怀疑我的第一种做事方式不是 best/right 方式;我不确定我的替代方案是否也是。
所以我问,什么是最好的 practice/most efficient/sensible 方法?
In previous projects, I had nested the object constructor and prototype of
Link
inside the constructor forChain
, however, I began to wonder this time if this was the best way...I have then begun wondering if I should just store the
Link
constructor and prototype out in the wild like I have withChain
还有第三种选择:Link
是 Chain
私有的:
var Chain = (function() {
function Link() {
// ...
}
// Link.prototype stuff here
function Chain() {
// ...
}
// Chain.prototype stuff here
return Chain;
})();
现在,Chain
是 public,Link
是私有的,但是只有一个 Link
而不是为每个 Chain
创建一个新的。
这同样适用于 ES2015+ class
语法:
const Chain = (function() {
class Link {
// ...
}
class Chain {
// ...
}
return Chain;
})();
I began to wonder this time if this the best way to do this as I would actually be appearing to set up each
Chain
with its' own definition ofLink
every time.
是的,这正是不这样做的原因。当你创建一千个链时,你不想创建数千个 Link
classes。始终将 class 彼此相邻放置,永远不要将一个放在另一个的构造函数中。
有时,特定于实例的辅助函数可能会有所帮助(设置属于该特定链的 link),但可以将其作为工厂方法来实现,并且仍然保留所有 link 来自所有链的共享相同的(基数)class.
Should I just store the Link constructor and prototype out in the wild like I have with
Chain
?
是的,就范围而言,这很好。除非 "the wild" 是全局范围,否则这没有错。如果您想进行一些封装,可以使用 ES6 模块仅导出该范围的 "public" 部分,或者使用 IIFE(如@T.J.Crowder 的回答)。
另一种将 class 保持在一起的常用方法是将 class 用作命名空间对象:
var Chain = function() {
this.links = [];
};
… // Chain.prototype
Chain.Link = function(key) {
this.prop = key;
};
… // Chain.Link.prototype
相同