目前我正在编写一个小应用程序并来到了这一点,我认为克隆一个对象而不是使用引用会很聪明。
我这样做的原因是,因为我正在收集列表中的对象。稍后我将只使用此列表,因为它是模型的一部分。引用不是我需要的,我想避免引用列表中的外部对象,因为我不希望有人构建一个可以从代码中不考虑的地方更改模型的构造。(模型中信息的完整性非常重要。)
另外,当我不使用引用时,我认为我会从中获得更好的性能。
所以我的总体问题仍然是:我什么时候应该更喜欢克隆而不是 javascript 中的引用?
谢谢!
目前我正在编写一个小应用程序并来到了这一点,我认为克隆一个对象而不是使用引用会很聪明。
我这样做的原因是,因为我正在收集列表中的对象。稍后我将只使用此列表,因为它是模型的一部分。引用不是我需要的,我想避免引用列表中的外部对象,因为我不希望有人构建一个可以从代码中不考虑的地方更改模型的构造。(模型中信息的完整性非常重要。)
另外,当我不使用引用时,我认为我会从中获得更好的性能。
所以我的总体问题仍然是:我什么时候应该更喜欢克隆而不是 javascript 中的引用?
谢谢!
如果稳定性很重要,那么克隆它。如果测试表明这是一个瓶颈,请考虑将其更改为参考。如果它是一个瓶颈,我会感到非常惊讶,除非你有一个非常复杂的对象,它非常频繁地来回传递(如果你这样做,这可能表明设计不好)。
还要记住,您只能做很多事情来使其他开发人员免于自己的愚蠢。如果他们真的想破坏您的 API,他们可以通过复制源代码或在运行时修改它来用自己的函数替换您的函数。如果您记录不得更改对象,则优秀的开发人员(是的,有一些)将遵循该规则。
对于它的价值,我在自己的项目中使用了这两种方法。对于不经常传递的小型结构,我为稳定性制作了副本,而对于较大的数据(例如,可能每帧传递的 3D 顶点数据),我不复制。
为什么不让存储在列表中的对象不可变呢?您可以存储闭包,而不是存储简单的类似 JSON 的对象。
假设您有一个具有两个属性A
和的对象B
。它看起来像这样:
myObj = {
"A" : "someValue",
"B" : "someOtherValue"
}
但是,正如您所说,任何人都可以通过简单地覆盖它的属性 A
或B
. 您可以传递从实际对象创建的只读数据,而不是将列表中的此类对象传递给客户端。
首先定义一个函数,它接受一个普通对象并返回一组访问器:
var readOnlyObj = function(builder) {
return {
getA : function() { return builder.A; },
getB : function() { return builder.B; }
}
}
然后代替您的对象myObj
给用户readOnlyObj(myObj)
,以便他们可以通过方法getA
和访问属性getB
。
通过这种方式,您可以避免克隆成本,并提供一组清晰的用户可以对您的对象执行的有效操作。