arr.push(Math.random());
and
arr[arr.length]=Math.random();
have the same result.
So, what's the difference between them? In other words, when is it better to use the former than the latter?
what's the difference between them
Looking at the specification and giving it some thought, there are at least six:
push(...)
is a method call, the other is an assignment.push
: arr.push(one, two, three)
. To do that with assignment, you need multiple assignments. (push
also doesn't update length
until it's done all the work, whereas naturally multiple assignments would update it for each assignment.)push
checks to see if the array's length will become > 253-1 and throws a TypeError
if so; assignment does not, it just happily creates a property with a name that isn't an array index. (It's an interesting check, given that array indexes are only allowed to be up to 232-1. But one the spec does in lots of places in relation to array length.)arr.push(...)
looks up push
on arr
, it can be intercepted (by assigning a new push
to arr
or to Array.prototype
). The assignment can only be intercepted on a per-property basis (using a setter for "0"
, "1"
, etc.) or via a Proxy
.set
trap, rather than working with the array directly, you may observe different set
calls (because the set
trap will presumably set the value on the underlying array directly, and so you won't see the set
for length
).arr.push(value)
is the new length of the array; the result of arr[arr.lenght] = value
is the value pushed.In other words, when is it better to use the former than the latter?
It's entirely up to you. Since push
is a method call that ultimately ends up doing the same thing the assignment does (with a bit more overhead, such as the length
check), then in theory on some engines or at least in some situations it may be the tiniest bit slower than direct assignment; but then, your direct assignment has the overhead of looking up arr.length
. In practice, on modern engines, I see no significant difference; test here, and any difference would be extremely unlikely to matter in the real world anyway. Other than that and #2-#6 above, it's a style choice.
Example of #5 (only works on JavaScript engines with ES2015 Proxy
support):
const a = [];
const p = new Proxy(a, {
set(target, prop, value) {
console.log("Proxy set called for " + prop + " = " + value);
target[prop] = value;
return true;
}
});
p[0] = "a"; // We don't see length set here
console.log(p[0]);
p.push("b"); // We do here, because `push` sets `length` through
// the proxy reference
console.log(p[1]);
In addition to T.J. Crowders detailed answer in real life my use of one or the other depends on one and only one factor. That's what return value i expect when i push an item to an array.
arr.push(item)
returns you the new length of the array.arr[arr.length] = item
returns you pushed item.arr.concat(item)
returns you a new array with the pushed item.(arr.push(item),arr)
returns you the array with the newly pushed
item.In functional programming they both have their use cases. However especially the later two can introduce a huge difference and unexpected bugs to you code if you are not careful since in JS arrays are reference types.
Oh by the way since you have asked, unlike as mentioned in older books, the first two has zero effect on performance, even micro performance wise no difference can be seen anymore. They are both very fast.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With