理论问题,例如我有一个名为 Order
的大对象,它有大量的属性:字符串、数字、数组、嵌套对象。
我有一个函数:
function removeShipment(order) {
order.shipment.forEach(
// remove shipment action
);
}
这意味着我只访问一个 prop (shipment
),但发送了一个大对象。
从垃圾收集和性能的 Angular 来看,传递Order
和传递Order.shipment
有区别吗?
因为对象通过引用传递,实际上并没有将Order
复制到变量中。
最佳答案
正如 ibrahim mahrir 在评论中所说——虽然我不知道他们为什么不发布答案,因为 OP 被激励选择“最佳答案”,因此选择了唯一的、令人困惑的回应——那里在将 order
传递给您的 removeShipment
方法或传递 order.shipment
这是因为 JavaScript 函数是原始类型的“按值传递”,例如 number
和 boolean
,并且它使用一种称为“按值调用”的东西共享”用于传递对象引用的副本(例如您的 order
和假设您的 Array
of shipments
)。当作为参数传递时,不会复制整个对象,只是在内存中复制对它的引用。传递 order
或 order.shipments
的两种方法实际上是相同的。
我确实为此编写了几个计时测试,但实际差异是如此之小,以致于编写一个甚至可以正确测量它的测试都异常困难。为了完整起见,我将在最后包含我的代码,但根据我在 Firefox 和 Chrome 中的有限测试,它们实际上是相同的,正如预期的那样。
与您的问题/答案相同的另一个问题/答案(以及关于为什么“微基准测试”通常不会产生正确结果的精彩视频)证实了我所写的内容,请参阅:does size of argument in a javascript function affects its performance?
请参阅此答案,了解“共享调用”的含义 Is JavaScript a pass-by-reference or pass-by-value language?
您没有具体说明“删除发货操作”实际上“意味着”什么。如果您只是想从订单对象中“删除所有货件”,您可以只执行 testOrder.shipments = []
。如果没有别的东西可以到达他们,他们会在这之后的某个时候被垃圾收集。我只是要遍历每个并作为 stub 执行加法操作,否则我担心一切都会被优化掉。
// "num" between 0 inclusive & 26 exclusive
function letter(num)
{
return String.fromCharCode(num + 65)
}
// Ships have a 3-letter name & a random value between 0 & 1
function getShipment() {
return { "name": "Ship", "val": Math.random() }
}
// "order" has 100 "Shipments"
// As well as 676 other named object properties with random "result" values
// e.g. order.AE => Object { result: 14.9815045239037 }
function getOrder() {
var order = {}
for (var i = 0; i < 26; i++)
for (var j = 0; j < 26; j++) {
order[letter(i) + letter(j)] = { "result": (i+j) * Math.random() }
}
order.shipments = Array.from({length: 100}).map(getShipment)
return order
}
function removeShipmentOrder(order) {
order.shipments.forEach(s => s.val++);
}
function removeShipmentList(shipmentList) {
shipmentList.forEach(s => s.val++);
}
// Timing tests
var testOrder = getOrder();
console.time()
for(var i = 0; i < 1000000; i++)
removeShipmentOrder(testOrder)
console.timeEnd()
// Break in-between tests;
// Running them back-to-back, the second test always took longer.
// I assume it's actually due to some kind of compiler optimisation
var testOrder = getOrder();
console.time()
for(var i = 0; i < 1000000; i++)
removeShipmentList(testOrder.shipments)
console.timeEnd()
关于javascript - 在javascript中将对象作为参数传递的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42396902/