This is a long comment on a programming pattern used in YUI, so don't read
it last thing on a Friday afternoon ;)
In a lot of places, YUI libraries push values on to the end of a list by
doing:
myArray[myArray.length] = something
I assume this is a speed issue rather than a compatibility problem, because
push() is also used sometimes.
Although this pattern is used in many places, it's common to see it in
string concatenation operations (because of IE's famous speed issues).
Here's a completely random example, taken from calendar.js:
html[html.length] = "<thead>";
html[html.length] = "<tr>";
html[html.length] = '<th colspan="' + colSpan + '" class="' +
this.Style.CSS_HEADER_TEXT + '">';
html[html.length] = '<div class="' + this.Style.CSS_HEADER + '">';
Because foo[foo.length] takes a while to type, it encourages the programmer
to split strings based on elegance rather than efficiency. This causes two
problems:
1) Strings combined with "+" that would be better written as two seperate
push operations. For example, the third line above combines several
strings with "+" because they're all logically part of a single tag, even
though this causes speed problems in IE.
2) Strings written as separate push operations that would be better
combined with "+". The YUI compressor will combine two literal strings
separated by "+" into one long string, so the first two lines in the above
example should be combined that way.
The net effect of this is to decrease efficiency and increase code size.
There are several possible solutions, which I'll spend the rest of this
post discussing. Perhaps unsurprisingly, I will leave my favourite until
last.
_ Add it to the style guide _
I assume that the use of foo[foo.length] is mandated in some style guide.
Wherever this rule is written down, it could be amended with a line like
"avoid the temptation to concatenate things with '+'".
While this is the simplest solution, its chances of working are slim:
programmers use the '+' because it comes naturally and makes their lives
easier. A comment like this would just remind them that the shortcut
exists.
_ Give up on foo[foo.length] and use push() _
This is a more practical solution, albeit one that loses the benefits of
foo[foo.length]. Ideally, the above example could be rewritten as:
html.push("<thead>" +
"<tr>" +
'<th colspan="', colSpan, '" class="', this.Style.CSS_HEADER_TEXT, '">'
+
'<div class="', this.Style.CSS_HEADER, '">'
);
This allows the YUI compressor to do its job, but puts a small burden on
the programmer to remember when to use '+' and when to use ','.
_ Create a new function: Array.yui_push() _
In the above example, the YUI compressor can't automatically determine
whether to combine literal strings because sometimes it's necessary for
push()ed strings not to be combined. That problem can be solved by
creating a yui_push() function:
Array.prototype.yui_push = Array.prototype.push;
The above example could then be rewritten as:
html.yui_push("<thead>",
"<tr>",
'<th colspan="', colSpan, '" class="', this.Style.CSS_HEADER_TEXT,
'">',
'<div class="', this.Style.CSS_HEADER, '">'
);
In uncompressed code, this would run perfectly well, although slightly
slower than before. The YUI compressor could transform this into either:
html.push('<thead><tr><th colspan="',colSpan,'"
class="',this.Style.CSS_HEADER_TEXT,'"><div
class="',this.Style.CSS_HEADER,'">');
Or:
html[html.length]='<thead><tr><th colspan="';
html[html.length]=colSpan;
html[html.length]='" class="';
html[html.length]=this.Style.CSS_HEADER_TEXT;
html[html.length]='"><div class="';
html[html.length]=this.Style.CSS_HEADER;
html[html.length]='">';
Depending on whether the user requested compact or fast handling of
Array.yui_push().
- Andrew
george puckett
None
None
Public
|
Date: 2009-01-23 00:46 The YUI project has been migrated from Source Forge to YUILibrary.com. |
|
Date: 2008-02-28 16:37
|
| Field | Old Value | Date | By |
|---|---|---|---|
| status_id | Open | 2009-01-23 00:46 | gpuckett |
| assigned_to | msweeney | 2009-01-23 00:46 | gpuckett |
| allow_comments | 1 | 2009-01-23 00:46 | gpuckett |
| close_date | - | 2009-01-23 00:46 | gpuckett |
| summary | "foo[foo.length] = bar" considered harmful? | 2008-11-21 21:53 | gpuckett |
| assigned_to | miraglia | 2008-02-28 16:37 | miraglia |
| assigned_to | nobody | 2008-02-01 21:08 | gpuckett |