3

I'm reading through a jquery plugin, and find this interesting syntax:

'sth'+ +new Date

It creates a numeric string which the author used for a unique id: sth1237004731731

I'm curious what kind of syntax it is, and if there's some reading materials about it? Thanks!

Xun Yang
  • 4,209
  • 8
  • 39
  • 68

2 Answers2

6

It's using some side effects of JavaScript's type coercion to build a unique identifier (probably for an element). The confusing part is the +new Date. Here, new Date (or new Date()) returns a Date object. But putting a + or a - in front of this forces the JS interpreter to coerce this value to a Number object, and the way JS does Date > Number is by returning the timestamp (or getTime()).

So this code could be expressed differently like this:

var date = new Date(), // "Mon May 14 2012 10:03:58 GMT-0400 (EST)"
    timestamp = date.getTime(), // 1337004238612
    identifierString = "sth" + timestamp.toString();

You might reasonably claim that there's no need to be so verbose, so I personally would probably have written this as:

var identifier = "sth" + (new Date()).getTime();

However, please avoid coding things like your example if you ever expect someone might have to maintain your code. If it stopped you in your tracks, it probably will stop a lot of people. Coding style is not merely about expressing intent to the interpreter, but expressing intent to human developers. If the code works in the browser but fails with a syntax error in most experienced developers' heads, you've done it wrong, plain and simple.

Andrew
  • 14,204
  • 15
  • 60
  • 104
  • Thanks for the explanation @Andrew! And I totally agree with your points, after being confused by numerous cryptic examples. – Xun Yang May 14 '12 at 14:25
  • I agree that the unary `+` is often cryptic, since not many people know about it. An alternative option is to use `Number(expr)` instead of `+expr`. The two have identical behavior except `+expr` will return `ToNumber(GetValue(expr))` whereas `Number(expr)` returns simply `ToNumber(expr)`. In the real world, this means no difference, since `GetValue` is mainly for internal (spec-level) purposes. – Reid May 14 '12 at 14:33
  • 1
    @Reid, I dunno. The `Date` object has a specific method for returning a timestamp that's been there since the beginning. Just lately, there's been this very odd search for the most absolutely minimal coding expressions possible and it always seems to escalate into 'side effects' territory, which I think is a little dangerous. It stops younger programmers from grokking the language and drives a wedge in the wider community (as if we need any more). JS is a fantastically simple language (with some really bizarre quirks), but if this continues, our code will read like regular expressions. – Andrew May 14 '12 at 14:43
5

This is an interesting use of the unary + operator. Basically, you can break down this expression into three separate parts, splitting at the binary + operator:

"sth", then +, then +new Date.

The first operand of the binary + is just a generic string literal. The second operand uses the unary + operator, which, as the linked standard states, converts its operand to a Number.

Because the new operator has the highest precedence, it "binds tighter" than the unary +, which means new Date will be evaluated first. So the operand of the unary + is, in turn, the result of the expression new Date. Of course, new Date simply creates a blank Date object. As per § 15.9.3.3 new Date():

The [[PrimitiveValue]] internal property of the newly constructed object is set to the time value (UTC) identifying the current time.

In other words, a new Date will just be a Date object representing the current time. And, in turn, +new Date will convert a blank Date object to a number.

The Short Answer

The specification is long and hard to follow. In short, +new Date returns the UNIX timestamp associated with the current time.

The Long Answer: Following the Spec

The long answer, following the specification, is that the unary + calls ToNumber(GetValue(expr)) where expr is the evaluated operand. GetValue(dateObj) will simply return dateObj, so the expression then becomes ToNumber(dateObj).

The result of ToNumber depends on what the type of the argument is. In the case of an object, it returns ToNumber(ToPrimitive(input argument, hint Number)).

ToPrimitive will, in turn, call the valueOf property of the Date object. That returns a Number, which is the time value associated with the Date object: finally, what we were looking for! Then it goes back up the chain: ToNumber(num) simply returns num.

Of course, from there, the string "sth" and the result of +new Date are concatenated (you can find that in the spec if you so wish), which gives you the result you were looking for.

Reid
  • 18,959
  • 5
  • 37
  • 37
  • Thanks @Reid for your in-depth explanation! Wish I could mark your answer as accepted too if it's allowed by Stack :) – Xun Yang May 14 '12 at 14:31