Built-In Objects - Number

As you would guess just as there is a String object there is a Number object.

If you try:

alert(Number(3));

you will see the number 3 displayed. You have created a Number object with the value 3.

JavaScript doesn't distinguish between different types of number - so no ints and floats. You can use integers, whole numbers, or decimal numbers such as 1.234 as values for Number objects.

This has implication that we have to look at later but for now you can just accept the simplification of not having to worry about different representations of numeric values. Don't underestimate the value of this simplification to a beginner. When you start to explain to a non-programmer that there are two types of number floats and ints you can see their eyes glaze over and a deep mistrust of such sillyness creeps into their soul. Later is the time to worry about integer v floating point operations not right at the start of learning and not in everyday programming. The language should take care of the messy things in life and if you don't agree with this there is always assembler waiting for your return.

In theory JavaScript would not make a fuss about any form of representation of data. JavaScript does treat the Number 1 and the String "1" as being very similar and in many cases they can be used interchangeably. This too can cause problems, but again it is an initial simplification and another important one for the beginner. If you think that explaining the difference between float and int to a beginner is difficult then you aren't going to want to go into 1 is not the same as "1". Again the representation of data is not something that a language should force you to consider every time you write a simple instruction. The point of a high level language is to take away as many of the low level concerns as possible and this is something that a lot of modern language have forgotten or sacrificed in the name of strong data typing.

You can dynamically create properties on Number objects as you can on any object and this can be something of a shock if you haven't encountered it before.

Of course, you don't have to write new Number() to create a Number object you can simply write its value, as in:

var myObject=3;

Now here we hit a snag - primitives.

The Primitive Problem

The idea that everything in JavaScript is an object is an ideal - and one not quite lived up to.

For efficiency reasons when you make use of a Number literal like 3 JavaScript doesn't create a Number object. It stores the 3 as a primitive data value.

The same is true of String literals like "ABC" and of boolean, null and undefined - all of which will be described later. What matters at the moment is that idea that there are types of data that are not stored as objects for efficiency reasons.

That is

var myObject=3;

actually creates a primitive value and not an object.

However JavaScript does its best to pretend that myObject is a Number object.

If you try to make use of a property of the Number object like

myObject.toString()

then JavaScript will oblige and convert the primitive value to a Number object and call the method

This automatic conversion is called boxing and the problem is that for efficiency JavaScript immediately unboxes a primitive value. This doesn't matter when you are trying to make use of built in properties but if you try to add a property it will be immediately lost.

If you want to make use of custom properties on numbers you have to explicity box the value using the Number constructor as in the examples given earlier.

In practice this doen't have any real impact on what you want to write because you don't often want or need to add custom properties to the built in objects.

To be clear:

JavaScript's primitive data types behave like objects that you cannot add properties to - that is they cannot be customized.

If you create the data type using say new Number then you get a complete object that you can use and customize.

There is also an interesting extra problem in that if you try to use a property on a numeric literal using the "dot" notation - it doesn't work. The reason is that JavaScript interprets the dot as a decimal point. So you have to write not

3.toString();

but

(3).toString();

or

3["toString"];

These exceptions are a shame because they spoil the deep principles.

Expressions and Immutability

One of the main tools of any programming language is the expression.

An expression takes data and combines it to produces new data.

For example, an arithmetic expression takes numbers and combines them to make new numbers. The ways in which the data can be combined takes the form of different operators. So arithmetic expressions have the addition operator and multiplication and so on.

For example:

2+3*4

is an expression that combines 2, 3 and 4 and produces a new value of 14.

When you think of expression in JavaScript you are encouraged to think of the operators as working with objects to create new objects.

For example:

2+3*4

combines three Number objects with values 2, 3 and 4 and creates a new Number object with the value 14.

In this sense you can imagine that the String and the Numeric objects are immutable - they don't change their values they are simply used within expressions to create new objects with different values.

The fact that an expression always creates a new object is a natural idea that explains all sort of minor behavior in JavaScript.

You will find that myObject2 has a value of 4 but it doesn't have a myProperty i.e. it is undefined.

The reason is that the arithmetic expression generates a new Number object that doesn't have a myProperty unless you go to the trouble of recreating it.

That is expressions that combine objects always create a new object.

Of course there is the complication of primitive data but in the main you can ignore it. The simple reason is that a primitive data value behaves as if it has only the default properties of the object and so when you combine them in an expression you get something that has just the default properties. Once again it looks as if expression take in objects and spit out a new object - even with primitive values.

In short you can alway think of expressions as working with objects and creating a new object as the result.