Comments for How IE Mangles The Design Of JavaScript Libraries
But JavaScript Libraries developpers are not the only victims of IE. I can't recall how many time I coded something (anything) in JavaScript and made it work in Firefox in a breeze with a beautiful minimalist and high level code .. until I make it work in IE and have to thow in a bunch of ugly hacks and conditions. That is so depressing.
I wonder if one day web developpers of the world will unite for a class action against Microsoft for all these years of imposed stress, I'm sure some of us are bald now because of IE g.
Yeah, I'll blog more about lettable once I've got all the wrinkles ironed out. It's really painful to use because the lettable objects can't participate in the prototype chain due to the way JScript/VBscript object peering appears to work and the fact that VBScript class instances don't appear to be as mutable as JS objects.
Regardless, it may be enough...we'll see. I still haven't spent any time looking at the performance, which I expect to be terrible on IE.
Regards
Only then will HTML componentization become a reality.
I sort of agree...it's just that XBL is also terrible. XBL 2.0 seems to natively support inlining definitions which is an improvement. Regardless, it still forces you into the XML straight-jacket for what is a purely HTML-centric endeavor.
Frankly, most of us would just settle for the selectors API being implemented anywhere...boiling the ocean (ala XBL) might be the right end point, but the transition period needs some love. Any movement on that front from anyone would be hugely helpful.
Regards
Great post.
Can you explain a little on the "getter/setter" issue? I am not sure of the significance, here is why:
-
For JS toolkit developers, writing and offering an API such as "setProperty1(value") vs. your suggested approach takes similar efforts;
-
For page authoers, using API such as "obj.setProperty1(value)" vs doing "obj.property1=value" takes similar efforts as well.
Why do you think the implicit setter/getter via accessing object properties directly is much better than an explict set/get API?
Thanks.
WRT to getters and setters, there are a couple of design-ish issues at work.
First, the DOM uses implicit getter/setter support to affect the layout and rendering of many parts of the page. If a widget is going to effectively "subclass" an element, it needs to be able to provide a similarly compact and familiar surface area. XBL and HTC provide this capability as a built-in part of their feature set...it simply boggles the mind that despite knowing it would be a critical requirement in a browser environment having done multiple revs of getter/setter bindings for the DOM, MS didn't provide a language-level construct to get it done. APIs feel more "webish" when you can just set a property and have things happen.
Secondly, many getters and setters can (and should be) auto-generated. One of the major failings with languages like Java is that their getter/setter behaviors require explicit, up-front cooperation. Python and Ruby have nice "outs" (metaclasses and method_missing, respectively) and Java could have bought it's way out of this with getter/setter decorators, but Java's annotations are too stupid to express this kind of compact "set it and forget it" default behavior creation without YAPPT (yet another pre-processing tool). This matters a lot in cases like data binding where we may not actually want to fetch the value until it's actually requested and where writing may need to be "async" and/or batched, which we can't just dish off to a thread in JS-land. Providing stubbed-out property slots allows you to defer the work until it's actually required, and pre-processing tools generally just don't work with JavaScript...sure you can go some distance, but creating a build system dependency is a fast-path to oblivion for modern, idiomatic JS toolkit code. If your tool/code requires some build system and someone else's doesn't, I'll be betting on that someone else (hence all of Dojo's build steps are entirely optional).
Lastly, size matters. You're right that for any instantaneous example, both approaches are roughly the same size and effort, but with auto-generation of getter/setter behaviors across common concerns, plus not needing the extra 5 chars for every operation, you can do a lot to reduce the size of JS code with getters/setters. That matters a ton when you're measuring increases and reductions to toolkit size in bytes (like we are with Dojo).
Maybe this is all environmental...if the DOM had a getStyle("display") method instead of style.display, maybe this wouldn't even be an issue...but we're well down the path now, and going against the grain of the web is a bad call now. It'd be great if the JScript team got with the program on this one.
Regards
Obviously, one could try to wrap the intrinsic functions and detect how they manipulate the length property, but then you’ve ruined their [DontEnum] status and now they end up in the iterable surface area of instances. Ugg.
You're wrong. Changing the value of a property does not change the property's attributes (DontEnum doesn't change). Why don't you try it:
var oldPop = Array.prototype.pop;
Array.prototype.pop = function() { alert("length before: " +this.length); oldPop.call(this); alert("length after: " + this.length); }; alert(Array.prototype.propertyIsEnumerable("pop"));
[1,2,3].pop();
Whether the DontEnum status is changed should not matter much for Arrays. Normal array iteration is done using a for loop for indexed props.
@alex
This means that while you can use for(var x in list){ ... style iteration,
Using for in
on an Array is a bad practice. It is bad because an Array is may have enumerable properties other than its indexed properties. For example, Array.prototype.forEach
is sometimes added conditionally:
if(!Array.prototype.forEach) Array.prototype.forEach = function()
If forEach
didn't exist, it was added as a new property and is enumerable, by default.
var nl = new dojo.NodeList(document.getElementsByTagName("*")) nl.length; // It is always 1. nl.forEach // function...
The length
is always 1, so using a for loop won't work. The dojo.NodeList keeps its items at position 0
items = nl[0];
var nl = new dojo.NodeList(document.getElementsByTagName("*")) nl[0]; nl.forEach; nl.forEach(function(o){alert(o.tagName);});
Produces one alert of "undefined".
myFunction will receive the node in the this parameter, plus some other constant parameters as strings.
I took a look at that lettable hack - unbelievably clever! I never would have thought of using VBScript.
bobby