There are presentations and even a website dedicated to JavaScript oddities. I'm sure this one I ran into has been discussed before, but it certainly surprised me.
I wrote a little function that I thought was pretty trivial. Given a set of objects, iterate over them, check some value, and if good, append matches to an array. Here is an example of what I wrote.
When I ran my code, I kept getting a 0-length array back. I added a simple variable inside my condition and confirmed that it was matching and appending those matches, so... wtf?
Some of you probably see it right away. It took me a good twenty minutes of frustration before I saw it. See the push call? I used brackets instead of parenthesis. I have no idea why this didn't throw an error and I'd love to know why. Ok, JavaScript gurus, can you explain this one?
Archived Comments
I have no idea why this didn't throw an error and I'd love to know why. Ok, JavaScript gurus, can you explain this one?
Functions are objects, [] is notation to access properties of an object which is sugar'd by . notation (foo['bar'] === foo.bar) (in addition to array access), push[something] simply tries to access a key that doesn't exist, this will not throw an error, it will simply return undefined
Functions have methods on them; is - array.push.apply(...).
You can dynamically access them like: array.push["apply"](...).
So by using brackets and pushing an invalid function name in there you were simply trying to access something that didn't exist. Log it and you'd get an undefined.
Makes sense - thanks both of you.
Oh, Shawn said the same thing. I didn't see his. Lol
Sad thing is - I *knew* this too - just... forgot I suppose. :)
I figured it'd make sense once you saw it since it is the same for dynamic access in CF.
obs.push is an object and you access one of its properties via the square brackets. The WTF part of the thing is that *everything* in square brackets is converted to string, even array indices. That is, the spec (as opposed to JavaScript engines) interprets array indices as strings and has rules for their shapes [1].
You can use String() as a function to check how the conversion to string is performed.
[1] http://www.2ality.com/2012/...
obs is an Array and it's also an Object.
What this means is that beside taking index values, it accepts properties like any other Object, including other Objects: push, which, in return, have properties of their own: [something].
http://jsfiddle.net/cfjedim...
<iframe width="100%" height="300" src="http://jsfiddle.net/cfjedim..." allowfullscreen="allowfullscreen" frameborder="0"></iframe>
WTF jsFiddle link :)
http://jsfiddle.net/Su9eh/2/
Dumitru - all HTML is escaped for security reasons here.
OK :)
Anyway, Shawn Biddle is spot on. I just wanted to remind us about the "almost everything is an object in JavaScript".