# What’s happening in this code with Number objects holding properties and incrementing the number?

## What’s happening in this code with Number objects holding properties and incrementing the number?

A recent tweet contained this snippet of JavaScript.
Can someone please explain what is happening in it step by step?
> function dis() { return this }
undefined
> five = dis.call(5)
Number {[[PrimitiveValue]]: 5}
> five.wtf = ‘potato’
“potato”
> five.wtf
“potato”
> five * 5
25
> five.wtf
“potato”
> five++
5
> five.wtf
undefined
> five.wtf = ‘potato?’
“potato?”
> five.wtf
undefined
> five
6

In particular, it is not clear to me:

why the result of dis.call(5) is a Number with some kind of a [[PrimitiveValue]] property, but the results of five++ and five * 5 appear to just be the plain numbers 5 and 25 (not Numbers)
why the five.wtf property disappears after the five++ increment
why the five.wtf property is no longer even settable after the five++ increment, despite the five.wtf = ‘potato?’ assignment apparently setting the value.

### Solution 1:

OP here. Funny to see this on Stack Overflow 🙂

Before stepping through the behaviour, its important to clarify a few things:

1. Number value and Number object (`a = 3` vs `a = new Number(3)`) are very different. One is a primitive, the other is an object. You cannot assign attributes to primitives, but you can to objects.

2. Coercion between the two is implicit.

For example:

``````(new Number(3) === 3)  // returns false
(new Number(3) == 3)   // returns true, as the '==' operator coerces
(+new Number(3) === 3) // returns true, as the '+' operator coerces
``````
3. Every Expression has a return value. When the REPL reads and executes an expression, this is what it displays. The return values often don’t mean what you think and imply things that just aren’t true.

Ok, here we go.

### The pledge.

``````> function dis() { return this }
undefined
> five = dis.call(5)
[Number: 5]
``````

Define a function `dis` and call it with `5`. This will execute the function with `5` as the context (`this`). Here it is coerced from a Number value to a Number object. It is very important to note that were we in strict mode this would not have happened.

``````> five.wtf = 'potato'
'potato'
> five.wtf
'potato'
``````

Now we set the attribute `five.wtf` to `'potato'`, and with five as an object, sure enough it accepts the Simple Assignment.

``````> five * 5
25
> five.wtf
'potato'
``````

With `five` as an object, I ensure it can still perform simple arithmetic operations. It can. Do its attributes still stick? Yes.

### The turn.

``````> five++
5
> five.wtf
undefined
``````

Now we check `five++`. The trick with postfix increment is that the entire expression will evaluate against the original value and then increment the value. It looks like `five` is still five, but really the expression evaluated to five, then set `five` to `6`.

Not only did `five` get set to `6`, but it was coerced back into a Number value, and all attributes are lost. Since primitives cannot hold attributes, `five.wtf` is undefined.

``````> five.wtf = 'potato?'
'potato?'
> five.wtf
undefined
``````

I again attempt to reassign an attribute `wtf` to `five`. The return value implies it sticks, but it in fact does not because `five` is a Number value, not a Number object. The expression evaluates to `'potato?'`, but when we check we see it was not assigned.

### The prestige.

``````> five
6
``````

Ever since the postfix increment, `five` has been `6`.

### Solution 2:

There are two different ways to represent a number:

``````var a = 5;
var b = new Number(5);
``````

The first is a primitive, the second an object. For all intents and purposes both behave the same, except they look different when printed to the console. One important difference is that, as an object, `new Number(5)` accepts new properties just like any plain `{}`, while the primitive `5` does not:

``````a.foo = 'bar';  // doesn't stick
b.foo = 'bar';  // sticks
``````

As for the initial `dis.call(5)` part, please see How does the “this” keyword work?. Let’s just say that the first argument to `call` is used as the value of `this`, and that this operation forces the number into the more complex `Number` object form.* Later on `++` forces it back into the primitive form, because the addition operation `+` results in a new primitive.

``````> five = dis.call(5)  // for all intents and purposes same as new Number(5)
Number {[[PrimitiveValue]]: 5}
> five.wtf = 'potato'
"potato"
> five.wtf
"potato"
``````

A `Number` object accepts new properties.

``````> five++
``````

`++` results in a new primitive `6` value…

``````> five.wtf
undefined
> five.wtf = 'potato?'
"potato?"
> five.wtf
undefined
``````

…which does not have and does not accept custom attributes.

* Note that in strict mode the `this` argument would be treated differently and would not be converted to a `Number`. See http://es5.github.io/#x10.4.3 for the implementation details.

### Solution 3:

There’s Coercion in the JavaScript World – A Detective Story

Nathan, you have no idea what you’ve uncovered.

I’ve been investigating this for weeks now. It all started on a stormy night last October. I accidentally stumbled upon the `Number` class – I mean, why in the world did JavaScript have a `Number` class?

I wasn’t prepared for what I was going to find out next.

Related:  What's the difference between `HTMLElement` and `Element`?

It turns out that JavaScript, without telling you, has been changing your numbers to objects and your objects to numbers right under your nose.

JavaScript was hoping no one would catch on, but people have been reporting strange unexpected behavior, and now thanks to you and your question I have the evidence I need to blow this thing wide open.

This is what we’ve found out so far. I don’t know if I should even be telling you this – you might want to turn off your JavaScript.

``````> function dis() { return this }
undefined
``````

When you created that function, you probably had no idea what was going to happen next. Everything looked fine, and everything was fine – for now.

No error messages, just the word “undefined” in console output, exactly what you would expect. After all, this was a function declaration – it isn’t supposed to return anything.

But this was just the beginning. What happened next, no one could have predicted.

``````> five = dis.call(5)
Number {[[PrimitiveValue]]: 5}
``````

Yeah I know, you expected a `5`, but that’s not what you got, was it – you got something else – something different.

The same thing happened to me.

I didn’t know what to make of it. It drove me nuts. I couldn’t sleep, I couldn’t eat, I tried to drink it away, but no amount of Mountain Dew would make me forget. It just didn’t make any sense!

That’s when I found out what was really going on – it was coercion, and it was happening right there in front of my eyes, but I was too blind to see it.

Mozilla tried to bury it by putting it where they knew nobody would look – their documentation.

“… and primitive values will be converted to objects.”

It was right there plain as can be spelled out in Open Sans font. It was the `call()` function – how could I be so stupid?!

My number was no longer a number at all. The moment I passed it into `call()`, it became something else. It became… an object.

I couldn’t believe it at first. How could this be true? But I couldn’t ignore the evidence that was mounting up around me. It’s right there if you just look:

``````> five.wtf = 'potato'
"potato"

> five.wtf
"potato"
``````

`wtf` was right. Numbers can’t have custom properties – we all know that! It’s the first thing they teach you at the academy.

We should have known the moment we saw the console output – this was not the number we thought it was. This was an impostor – an object passing itself off as our sweet innocent number.

This was… `new Number(5)`.

Of course! It made perfect sense. `call()` had a job to do, he had to invoke a function, and to do that he needed to populate `this`, he knew he couldn’t do that with a number – he needed an object and he was willing to do anything to get it, even if that meant coercing our number. When `call()` saw the number `5`, he saw an opportunity.

It was the perfect plan: wait until no one was looking and swap out our number for an object that looks just like it. We get a number, the function gets invoked, and no one would be the wiser.

It really was the perfect plan, but like all plans, even perfect ones, there was a hole in it, and we were about to fall right into it.

See, what `call()` didn’t understand was that he wasn’t the only one in town who could coerce numbers. This was JavaScript after all – coercion was everywhere.

`call()` took my number, and I wasn’t going to stop until I pulled the mask off of his little impostor and expose him to the whole Stack Overflow community.

But how? I needed a plan. Sure it looks like a number, but I know it’s not, there’s gotta be a way to prove that. That’s it! It looks like a number, but can it act like one?

I told `five` I need him to become 5 times larger – he didn’t ask why and I didn’t explain. I then did what any good programmer would do: I multiplied. Surely there was no way he could fake his way out of this.

``````> five * 5
25
> five.wtf
'potato'
``````

Damn it! Not only did `five` multiply just fine `wtf` was still there. Damn this guy and his potato.

What the hell was going on? Was I wrong about this whole thing? Is `five` really a number? No, I must be missing something, I know it, there’s something I must be forgetting, something so simple and basic that I’m completely overlooking it.

This was not looking good, I had been writing this answer for hours and I was still no closer to making my point. I couldn’t keep this up, eventually people would stop reading, I had to think of something and I had to think of it fast.

Related:  Resetting the opacity of a child element - Maple Browser (Samsung TV App)

Wait that’s it! `five` wasn’t 25, 25 was the result, 25 was a completely different number. Of course, how could I forget? Numbers are immutable. When you multiply `5 * 5` nothing gets assigned to anything you just create a new number `25`.

That must be what’s happening here. Somehow when I multiply `five * 5`, `five` must be getting coerced into a number and that number must be the one used for the multiplication. It’s the results of that multiplication that gets printed to the console, not the value of `five` itself. `five` never gets assigned anything – so of course it doesn’t change.

So then how do I get `five` to assign himself the result of an operation. I got it. Before `five` even had a chance to think, I yelled “++”.

``````> five++
5
``````

Aha! I had him! Everybody knows `5 + 1` is `6`, this was the evidence I needed to expose that `five` was not a number! It was an impostor! A bad impostor that didn’t know how to count. And I could prove it. Here’s how a real number acts:

``````> num = 5
5
> num++
5
``````

Wait? What was going on here? sigh I got so caught up in busting `five` that I forget how post operators work. When I use the `++` at the end of `five` I’m saying return the current value, then increment `five`. It’s the value before the operation occurs that gets printed to the console. `num` was in fact `6` and I could prove it:

``````>num
6
``````

Time to see what `five` really was:

``````>five
6
``````

…it was exactly what it should be. `five` was good – but I was better. If `five` were still an object that would mean it would still have the property `wtf` and I was willing to bet everything it didn’t.

``````> five.wtf
undefined
``````

Aha! I was right. I had him! `five` was a number now – it wasn’t an object anymore. I knew the multiplication trick wouldn’t save it this time. See `five++` is really `five = five + 1`. Unlike the multiplication, the `++` operator assigns a value to `five`. More specifically, it assigns it the results of `five + 1` which just like in the case of multiplication returns a new immutable number.

I knew I had him, and just to make sure he couldn’t squirm his way out of it. I had one more test up my sleeve. If I was right, and `five` was really a number now, then this wouldn’t work:

``````> five.wtf = 'potato?'
'potato?'
``````

He wasn’t going to fool me this time. I knew `potato?` was going to be printed to the console because that’s output of the assignment. The real question is, will `wtf` still be there?

``````> five.wtf
undefined
``````

Just as I suspected – nothing – because numbers can’t be assigned properties. We learned that the first year at the academy 😉

Thanks Nathan. Thanks to your courage in asking this question I can finally put all this behind me and move on to a new case.

Like this one about the function `toValue()`. Oh dear god. Nooo!

### Solution 4:

``````01 > function dis() { return this }
02 undefined
03 > five = dis.call(5)
04 Number {[[PrimitiveValue]]: 5}
05 > five.wtf = 'potato'
06 "potato"
07 > five.wtf
08 "potato"
09 > five * 5
10 25
11 > five.wtf
12 "potato"
13 > five++
14 5
15 > five.wtf
16 undefined
17 > five.wtf = 'potato?'
18 "potato?"
19 > five.wtf
20 undefined
21 > five
22 6
``````

`01` declares a function `dis` that returns the context object. What `this` represents changes depending on whether you’re using strict mode or not. The entire example has different results if the function were declared as:

``````> function dis() { "use strict"; return this }
``````

This is detailed in section 10.4.3 in the ES5 specification

1. If the function code is strict code, set the ThisBinding to thisArg.
2. Else if thisArg is null or undefined, set the ThisBinding to the global object.
3. Else if Type(thisArg) is not Object, set the ThisBinding to ToObject(thisArg).

`02` is the return value of the function declaration. `undefined` should be self explanatory here.

`03` the variable `five` is initialized with the return value of `dis` when called in the context of the primitive value `5`. Because `dis` is not in strict mode, this line is identical to calling `five = Object(5)`.

`04` The odd `Number {[[PrimitiveValue]]: 5}` return value is the representation of the object that wraps the primitive value `5`

`05` the `five` object’s `wtf` property is assigned a string value of `'potato'`

`06` is the return value of the assignment and should be self explanatory.

`07` the `five` object’s `wtf` property is being examined

`08` as `five.wtf` was previously set to `'potato'` it returns `'potato'` here

`09` the `five` object is being multiplied by the primitive value `5`. This is no different from any other object being multiplied and is explained in section 11.5 of the ES5 specification. Of particular note is how objects are cast to numeric values, which is covered in a few sections.

Related:  javascript change event on input element fires on only losing focus
1. Let primValue be ToPrimitive(input argument, hint Number).

Return a default value for the Object. The default value of an object is retrieved by calling the [[DefaultValue]] internal method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] internal method is defined by this specification for all native ECMAScript objects in 8.12.8.

Let valueOf be the result of calling the [[Get]] internal method of object O with argument “valueOf”.

1. If IsCallable(valueOf) is true then,

1. Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value and an empty argument list.
2. If val is a primitive value, return val.

This is all a roundabout way of saying that the object’s `valueOf` function gets called and the return value from that function is used in the equation. If you were to change the `valueOf` function you could change the results of the operation:

``````> five.valueOf = function () { return 10 }
undefined
> five * 5
50
``````

`10` as `five`s `valueOf` function was unchanged, it returns the wrapped primitive value `5` so that `five * 5` evaluates to `5 * 5` which results in `25`

`11` the `five` object’s `wtf` property is evaluated again despite having been unchanged from when it was assigned on `05`.

`12` `'potato'`

`13` the Postfix Increment Operator is called on `five`, which gets the numeric value (`5`, we covered how earlier), stores the value so that it can be returned, adds `1` to the value (`6`), assigns the value to `five`, and returns the stored value (`5`)

`14` as before, the returned value is the value before it was incremented

`15` the `wtf` property of the primitive value (`6`) stored at the variable `five` is accessed. Section 15.7.5 of the ES5 specification defines this behavior. Numbers get the properties from `Number.prototype`.

`16` `Number.prototype` doesn’t have a `wtf` property, so `undefined` is returned

`17` `five.wtf` is assigned a value of `'potato?'`. Assignment is defined in 11.13.1 of the ES5 specification. Basically the value assigned is returned but not stored.

`18` `'potato?'` was returned by the assignment operator

`19` again `five`, which has a value of `6` is accessed, and again `Number.prototype` doesn’t have a `wtf` property

`20` `undefined` as explained above

`21` `five` is accessed

`22` `6` is returned as explained in `13`

### Solution 5:

It’s pretty simple.

``````function dis () { return this; }
``````

This returns the `this` context. So, if you do `call(5)` you’re passing the number as an object.

The `call` function doesn’t supply arguments, the first argument you give is the context of `this`. Usually if you want it on it’s on context, you give it `{}` so `dis.call({})`, which means `this` in the function is an empty `this`. However, if you pass `5` it seems it will be converted to an object. See .call

So the return is `object`

When you do `five * 5`, JavaScript sees the object `five` as the primitive type, so is equivalent to `5 * 5`. Interestingly, do `'5' * 5`, it still equals `25`, so JavaScript is clearly casting under the hood. No changes to the underlying `five` type is done on this line

But when you do `++` it will convert the object to the primitive `number` type thus removing the `.wtf` property. Because you are affecting the underlying type

### Solution 6:

The primitive values can’t have property. But when you try to access to a property on primitive value, it transparently transtype to a temporary Number object.

So:

``````> function dis() { return this }
undefined
// Like five.dis(), so dis return the temporaty Number object and
// reference it in five
> five = dis.call(5)
Number {[[PrimitiveValue]]: 5}

// Write the wtf attribut on the Number object referenced by five
> five.wtf = 'potato'
"potato"
// Read the wtf attribut on the Number object referenced by five
> five.wtf
"potato"

// Return 5*5 but dont change the reference of five
> five * 5
25
// Read the same wtf attribut on the Number object referenced by five
> five.wtf
"potato"

// Change the five reference to a new primitive value (5+1). Five
// reference a primitive now.
> five++
5

// Read the wtf attribut on a new temporary Number object construct from
// the primitive referenced by five. So wtf does not exist.
> five.wtf
undefined

// Write the wtf attribut on a new temporary Number object construct from
// the primitive referenced by five. But this object not referenced by
// five. It will be lost.
> five.wtf = 'potato?'
"potato?"

// Read the wtf attribut on a new temporary Number object construct from
// the primitive referenced by five. So wtf does not exist.
> five.wtf
undefined
> five
6
``````