I have considered a non backwards compatible JavaScript descendant to clean things up. It would be interesting to hear what you consider to be problems.
I have considered a non backwards compatible JavaScript descendant to clean things up. It would be interesting to hear what you consider to be problems.
>>> let xs = [,'foo']
<<< undefined
>>> xs
<<< Array [ <1 empty slot>, "foo" ]
>>> xs.map((x, index) => index)
<<< Array [ <1 empty slot>, 1 ]
>>> for (let x of xs) console.log(x);
undefined
foo
<<< undefined
>>> for (let x in xs) console.log(x);
1
<<< undefined
>>> xs.length
<<< 2
>>> delete xs[1]
<<< true
>>> xs.length
<<< 2
>>> xs
<<< Array [ <2 empty slots> ]
Empty slots are skipped in map() and for-in, but not in for-of and the new array from map() will have the same empty slots. delete will change a slot to empty, it won't change the length of the array.Still, much saner than PHP arrays.
PHP basically has arrays and maps merged into one. Basically like Lua does.
It is pretty handy. Not sure what you find insane about it.
Of course the functions for arrays in the standard library are consistently inconsistent but that is just a general PHP thing. Isn't a big deal when you use an IDE.
How about array_filter() returning an associative array, because it doesn't renumber the indexes? You need to run it through array_values() after. You run into this all the time when converting to json.
For something more obscure but equally infuriating, how about using iterator_to_array() on anything that uses `yield from`? Everything yielded that way will overwrite previously yielded values, unless you pass a magic boolean parameter that of course defaults to doing the wrong thing (PHP is chock full of those). OFC it's because of the behavior of array keys.
How about when you do want associative array semantics and use a string index that consists entirely of numeric digits? It gets cast into an int, always, and you cannot control that. This is super "fun" when you run array_keys on your associative array you only used string keys on, and naïvely think it will return only strings. Crash at runtime if your function was declared to just take a string.
There are so many more WTFs, these were just off the top of my head from issues I've encountered recently. I make my living with PHP, but you'll never see me defending arrays. Though at least they're zero-based As The Deity Intended It.
- There's both undefined and null
- There's three ways to declare variable
- typeof vs instanceof
- for in vs for of
- the way `this` works
- semantics of functions called with the wrong number of args
There's far more that I can't immediately recall.
A lot of the fixes are just removing the old broken way of doing things.
I'd still probably change 'for x of ...' to implicitly be 'const x' and require let if you are doing shenanigans with changing the values.
I am surprisingly ok with null and undefined. Null means not a thing, undefined means there is not even the notion of the thing.
I'm pretty sure there are more than three ways to declare a variable.
x=5
let x=5
var x=5
window.x=5
window["x"]=5 //arguably the same as above.
Object.defineProperty(window,"x",{value:5})
Object.assign(window,{x:5})
at leastIf only "undefined" was consistently the same as lack of variable / collection entry, it would be understandable. But as things are, {x: 1, y: undefined} is not the same as {x: 1} in many ways - indeed, so much so that TS distinguishes between these two cases in its type system.
A variable reference can lookup properties on the global object, or other objects with ‘with’
To make matters even worse, there's a difference between setting an object property to undefined as opposed to omitting it. So one could say there are two different "undefined"s.
FWIW Python has three (default, nonlocal, and global).
And many languages have two.