I asked this on MDN's discussions, but since they're still using newsgroups and mailing lists like it's 1994, I'm not exactly expecting a straight answer from that source -- so I'll ask it here too since we've got some people with a decent command of JS in here. I'm stuck wondering what the devil much of their code is even for -- so much of it seems like pointless bloat or completely failing to grasp how variables, objects and methods work in JS. ... which feels odd since I usually hold MDN up as an example of sites that get things right. Let's use Array.every as an example. It's new in ECMAScript 262-5, so they have a polyfill for older UA's. https://developer.mozilla.org/en-US...ence/Global_Objects/Array/every#Compatibility First up, there's this: if (this === void 0 || this === null) throw new TypeError(); Code (markup): Inside an Array.prototype.method -- how would it be possible to call the method of an object when the variable/instance of the object would be void or null... void or null are INHERENTLY not an object of type. The moment you are able to call the method, it should be impossible for those conditions to be true -- unless of course you called it via Array.prototype... that's the only thing I can figure they're trying to trap for, and that seems really silly. Then: var t = Object(this); Code (markup): What point is there to converting it to an object for processing? Doesn't that make it HARDER to work with? THEN: var len = t.length >>> 0; Code (markup): I've never had Array.length need a forced number conversion -- is this something to do with the pointless idiotic conversion to object? Loving the multiple var declarations for nothing BTW THEN: var thisArg = arguments.length >= 2 ? arguments[1] : void 0; Code (markup): Wouldn't it be easier to just have it exist in the function declaration then run typeof == "undefined"? THEN: for (var i = 0; i < len; i++) { if (i in t && !fun.call(thisArg, t[i], i, t)) return false; } Code (markup): First off, if they had left in as an Array, arrays auto-compress and index, so there's no reason to be checking for 'i in t' -- second, if it's an object, wouldn't "for (i in t)" have been the proper way of doing this?!? I'm trying to figure out why they have that convoluted mess, instead of something simple like: if (!Array.prototype.every) Array.prototype.every = function(func, thisArg) { if (typeof func != 'function') throw new TypeError(); thisArg = typeof thisArg == 'undefined' ? void 0 : thisArg; for (var t=0; t<this.length; t++) { if (!fun.call(thisArg, this[t], t, this)) return false; } return true; } Code (markup): Which is pretty much what I'm going to use unless someone can explain why they've got all that extra stuff in there...
If anyone is curious, I 'kind of' got an answer on MDN's mailing list. (Mailing lists... what is this 1994?) It turns out they are being pedantically literal on interpreting the implementation specification, "every" for example: http://es5.github.io/#x15.4.4.16 Allegedly it's out of some form of fear about 'corner cases' in legacy browsers, but I really have to call BULLSHIT on that. Those instructions make perfect sense if you're implementing it in C++... It just looks to me like they failed to bother translating it to javascript and pulling out all the stuff that does absolutely NOTHING in JS. JS doesn't HAVE a uInt32 type, so 'converting to uInt32' is pointless. JS arrays are more simply processed as.. well, arrays -- so converting to object does nothing... IF converted to object JS has for (i in k) for objects. Generally you shouldn't even HAVE a for++ loop on objects in javascript and in my own testing, their polyfills actually have a risk of failure since objects don't compress indexes like Arrays do, and the only reason it doesn't fail is you start out with an Array. Unless you call it via prototype (which you shouldn't) it is impossible for "this" to be void or null... They quite literally just took the C++ instructions and didn't even TRY rubbing some brain cells together to ACTUALLY write it as JavaScript. Even bigger laugh, the respondent seemed to be unaware of how JavaScript compresses indexes so it's ALWAYS 0..(length-1) even if you delete from the middle... VERY disappointing out of MDN, which usually has pretty good info in it... but yeah, turns out I'm right, there is NO legitimate reason for that to be more than my gutted rewrite other than the authors over there failing to bother translating it from C++ to JS properly... disturbing when that was written by people IMPLEMENTING a JavaScript engine... :/
Well, maybe it's not entirely what I just said -- they were implementing it based on code that could be used on any set of elements, not just Arrays -- but that's why most of it should have been tossed the moment it was applied to Array.prototype -- since you'd KNOW it's a type array, and all that code could ever accept is Array, most of that code doesn't apply. They wrote a generic handler, then translated it to someplace it's no longer generic. More I think on it the more I understand why it was done... still doesn't make it what SHOULD have been done.