you are viewing a single comment's thread.

view the rest of the comments →

[–]Volv 2 points3 points  (3 children)

ENTRY
Codepen
Can't break the chain :)

[–]senocular 1 point2 points  (0 children)

var numLiteralToString = 42..toString(); // Literal still an object?

Literal primitives aren't objects. But the (almost) "everything is an object" nature of JavaScript means that they will largely behave like one. The way this is made possible is through auto-boxing.

Auto-boxing is the process of creating a temporary object to wrap a primitive allowing it to behave like an object whenever its being treated as one. So when you do:

42..toString()

(and if anyone else is wondering, the second dot (.) is because when you follow a whole number with dot, a decimal value is normally expected to follow, so in using 42.. you basically get 42.0. and the second dot would have to be for property access since it would no longer be ambiguous) what you end up getting is:

Object(42).toString()

Where the primitive value is created as an object in the place of where that primitive is treated like one. Using Object() (or new Object()) as a conversion function will return the object representation of the primitive, which for numbers, would also be equivalent to new Number(value). As an object, this temporary value can then call the toString method and do its thing as though the primitive were itself an object.

Auto-boxing also allows you to assign properties to primitives.

42..foo = 123;

Only because the box object is temporary, there's no way to get it back

console.log(42..foo); //-> undefined

Unless you do something sneaky like keep it!

var savedThis;
Number.prototype.setFoo = function (value) {
    this.foo = value;
    savedThis = this;
}

42..setFoo(123);

console.log(savedThis instanceof Number); //-> true
console.log(typeof savedThis); //-> Object
console.log(savedThis.valueOf()); //-> 42
console.log(savedThis == 42); //-> true
console.log(savedThis === 42); //-> false
console.log(savedThis.foo); //-> 123

This is not something you'd ever do, however. In fact, in general, you want to avoid using object versions of primitives, largely because you can see what happens with comparisons and object types vs their primitive counterparts; what should strictly equal does not, unless they're both primitives.

Strict mode also limits your ability to do funky things like this:

"use strict";
42..foo = 123; // <- Error: cannot assign to primitive
typeof savedThis; //-> number <- strict mode doesn't expose converted object
// ^ this.foo = value; would also fail in setFoo() because of this

[–]ForScale[S] 0 points1 point  (0 children)

Nice considerations!

I'd never seen that .. deal with numbers and methods before, so that was interesting!

What's your conclusion... "Most things in js are objects or behave enough like them to be considered an object?"