views:

191

answers:

3

JavaScript does funky automatic conversions with objects:

var o = {toString: function() {return "40"; }};
print(o + o);
print((o+1)+o);
print((o*2) + (+o));

will print:

4040
40140
120

This is because +, if any of the arguments are objects/strings, will try to convert all the arguments to strings then concatenate them. If all arguments are numbers, it adds them together. * and unary + convert objects to numbers using toString (as well as valueOf, not shown here).

What does JavaScript do for the ++ operator?

+3  A: 

The following code illustrates this well:

var a = {toString: function() {return "40"; }};
nl(typeof a);
nl(typeof +a);
nl(typeof a);
nl(typeof (a++));
nl(a);
nl(typeof a);

The output is:

object
number
object
number
41
number

Unary plus converts the object to a number and doesn't modify it. a++ first converts the object to a number, then returns that number, and then increments the number, storing the value in a.

This is opposed to another possible solution, where a++ would first return the object, and then do the conversion to a number and incrementation.

Claudiu
+1  A: 

The ++ operator does a "toNumber" conversion (basically a combination of type rules and the valueOf function). Basically for any resolve expression

 resolveExpression++

The steps taken by the JS engine are

 <temp> = toNumber(resolveExpression);
 resolveExpression = <temp> + 1;
 <result> = <temp>

For non-atomic resolve expressions, eg. base.resolve++ or base["resolve"]++, etc. base is resolved only once and then reused. In any sane case this is irrelevant, however it's important if the value being incremented is an object with a valueOf implementation that changes the base object.

eg.

base = {};
base.value = {valueOf:function(){base = {}; return 5;}}
base.value++;
olliej
+4  A: 

From ECMAScript Language Specification

11.3 Postfix Expressions

Syntax

PostfixExpression :

  • LeftHandSideExpression
  • LeftHandSideExpression [no LineTerminator here] ++
  • LeftHandSideExpression [no LineTerminator here] --

11.3.1 Postfix Increment Operator

The production PostfixExpression : LeftHandSideExpression [no LineTerminator here] ++ is evaluated as follows:

  1. Evaluate LeftHandSideExpression.
  2. Call GetValue(Result(1)).
  3. Call ToNumber(Result(2)).
  4. Add the value 1 to Result(3), using the same rules as for the + operator (section 11.6.3).
  5. Call PutValue(Result(1), Result(4)).
  6. Return Result(3).


This is pseudo javascript code of how postInc works:

function postInc(a) {
  var x = +a; // Converts a to a number, Section 11.4.6 Unary + Operator
  a = x + 1;
  return x;
}

Edit: As mikesamuel said: it's not parseInt. Updated to reflect that.

some
There's no parseInt involved.It converts to a number, so the result might have a fractional part.consider x = '4.5', ++xand the internal number conversion scheme will recognize hex in strings x = '0xA', ++x
Mike Samuel
@Mikesamuel: Yep, my bad. It was supposed to be in pseudo code... I have updated it now. Thank you for pointing it out.
some