I've been trying to teach myself Javascript lately and I'm noticing several slightly quirky syntax choices used by various different authors. Usually I can figure them out, but this one's stumped me a bit.
The author of the post here creates an empty object, colors, which will contain a set of properties for each background color in the page. Each color property will have a value equal to the total area covered by that color. To do this, he uses the following syntax:
// ...set or override it in the colors object,
// adding the current element area to the
// existing value.
colors[bgColor] = (colors[bgColor] >> 0) + nodeArea;
At this point, the property named by the value of bgColor may or may not be present in the object. The intent of the expression in the parenthesis is presumably to return the running total or 0 if this is the first time the color is seen. My question is, is this the right shift operator being overloaded and I'm searching for the wrong name, or why does the right shift behave this way?
The intent of the expression in the parenthesis is presumably to return the running total or 0 if this is the first time the color is seen. My question is, is this the right shift operator being overloaded and I'm searching for the wrong name, or why does the right shift behave this way?
It's not overloaded (JavaScript doesn't have operator overloading). It's relying on the fact that undefined >> 0
is 0
and anyNumber >> 0
is anyNumber
(caveats to follow). If the property doesn't exist yet, looking it up yields undefined
, and so >> 0
turns that into 0
. If the property is defined and contains a whole number that fits in 32 bits, >> 0
returns the number without changing it. (If the number has a fractional part, it's truncated, and if it doesn't fit in 32 bits, it's wrapped if I'm reading that right, but I don't think that's what the coder is trying to do.) So by doing that, then adding the area, they are indeed adding to a running total (or initializing it if it isn't there yet).
It's mostly a shorthand version of:
if (colors[bgColor]) {
colors[bgColor] += nodeArea;
}
else {
colors[bgColor] = nodeArea;
}
...(as any falsey value >> 0
is 0
) but with the added feature that it will always result in a non-NaN
number provided nodeArea
is a non-NaN
number, whereas with some truthy non-number values for colors[bgColor]
({}
, for instance), the "long" version above would result in a string or in NaN
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With