<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.0.3" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Ash Searle's Blog</title>
	<link>http://hexmen.com/blog</link>
	<description>On programming, and other things...</description>
	<pubDate>Thu, 03 Jul 2008 10:51:13 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.0.3</generator>
	<language>en</language>
			<item>
		<title>Function.prototype.apply revisited</title>
		<link>http://hexmen.com/blog/2006/12/revisiting-functionprototypeapply-for-ie5/</link>
		<comments>http://hexmen.com/blog/2006/12/revisiting-functionprototypeapply-for-ie5/#comments</comments>
		<pubDate>Tue, 26 Dec 2006 17:50:46 +0000</pubDate>
		<dc:creator>Ash</dc:creator>
		
	<category>JavaScript</category>
		<guid isPermaLink="false">http://hexmen.com/blog/2006/05/revisiting-functionprototypeapply-for-ie5/</guid>
		<description><![CDATA[You can learn a lot about JavaScript by implementing your own version of <code>apply</code>.  In this post I present my own implementation with plenty of notes to highlight and explain the hidden complexity.]]></description>
			<content:encoded><![CDATA[<p>You can learn a lot about JavaScript by implementing your own version of <code>apply</code>.  In this post I present my own implementation with explanatory notes to highlight hidden complexity: </p>
<pre><code class="javascript">Function.prototype.apply = function(thisArg, argArray) {
    if (<a href="#identify-functions">typeof this != &#8220;function&#8221;</a>) {
        throw new Error(&#8221;apply called on incompatible &#8221; +
                    &#8220;object (not a function)&#8221;);
    }
    if (<a href="#identify-arrays-and-arguments">argArray != null &#038;&#038; !(argArray instanceof Array)
        &#038;&#038; typeof argArray.callee != &#8220;function&#8221;</a>) {
	throw new Error(&#8221;The 2nd argument to apply must &#8221; +
                    &#8220;be an array or arguments object&#8221;);
    }

    thisArg = (thisArg == null) ? <a href="#global-scope">window</a> : <a href="#ToObject">Object(thisArg)</a>;
    <a href="#attaching-methods">thisArg.__applyTemp__ = this</a>;

    <a href="#youngpup">// youngpup&#8217;s hack</a>
    var parameters = [],
        length = <a href="#ToUInt32">(argArray || &#8220;&#8221;).length &gt;&gt;&gt; 0</a>;
    for (var i = 0; i &lt; length; i++) {
	parameters[i] = &#8220;argArray[&#8221; + i + &#8220;]&#8221;;
    };
    var functionCall =
            &#8220;thisArg.__applyTemp__(&#8221; + parameters + &#8220;)&#8221;;

    <a href="#error-handling">try</a> {
	return eval(functionCall)
    } <a href="#error-handling">finally</a> {
	<a href="#cleaning-up">try {
            delete thisArg.__applyTemp__
        } catch (e) {
            /* ignore */
        }</a>
    }
}

<a href="#call">Function.prototype.call</a> = function(thisArg) {
    return this.apply(thisArg,
            Array.prototype.slice.apply(arguments, [1]));
}
</code></pre>
<p class="download">Download: <a href="/code/apply-call.js">apply-call.js</a></p>
<h3>Validating <code>apply</code>&#8217;s context and parameters</h3>
<p id="identify-functions">The ECMAScript specification says that <code>apply</code> may only be called on objects with a [[Call]] property (i.e. functions), and a <code>TypeError</code> should be thrown if an attempt is made to call it on non-function objects.  The <code>typeof</code> operator allows us to identify functions easily: <code>typeof object</code> evaluates to <code>"function"</code> if and only if the object has a [[Call]] property.</p>
<p id="identify-arrays-and-arguments">The second parameter to <code>apply</code> is optional, but <em>if it&#8217;s supplied</em> it must be either an array or an arguments object - if not, a TypeError should be thrown.  The expression <code>argArray != null</code> is deceptively simple, but exploits an interesting JavaScript fact:  <code><var>object</var> == null</code> evaluates to <code>true</code> if-and-only-if <var>object</var> is <code>null</code> <em>or <code>undefined</code></em> (so <code>object != null</code> evaluates to <code>true</code> for any value <strong>except</strong> <code>null</code> or <code>undefined</code>.)</p>
<p>Checking whether an object is an instance of an array is simply a matter of using the <code>instanceof</code> operator with the Array constructor <code>Array</code> (i.e. <code>object instanceof Array</code>.)  To check whether something is an <code>arguments</code> object is a little more complicated as the ECMAScript specification does not define an <code>Arguments</code> class or function.  We resort to a capability test: we check whether the object has a <code>callee</code> property that&#8217;s a function (<code>typeof object.callee == "function"</code>.)  I think this is a better test than checking for a numeric <code>length</code> property, as both <code>String</code> and <code>NodeList</code> have <code>length</code> properties defined, but neither of them are should be accepted when passed as the second argument to <code>apply</code>.</p>
<h3 id="global-scope">Getting an appropriate object to use as <code>this</code></h3>
<p>If <code>thisArg</code> is <code>null</code> or <code>undefined</code>, the global-scope must be used as <code>this</code>.  Since I&#8217;m writing this version of <code>apply</code> for use in a browser: the global-scope is the <code>window</code> object.</p>
<p id="ToObject">JavaScript&#8217;s <code>typeof</code> operator allows you to differentiate several types of primitive value (booleans, numbers and strings)  To turn primitive values into objects (as required by the specification of <code>apply</code>) we pass them through the <code>Object</code> function.  From this point on, you should use <code>instanceof</code> instead of <code>typeof</code> to differentiate different types of object.</p>
<h3>Using functions as methods</h3>
<p id="attaching-methods">The purpose of <code>apply</code> is to be able to assign a specific object as <code>this</code> for the duration of a function call.  Without native browser-support, the only way to achieve this is to assign the function as a property of the object (thereby making the function a &#8216;method&#8217; of the object.)  Ideally we would generate and check for a non-existent property-name - but this cannot be achieved with 100% reliability on our main target browser (Internet Explorer 5) as there is no way of checking for the existence of a property (the specification defines <code>Object.prototype.hasOwnProperty</code> for this purpose; IE5 doesn&#8217;t support it, and it cannot be implemented reliably.)  Accepting the futility of the situation, we go with a &#8216;good enough&#8217; implementation and hope that <code>__applyTemp__</code> isn&#8217;t being used for any other purpose.</p>
<h3 id="ToUInt32">Establishing how many parameters to pass</h3>
<p>We&#8217;ve established that <code>argArray</code> is either <code>null</code>, <code>undefined</code>, an array or an arguments object, we  now need to establish how many parameters need passing to the function call.  The rather obtuse expression <code>(argArray || "").length &gt;&gt;&gt; 0)</code> is dense code to meet the specification: no arguments (<code>0</code>) are passed if <code>argArray</code> is <code>null</code> or <code>undefined</code>, otherwise the <code>length</code> property is cast to an unsigned 32-bit integer, and the result is the number of parameters that will be passed (it&#8217;s extremely unlikely that the result will be any different to using the <code>length</code> property as-is; but since it&#8217;s trivial to do things properly, we do so.)  A more simplistic and readable version of the code would read: <code>(argArray == null) ? 0 : argArray.length</code></p>
<h3 id="youngpup">Calling a function with an arbitrary number of parameters</h3>
<p>If you google for implementations of <code>apply</code> you&#8217;ll inevitably come across code derived from <a href="http://boring.youngpup.net/2002/oldblog123">youngpup&#8217;s version</a>.  I don&#8217;t know if <abbr title="youngpup, also known as Aaron Boodman">he</abbr> created the hack, but it&#8217;s the inspiration for my version, so credit where credit&#8217;s due.  The purpose of the hack is to pass a variable number of parameters to a function, without having to consider 1, 2, 3, 4 arguments (etc.) separately.  The hack works by building a function-call as a string, then passing the string to <code>eval</code>.  For example, to pass two parameters, this would be passed to <code>eval</code>: <code>"thisArg.__applyTemp__(argArray[0], argArray[1])"</code></p>
<h3 id="error-handling">Error handling and cleaning-up</h3>
<p>Earlier on, we attached the function as a method of the object.  To ensure this is a <em>temporary</em> attachment, we have to remove the method once the function call has completed (using <code>delete</code>).  We have to be careful though, as the function call may cause an error to be thrown, and we don&#8217;t want to swallow or ignore this error.  Fortunately, we can use the <code>try</code>/<code>finally</code> construct to run some clean-up code after the function call, regardless of whether the function-call ends in an exception or not.</p>
<p id="cleaning-up">Ideally, cleaning-up would simply be a matter of writing <code>delete object.property</code>; but in the world of Internet Explorer nothing is that simple.  Errors can be thrown when you try to <code>delete</code> properties on host objects (a host object is an object supplied by the browser and accessible through JavaScript, but not defined in the ECMAScript specification.  e.g. <code>ActiveXObject</code>.)   As we don&#8217;t imagine anyone will be interested in errors generated during clean-up, we wrap a simple <code>try</code>/<code>catch</code> around the clean-up code to swallow any errors generated here.</p>
<h3 id="call">Function.prototype.call</h3>
<p>It&#8217;s trivial to implement <code>call</code> in terms of <code>apply</code>.  The first parameter to <code>call</code> becomes the first parameter to <code>apply</code>.  The rest of the parameters are passed by applying <code>Array</code>&#8217;s <code>slice</code> method to the <code>arguments</code> object.  This demonstrates our first useful application of <code>apply</code>: converting <code>arguments</code> objects to standard arrays.</p>
<h3>Conclusion</h3>
<p>To implement <code>apply</code> we&#8217;ve had to understand <code>typeof</code>, functions, methods, <code>this</code>, <code>null</code>, the loose equality operator, global-scope, object properties, <code>try</code>/<code>catch</code>/<code>finally</code>, the <code>arguments</code> object, <code>eval</code>, primitive values and errors.  This is a lot of ground to cover for such a short function, and I can&#8217;t think of any other function that teaches you so much while writing it.</p>
]]></content:encoded>
			<wfw:commentRSS>http://hexmen.com/blog/2006/12/revisiting-functionprototypeapply-for-ie5/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>Numbers in form-fields</title>
		<link>http://hexmen.com/blog/2007/01/numbers-in-form-fields/</link>
		<comments>http://hexmen.com/blog/2007/01/numbers-in-form-fields/#comments</comments>
		<pubDate>Mon, 08 Jan 2007 12:39:58 +0000</pubDate>
		<dc:creator>Ash</dc:creator>
		
	<category>JavaScript</category>
		<guid isPermaLink="false">http://hexmen.com/blog/2007/01/numbers-in-form-fields/</guid>
		<description><![CDATA[JavaScript is often used for client-side form validation to save unnecessary round-trips to the server.  Unfortunately, lots of client-side validation relies on lenient JavaScript methods such as parseInt, allowing numbers to be input in ways totally unacceptable to your server-side code.  Let&#8217;s have a look at the problems and some solutions.
Server-side validation
It&#8217;s a [...]]]></description>
			<content:encoded><![CDATA[<p>JavaScript is often used for client-side form validation to save unnecessary round-trips to the server.  Unfortunately, lots of client-side validation relies on lenient JavaScript methods such as <code>parseInt</code>, allowing numbers to be input in ways totally unacceptable to your server-side code.  Let&#8217;s have a look at the problems and some solutions.</p>
<h3>Server-side validation</h3>
<p>It&#8217;s a golden-rule of web-development that you <em>never depend on client-side validation</em>.  Users can turn JavaScript off, and hackers can send any data they like at your servers.  So, the first thing you have to decide is what data is acceptable to your <strong>server</strong>.  For numbers on the server, are you planning on storing them in a database or performing calculations with them?  In either case, what format do the numbers need to be in: integers? decimals?  Are you going to manually trim white-space from the number, are you going to allow negative numbers?<a id="more-11"></a></p>
<p><em>(it&#8217;s tempting to make the server-side validation anally-retentive, not accepting anything except a strict sequence of decimal numbers.  I&#8217;d suggest that you at least accept (and remove) white-space around submitted numeric values.  This will avoid frustrating JavaScript-disabled users in the case where a form-field has some trailing white-space in it - impossible to see, and annoying to find and remove after receiving an &#8220;invalid input&#8221; error.)</em></p>
<h3>Client-side validation</h3>
<p>Once you&#8217;ve decided on and coded-up your server-side validation, it&#8217;s time to think about client-side validation.  Remember, the point of client-side validation is to avoid unnecessary round-trips to the server.  If you can determine that user-input on the client isn&#8217;t going to be acceptable to the server, don&#8217;t even bother sending it; instead, display informative and instructive messages to the user indicating which input you don&#8217;t like, why, and what type of input you want from them.</p>
<p>We need an example to work with.  I&#8217;m feeling unimaginative, so I&#8217;m going to use the stock order-form example.  Let&#8217;s suppose we have a <var>quantity</var> field that (for arbitrary business reasons) we will only accept with an integer from 0 - 100.  One naïve approach to validation may be:</p>
<pre><code class="javascript">var quantity = document.orderForm.quantity.value;
if (quantity &lt; 0 || quantity &gt; 100) {
  // inform user of invalid input
}</code></pre>
<p>Remember, form-field values are always strings, so the code above is relying on automatic type-conversion from strings to numbers using the <code>&lt;</code> and <code>&gt;</code> operators.  Unfortunately, if the user doesn&#8217;t input anything (<code>quantity === ""</code>), this would be treated exactly the same as if they&#8217;d entered <code>0</code>; and the <var>quantity</var> would pass our input validation.</p>
<p>I just mentioned that the validation would pass for an empty-string; in fact, validation would pass for any input consisting solely of white-space.  That&#8217;s due to the JavaScript behaviour:  <code>"\s*" &lt; 0</code> is <code>false</code> and <code>"\s*" == 0</code> is <code>true</code> (where I&#8217;ve used <code>\s*</code> to mean &#8216;optional white-space&#8217;.)</p>
<h3>Considering parseInt</h3>
<p>So, we don&#8217;t want white-space to be treated as <code>0</code>.  Fortunately (for now), <code>parseInt</code> (and <code>parseFloat</code>) will return <code><abbr title="Not a Number">NaN</abbr></code> for white-space input.  We could try to improve our code like this:</p>
<pre><code class="javascript">var quantity = parseInt(document.orderForm.quantity.value);
if (isNaN(quantity) || quantity &lt; 0 || quantity &gt; 100) {
  // inform user of invalid input
} else {
  // assume everything's hunky-dory?
}</code></pre>
<p>But, oh dear lord, what a can-of-worms we&#8217;ve just opened: <code>parseInt</code> accepts numbers in octal and hexadecimal as well as base-10, and it&#8217;s unlikely that we want to send octal or hexadecimal numbers to our server.  The sensible thing to do would seem to be to specify that we want to parse base-10 numbers using <code>parseInt(quantity, 10)</code>.</p>
<p>This just makes things worse.  Where we would have had <code>parseInt("0xFF")</code> returning <code>255</code> (and failing validation), we now have <code>parseInt("0xFF", 10)</code> returning 0 which passes our validation.  In other words, our client-side code has passed and we&#8217;re going to send the server &#8220;0xFF&#8221; as the quantity.  Hopefully your server-side code would validate this and return an error, but it feels like a waste of a round-trip.</p>
<p>There are also problems with floating-point numbers and scientific notation.  i.e. parseInt(&#8221;2.34&#8243;, 10) returns <code>2</code> as does parseInt(&#8221;2e04&#8243;, 10), but either of these inputs could cause problems on the server (&#8221;2e04&#8243; is scientific notation for <code>20000</code>, but <code>parseInt(x, 10)</code> stops parsing as soon as it reads a non-digit character.)</p>
<p>And then there&#8217;s the just-plain-strange input: <code>parseInt("3 bikinis", 10)</code> returns <code>3</code>.  What are you going to do with <code>"3 bikinis"</code> on the server?  It&#8217;s crazy-talk.</p>
<p>Clearly, <code>parseInt</code> is not enough on it&#8217;s own.</p>
<h3>Regular Expressions</h3>
<p>We&#8217;re talking about a <code>quantity</code> field, where we want a non-negative integer.  A simple-regular expression to check for a sequence of decimal digits is: <code>/\d+/</code>.  That still doesn&#8217;t help us avoid any trailing characters, so we need to pin it down using the <code>^</code> and <code>$</code> markers.  Remembering that the user can&#8217;t see white-space, we&#8217;ll show some tolerance by allowing leading and trailing white-space round the character (usually, you&#8217;d <em>trim</em> the field before validating, but I&#8217;m just adding some optional white-space to the regular-expression for now.)</p>
<pre><code class="javascript">var quantity = document.orderForm.quantity.value;
if (!/^\s*\d+\s*$/.test(quantity) || quantity &lt; 0 || quantity &gt; 100) {
  // inform user of invalid input
} else {
  // do something with quantity?
}</code></pre>
<p>We&#8217;re pretty happy that <var>quantity</var> has been entered in the right format, and we&#8217;ve used some implicit JavaScript type-conversion to check it&#8217;s in the right range (0 - 100.)  But surely if we want to do some calculations on it, then we&#8217;re going to have to use <code>parseInt</code> or some other method of converting strings to numbers?</p>
<h3>Unary <code>+</code> for type-conversion</h3>
<p>Forget <code>parseInt</code>.  If you know that a variable only contains digits (optionally wrapped in white-space) you can convert it to a number using a single <code>+</code>.  Let&#8217;s assume we have a couple of hidden fields: <var>unitPrice</var> and <var>shipping</var>.  We can assume these hidden fields contain numbers, and we know that the multiplication operator &#8216;<code>*</code>&#8216; will do automatic string-to-number conversion for us.  But the binary &#8216;<code>+</code>&#8216; operator doesn&#8217;t (i.e. <code>4 + "5"</code> equals <code>"45"</code> not <code>9</code>.)  Here&#8217;s unary <code>+</code> in action:</p>
<pre><code class="javascript">var form = document.orderForm;
var quantity = form.quantity.value;
<em>&#8230;validation omitted&#8230;</em>
var subtotal = form.unitPrice.value * quantity;
var total = subtotal + <strong>+</strong>form.shipping.value;</code></pre>
<p>I need to be explicit about octal numbers.  Although <code>parseInt</code> will (by default) parse octal, hexadecimal and base-10; when it comes to operators, octal is ignored.  In other words, <code>"0xff" == 255</code> is <code>true</code>, but <code>"010" == 8</code> is <code>false</code>.  Similarly <code>+"0xff"</code> is <code>255</code> but <code>+"010"</code> is <code>10</code>.</p>
<p>Unary <code>+</code> has a lot going for it, and if you&#8217;re using <a href="http://prototype.conio.net/" title="Prototype JavaScript Framework">prototype</a> this should appeal:
<pre><code class="javascript">var total = ($F('unitPrice') * $F('quantity')) + +$F('shipping');</code></pre>
<p><em>(though I&#8217;ll never understand why they chose to use <code>$F</code> instead of <code>$V</code>.  &#8216;F&#8217; for field, &#8216;V&#8217; for value, surely?  But I digress)</em></p>
<h3>Summary</h3>
<p>I set-out to briefly demonstrate how nice and compact unary <code>+</code> is, but managed to get side-tracked once again.  The original summary would have been &#8220;<code>+</code> rocks! <code>parseInt</code> sucks&#8221;, but instead, we&#8217;ve got:</p>
<ul>
<li>Beware of white-space</li>
<li>Know your number formats</li>
<li>Unary <code>+</code></li>
<li>Use regular-expressions to check user-input matches a required format</li>
<li>Show <em>some</em> lenience</li>
</ul>
<h3>Coming Soon&#8230;</h3>
<p>The next two articles are very likely to touch on <code>getComputedStyle</code> and CSS&#8217;s <code>!important</code> modifier.  The first should be quite short (but I tend to waffle, so it&#8217;ll probably end up long), and I need to work on some examples or illustrations for the second one.  After that, I&#8217;m not sure.  I&#8217;ve got some ridiculous code for creating PNGs in JavaScript, so I&#8217;ll probably give that an outing at some point.</p>
<p>Thanks for reading.
</p>
]]></content:encoded>
			<wfw:commentRSS>http://hexmen.com/blog/2007/01/numbers-in-form-fields/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>Array push and pop: a complete embarrassment for JavaScript</title>
		<link>http://hexmen.com/blog/2006/12/push-and-pop/</link>
		<comments>http://hexmen.com/blog/2006/12/push-and-pop/#comments</comments>
		<pubDate>Wed, 06 Dec 2006 12:00:49 +0000</pubDate>
		<dc:creator>Ash</dc:creator>
		
	<category>JavaScript</category>
	<category>Browsers</category>
		<guid isPermaLink="false">http://hexmen.com/blog/2006/12/push-and-pop/</guid>
		<description><![CDATA[Most JavaScript libraries include trivial implementations of Array's <code>push</code> and <code>pop</code> methods to provide support for older browsers.  With no exaggeration, <em>every implementation is flawed</em>.  While this is quite damming, I've discovered something worse: <em>not one browser implements push and pop correctly</em>.  Each browser has its own bugs: Internet Explorer's methods can't be reused; Safari has type-conversion issues; Firefox &#38; Opera don't truncate Arrays properly.

Seven years after the publication of the <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMAScript Language Specification</a>, shouldn't we expect a little more?  In this article, I'll document the current problems, and show how to write implementations that conform precisely to the language spec'.]]></description>
			<content:encoded><![CDATA[<p>Most JavaScript libraries include trivial implementations of Array&#8217;s <code>push</code> and <code>pop</code> methods to provide support for older browsers.  However, literally <em>every</em> library&#8217;s implementation is flawed.  While this is bad enough, I&#8217;ve also found that <em>every browser&#8217;s implementation of push and pop contains bugs</em>.  These vary from browser to browser: Internet Explorer&#8217;s methods can&#8217;t be reused; Safari has type-conversion issues; and Firefox &amp; Opera don&#8217;t truncate Arrays properly.</p>
<p>It&#8217;s been seven years since the publication of the <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">official ECMAScript Language Specification</a>, and I think we should expect a little more from our browsers.  In this article, I&#8217;ve documented the current problems, and I show how to write library implementations conforming precisely to the language spec&#8217;.<a id="more-13"></a></p>
<h3>JavaScript Implementation</h3>
<p>Here are my functions (the <code>&gt;&gt;&gt;</code> operator is explained later in the article):</p>
<pre><code class="javascript">Array.prototype.push = function() {
    var n = this.length &gt;&gt;&gt; 0;
    for (var i = 0; i &lt; arguments.length; i++) {
	this[n] = arguments[i];
	n = n + 1 &gt;&gt;&gt; 0;
    }
    this.length = n;
    return n;
};

Array.prototype.pop = function() {
    var n = this.length &gt;&gt;&gt; 0, value;
    if (n) {
	value = this[--n];
	delete this[n];
    }
    this.length = n;
    return value;
};
</code></pre>
<p class="download">Download: <a href="/code/push-pop.js">push-pop.js</a></p>
<h3>Testing</h3>
<p>Always up for a challenge, I&#8217;ve tried to produce a bug-free implementation that conforms to the specification.  You can see how it fares on my <a href="http://hexmen.com/tests/pushpop.html">push and pop test page</a> <ins datetime="2007-01-03T17:47:12+00:00">(fixed link)</ins>.  The test page allows you to compare several library implementations to the browser&#8217;s built-in implementation, and mine.  There are about thirty tests in all, and you should find that even the browser&#8217;s implementations fail a couple of tests (some fail substantially more.)</p>
<p>So, why the high failure rate?  Simple: most browsers haven&#8217;t implemented arrays correctly; their understanding of an <em>array index</em> and <code>length</code> is wrong.  From the specification (section 15.4):</p>
<blockquote><p>A property name <em>P</em> (in the form of a string value) is an <em>array index</em> if and only if ToString(ToUint32(P)) is equal to P and ToUint32(<em>P</em>) is not equal to 2<sup>32</sup>−1.  Every Array object has a <code>length</code> property whose value is always a non-negative integer less than 2<sup>32</sup>. The value of the <code>length</code> property is numerically greater than the name of every property whose name is an array index; whenever a property of an Array object is created or changed, other properties are adjusted as necessary to maintain this invariant. Specifically, whenever a property is added whose name is an array index, the <code>length</code> property is changed, if necessary, to be one more than the numeric value of that array index; and whenever the <code>length</code> property is changed, every property whose name is an array index whose value is not smaller than the new length is automatically deleted. This constraint applies only to properties of the Array object itself and is unaffected by <code>length</code> or array index properties that may be inherited from its prototype.</p></blockquote>
<p>In simplified terms: array indexes are integers in the range [0, 2<sup>32</sup>-2], and the array <code>length</code> can take any integer value in the range [0, 2<sup>32</sup>-1] (both ranges start at 0, but end at different values.)  The <code>length</code> of an array is greater than any set <em>array index</em>; if the <code>length</code> is set explicitly, all array indexes &ge; <code>length</code> are deleted.</p>
<h3>Bugs</h3>
<ul>
<li>setting an array <code>length</code> to a non-integer value, a negative value, or an integer &ge; 2<sup>32</sup> should cause an error to be thrown.  Firefox is the only browser to get this right - Safari, Opera and Internet Explorer all fail this test (I called this test, unimaginatively, <code>testArrayLength</code>)</li>
<li>truncating an array doesn&#8217;t always cause the right array values to be deleted in Firefox (<code>testArrayTruncation</code>)</li>
<li><code>length</code> is updated incorrectly in certain circumstances in Firefox, Safari and Opera (<code>testArrayLengthMagic</code>)</li>
</ul>
<p>Now we&#8217;ve established that every browser has at least one problem with arrays, let&#8217;s look at the specification of push:</p>
<blockquote><p>
<b>15.4.4.7 Array.prototype.push ( [ item1 [ , item2 [ , … ] ] ] )</b><br />
The arguments are appended to the end of the array, in the order in which they appear. The new length of the array is returned as the result of the call.</p>
<p>When the <b>push</b> method is called with zero or more arguments <em>item1, item2</em>, etc., the following steps<br />
are taken:</p>
<ol>
<li>Call the [[Get]] method of this object with argument <code>"length"</code>.</li>
<li>Let <em>n</em> be the result of calling ToUint32(Result(1)).</li>
<li>Get the next argument in the argument list; if there are no more arguments, go to step 7.</li>
<li>Call the [[Put]] method of this object with arguments ToString(<em>n</em>) and Result(3).</li>
<li>Increase <em>n</em> by 1.</li>
<li>Go to step 3.</li>
<li>Call the [[Put]] method of this object with arguments <strong>&#8220;length&#8221;</strong> and <em>n</em>.</li>
<li>Return <em>n</em>.</li>
</ol>
<p>The length property of the push method is 1.</p>
<p><em>NOTE</em><br />
<em>The <code>push</code> function is intentionally generic; it does not require that its <strong>this</strong> value be an Array object.  Therefore it can be transferred to other kinds of objects for use as a method. Whether the <code>push</code> function can be applied successfully to a host object is implementation-dependent.</em>
</p></blockquote>
<p>And the specification for <code>pop</code>:</p>
<blockquote><p>
<b>15.4.4.6 Array.prototype.pop ( )</b><br />
The last element of the array is removed from the array and returned.</p>
<ol>
<li>Call the [[Get]] method of this object with argument <code>"length"</code>.</li>
<li>Call ToUint32(Result(1)).</li>
<li>If Result(2) is not zero, go to step 6.</li>
<li>Call the [[Put]] method of this object with arguments <code>"length"</code> and Result(2).</li>
<li>Return <code><b>undefined</b></code>.</li>
<li>Call ToString(Result(2)-1).</li>
<li>Call the [[Get]] method of this object with argument Result(6).</li>
<li>Call the [[Delete]] method of this object with argument Result(6).</li>
<li>Call the [[Put]] method of this object with arguments <code>"length"</code> and (Result(2)-1).</li>
<li>Return Result(7).</li>
</ol>
<p><em>NOTE</em><br />
<em>The <code>pop</code> function is intentionally generic; it does not require that its <b>this</b> value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method. Whether the <code>pop</code> function can be applied successfully to a host object is implementation-dependent.</em>
</p></blockquote>
<p>The notes in both specifications are very important - they mean that each method must be portable, able to work in isolation - no dependence on other Array methods or properties.  Implementation should not rely on side-effects of manipulating a <code>length</code> property, nor should they use other array methods like <code>splice</code> (as seen in an unusual implementation of push and pop in <a href="http://javascript.crockford.com/remedial.html">Douglas Crockford&#8217;s Remedial JavaScript</a>).</p>
<p>It&#8217;s this requirement for independence that causes Internet Explorer to fail a whole slew of tests, and puts it at the back of the pack in terms of standards compliance. </p>
<h3>The <code>&gt;&gt;&gt;</code> operator</h3>
<p>Working through the <code>push</code> and <code>pop</code> specifications, both methods need to use type-conversion to convert arbitrary (possibly undefined) objects to unsigned 32-bit integers.  This can be done using the unsigned right-shift operator (<code>&gt;&gt;&gt;</code>), and this reveals another - trivial - bug:  IE5 and Safari fail to ignore particular white-space characters when converting strings to unsigned 32-bit integers.  It&#8217;s a minor bug, and I hope Safari can be easily fixed by the <a href="http://webkit.org/">WebKit</a> guys - Microsoft fixed this particular Internet Explorer bug when they released IE5.5. (<code>testToUint32</code>)</p>
<p>Steps 3 - 6 of <code>push</code> are a little ambiguous, and the specification probably should have stated that repeated increments to <code>n</code> must be done using 32-bit unsigned integer arithmetic - it&#8217;s kind-of implicit as <code>n</code> is assigned the result of the internal ToUint32 operator.  Using 32-bit arithmetic leads to some strange edge-cases: when <code>n</code> overflows from 2<sup>32</sup>-1 to 0, <code>push</code> will have set a property called <code>4294967295</code>.  This is strange, as <code>429496795</code> is <em>not</em> an <em>array index</em> (as discussed above), but at least it means the property-value will still be available after the inevitable array-truncation (when <code>length</code> is set to some small value in step 8.)</p>
<p>Although the specification leaves room for the occasional bit of ambiguity, and prescribes some strange behaviour as a consequence, I think it&#8217;s well put together.  On-screen, it&#8217;s not so easy to work with, but Mozilla have produced an <a href="http://www.mozilla.org/js/language/E262-3.pdf" title="Mozilla's improved ECMAScript Language Specification PDF">improved PDF</a> which includes lots of bookmarks to help navigate through the document.
</p>
]]></content:encoded>
			<wfw:commentRSS>http://hexmen.com/blog/2006/12/push-and-pop/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>Iterating over sparse arrays</title>
		<link>http://hexmen.com/blog/2006/12/iterating-over-sparse-arrays/</link>
		<comments>http://hexmen.com/blog/2006/12/iterating-over-sparse-arrays/#comments</comments>
		<pubDate>Wed, 06 Dec 2006 16:59:54 +0000</pubDate>
		<dc:creator>Ash</dc:creator>
		
	<category>JavaScript</category>
		<guid isPermaLink="false">http://hexmen.com/blog/2006/12/iterating-over-sparse-arrays/</guid>
		<description><![CDATA[This is a quick tip for iterating over arrays and other objects with a <code>length</code> property.  It's particularly suitable for sparse arrays, without having to worry whether any methods have been added to the prototype chain.]]></description>
			<content:encoded><![CDATA[<p>This is a quick tip for iterating over arrays and other objects with a <code>length</code> property.  It&#8217;s particularly suitable for sparse arrays, without having to worry whether any methods have been added to the prototype chain.<a id="more-14"></a></p>
<p>Dean Edwards recently described a pretty cool technique for <a href="http://dean.edwards.name/weblog/2006/07/enum/">enumerating javascript objects</a>, but (currently) it&#8217;s not appropriate for sparse arrays.  In case you&#8217;re unfamiliar with sparse arrays (or I&#8217;m using the wrong term), in the language of the <a href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach">Mozilla documentation for <code>Array.forEach</code></a>, a sparse array is one that&#8217;s not &#8220;dense&#8221;.  For example:</p>
<pre class="javascript">
// create a three-element array
var array = ['hope', 'empire', 'jedi'];
// add a fourth
array[987654321] = 'menace'; 

// because array length is now 987654322
// this is a really inefficient way of iterating:
for (var i = 0; i &lt; array.length; i++) {
    ... do something ...
}
</pre>
<p>Iterating over this array using the <code>for</code> loop shown above would mean the loop is executed hundreds of millions of times.  That&#8217;s terribly inefficient for an array containing so few elements.  A more efficient way is to use <code>for (property in object)</code>, with an <code>if</code> condition to filter out irrelevant properties:</p>
<pre class="javascript">
for (var property in object) {
    if (String(property &gt;&gt;&gt; 0) == property &#038;&#038;
            property &gt;&gt;&gt; 0 != 0xffffffff) {
        ... do something ...
    }
}
</pre>
<p>The <code>if</code> condition checks whether the property is an <em>array index</em> as defined by the language specification:</p>
<blockquote><p>A property name P (in the form of a string value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 2<sup>32</sup>−1
</p></blockquote>
<p>That&#8217;s it.
</p>
]]></content:encoded>
			<wfw:commentRSS>http://hexmen.com/blog/2006/12/iterating-over-sparse-arrays/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>Fixing Firebug&#8217;s Style Tab</title>
		<link>http://hexmen.com/blog/2006/12/fixing-firebugs-style-tab/</link>
		<comments>http://hexmen.com/blog/2006/12/fixing-firebugs-style-tab/#comments</comments>
		<pubDate>Mon, 11 Dec 2006 10:13:40 +0000</pubDate>
		<dc:creator>Ash</dc:creator>
		
	<category>CSS</category>
	<category>Browsers</category>
		<guid isPermaLink="false">http://hexmen.com/blog/2006/12/fixing-firebugs-style-tab/</guid>
		<description><![CDATA[Some users upgrading to the new Firebug Beta are having problems using the <strong>Style</strong> tab.  There is a short three-step procedure for fixing the problem, described here.]]></description>
			<content:encoded><![CDATA[<p>Lots of people are unable to use the <strong>Style</strong> tab in the new <a href="http://www.getfirebug.com/downloads.html" title="Download Firebug at www.getfirebug.com">Firebug</a> beta.  The <a href="http://getfirebug.com/faq.html">Firebug FAQ</a> leads to a thread suggesting this fix:</p>
<ol>
<li>Uninstall Firefox</li>
<li>Delete the (left-over) install folder (e.g. <code>C:\Program Files\Mozilla Firefox</code>)</li>
<li>Reinstall Firefox using a <em>custom install</em> (to ensure the DOM Inspector is installed</li>
</ol>
<p>Knowing that I already had the DOM Inspector installed, I thought I&#8217;d try removing just a few files, instead of the whole install folder.  Whatever I did worked, and the <strong>Style</strong> tab works for me now.  This more conservative procedure is:</p>
<ol>
<li>Uninstall Firefox</li>
<li>Delete only the named <code>inspector</code>* in <code>C:\Program Files\Mozilla Firefox\components</code>
</li>
<li>Reinstall Firefox using a <em>custom install</em> (to ensure the DOM Inspector is installed</li>
</ol>
<p>I&#8217;m not sure whether the uninstall and reinstall procedure is strictly necessary, so I&#8217;m hoping someone out there can try this:</p>
<ol>
<li>Stop Firefox</li>
<li>Delete all files named <code>inspector</code>* in <code>C:\Program Files\Mozilla Firefox\components</code>
</li>
<li>Restart Firefox</li>
</ol>
]]></content:encoded>
			<wfw:commentRSS>http://hexmen.com/blog/2006/12/fixing-firebugs-style-tab/feed/</wfw:commentRSS>
		</item>
	</channel>
</rss>
