Isn't this kind of negated by the fact that `delete arr[n]` working the way it does has required JavaScript arrays to never have been "real" arrays, in the entire history of the language?
I don’t think so. There’s a little bit more nuance to it (because it involves array “holes”—almost a third kind of null), but delete on an array index is semantically closer to assigning undefined to the index. It doesn’t actually delete the presence of the index.
> It doesn’t actually delete the presence of the index.
It actually removes the index.
> Object.keys([9,,9])
[ "0", "2" ]
The value of the `length` property does nothing to imply the presence or lack of any keys. This is covered in the "exotic objects" behavior section in chapter 10 of the ECMAscript spec.
It removes the property key. It does not remove the index. You can see the distinction in the iterator produced by the array prototype’s keys method which, per ECMAScript spec chapter 23, yields the array’s indexes. And they are, in fact, determined by the array’s length.
You can delete every property corresponding to an array’s indexes, and you’ll get the same result.
It doesn’t. It deletes the property “2”, but the index 2 remains present as a “hole” (like I mentioned before, almost a third kind of null). That removes it from iteration over the array object’s properties (i.e. your for-in loop), but doesn’t remove the index from the array or its iterable value representation: https://www.typescriptlang.org/play/?#code/MYewdgziA2CmB0w4E...
If you click run there and look at the logged output, you’ll see:
1. The length remains the same after the delete statement
2. The items after index 2 keep their index
3. The for-of loop continues to iterate over index 2 (which now produces an undefined value on read)
> the index 2 remains present as a “hole” (like I mentioned before, almost a third kind of null).
It's an interesting model, and I think it definitely has its uses when reasoning about JS arrays. I'm not yet convinced it's the best model, but it's something I'm going to have to let percolate through my brain for a while to weigh it up properly. Thanks.
I think you're misinterpreting how for-of works. For-of will iterate over deleted keys in the exact same way that it iterates over keys that never existed.
let a = [];
a[7] = 7;
for (let v of a) console.log(v);
> undefined, undefined, undefined, undefined, undefined, undefined, undefined, 7