views:

193

answers:

3

I just came across this piece in the Mozilla Javascript documentation:

var len = this.length >>> 0;  

I don't quite understand why this is being done. What good does zero-fill right shifting this.length by 0 do? As far as I understand, it does exactly nothing. Is it to safely establish a default value for len, even if this.length is not an integer? Can this ever feasibly be the case? If so, what's the difference between >> 0 and >>> 0?

+1  A: 

>>> is the unsigned right shift operator (see p. 76 of the JavaScript 1.5 specification), as opposed to the >>, the signed right shift operator.

>>> changes the results of shifting negative numbers because it does not preserve the sign bit when shifting. The consequences of this is can be understood by example, from an interpretter:

$ 1 >> 0
1
$ 0 >> 0
0
$ -1 >> 0
-1
$ 1 >>> 0
1
$ 0 >>> 0
0
$ -1 >>> 0
4294967295
$(-1 >>> 0).toString(16)
"ffffffff"
$ "cabbage" >>> 0
0

So what is probably intended to be done here is to get the length, or 0 if the length is undefined or not an integer, as per the "cabbage" example above. I think in this case it is safe to assume that this.length will never be < 0. Nevertheless, I would argue that this example is a nasty hack, for two reasons:

  1. The behavior of <<< when using negative numbers, a side-effect probably not intended (or likely to occur) in the example above.

  2. The intention of the code is not obvious, as the existence of this question verifies.

Best practice is probably to use something more readable unless performance is absolutely critical:

isNaN(parseInt(foo)) ? 0 : parseInt(foo)
fmark
Sooo... @johncatfish is correct? It's to ensure this.length is non-negative?
Duracell
Could the case of `-1 >>> 0` ever happen and if so, is it really desirable to shift it to 4294967295? Seems like this would cause the loop to run a few more times than necessary.
deceze
@deceze: Without seeing the implementation of `this.length` it is impossible to know. For any "sane" implementation the length of a string should never be negative, but then one might argue that in a "sane" environment we can assume the existence of a `this.length` property that always returns an integral number.
fmark
Why the downvote?
fmark
+3  A: 

Two reasons:

  1. The result of >>> is an "integral"

  2. undefined >>> 0 = 0 (since JS will try and coerce the LFS to numeric context, this will work for "foo" >>> 0, etc. as well)

Remember that numbers in JS have an internal-representation of double. It's just a "quick" way of basic input sanity for length.

However, -1 >>> 0 (oops, likely not a desired length!)

pst
+5  A: 
CMS
While the linked *array extras* implementation may be correct (or close to correct) the code is still a bad code example. Perhaps even a comment to clarify intention would resolve this situation.
fmark
Is it possible that the length of an array is *not* an integer? I can't imagine that, so this kind of `ToUint32` seems a bit unnecessary to me.
Marcel Korpel
@Marcel: Keep in mind that most of the `Array.prototype` methods are *intentionally generic*, they can be used on *array-like* objects e.g. `Array.prototype.indexOf.call({0:'foo', 1:'bar', length: 2}, 'bar') == 1;`. The `arguments` object is also a good example. For *pure* array objects, it's impossible to change the type of the `length` property, because they implement an special [[[`Put`](http://bit.ly/d5hfSL)]] internal method, and when an assignment is made to the `length` property, again is converted `ToUint32` and other actions are taken, like deleting indexes above the new length...
CMS