Value and Reference Types

Variables come in two different types: value types and reference types. Boolean values and numbers are value-based types, whereas strings, objects, arrays, and functions are reference types. Let's look at the differences.

Value types occupy a fixed size in memory. A Boolean value for example only takes one bit. All numbers in JavaScript are 64-bit floating point numbers, so each number is represented by 8 bytes. A reference type variable holds a reference to the value whose length is not fixed and can be of any size

Another difference between value and reference types is that value types are copied, passed, and compared by value. Reference types, are copied, passed, and compared by reference, rather than by value. Let's look at value types first:

var x = 1;
var y = x;       
alert(x == y);    // => true
alert(x === y);   // => true
x = 6;    
alert(x);         // => 6  
alert(y);         // => 1
alert(x == y);    // => false
alert(x === y);   // => false

When variable y is assigned to x it copies its value and following the assignment any relationship between x and y is severed. So, changing the value of x has no impact on the value of y.

Consider this example where a reference type is copied:

var x = { make: "Toyota" };
var y = x;
alert(x == y);      // => true
alert(x === y);     // => true
x.make = "Ford";
alert(x.make);      // => Ford
alert(y.make);      // => Ford
alert(x == y);      // => true
alert(x === y);     // => true

Following the execution of the second statement in which x is assigned to y, y refers to the same object that x refers to. JavaScript does not create a new copy of that object. If you make any changes to the underlying object through x, you can see these changes through y and vice-versa.

String, Boolean, and Number

String type

A string represents an ordered sequence of zero or more 16-bit values. Each value typically represents a Unicode character. Unicode is designed to represent all of the characters found in all human languages.

A string is wrapped in either double or single quotes. Adding a single-quote character within a string that is delimited by double quotes is no problem; the same is true for adding a double-quote character in a single-quote delimited string. Adding a single quote in the latter requires an escape character before the single quote, like so \'. Other common escape characters include \n = newline; \r = carriage return; \t = tab, and \\ = backslash.

A string literal can be split across one or more lines by placing an escape character \ (called a continuation character) at the end of each line except the last one. The \ character does not become a part of the string literal. Here are some examples of string literals:

var s1 = "Don't ignore Peter's feedback";
var s2 = 'Don\'t ignore Peter\'s feedback';
var s3 = 'Andrew Fuller\n Bob Springsteen';
var s4 = "Andrew Fuller, \
Bob Springsteen, \
Helena Williams";

Note that using the continuation character is generally not recommended.

Here are some other string members you frequently use: length, and charAt.

var s = "Paris, London, Amsterdam";
alert(s.length);              // => 24
alert(s.charAt(0));           // => P. First character
alert(s.charAt(s.length-1));  // => m. Last character

And here are some additional frequently used string methods: indexOf, lastIndexOf, toLowerCase, substring, replace, and split.

var s = "Paris, London, Amsterdam";
// Gets position of first 'a', returns 1
// Gets position of first 'a' starting at 3, returns 22
alert(s.indexOf("a", 3));     
// Gets position of last 'o', returns 11
// Converts string to lower-case
// Gets substring starting from the 15th character to the last,
alert(s.substring(14, s.length)); 
// Replaces "London" with "Berlin"
alert(s.replace("London", "Berlin"));   
// splits into an array of substrings using ", " separator
alert("Array: " + s.split(", ")); 

When comparing two strings they are considered equal when they have the same length and the same sequence of characters in corresponding positions.

var str1 = "Hello World";
var str2 = "Hello" + " World";
alert(str1 == str2);      // => true
alert(str1 === str2);     // => true

JavaScript strings are immutable

When we say that strings are immutable it means that once created, the contents of a string is of fixed length and cannot be modified. String may appear mutable when you work with them but they are not.: they are immutable internally. JavaScript does not offer any method or property that lets you alter the contents of a string value.

Again, modifying the string may appear to work, but in fact, a new string is generated. In the following example, b is referencing the same string as a. However, when modifying the underlying string through the b reference, a new string is created internally and its reference is assigned to b without affecting the original string referenced by a.

var a = "Hey";
var b = a;
b += ", what's up";
alert(b);            // => Hey, what's up
alert(a);            // => Hey

String methods like replace and toLowerCase appear to alter the string on which they operate, but they also return new strings.

Boolean type

The Boolean type has two literal values: true and false. Note that true and false are language keywords and are not the same as 1 and 0.

All types of values in JavaScript have Boolean equivalents. An empty string, null, undefined, NaN, 0, -0, and false itself evaluate to the Boolean value false. All these types and their values are referred to as falsy. On the other hand, a non-empty string, any non-zero number including Infinity, any object, and true itself evaluate to the Boolean value true. These types and their values are referred to as truthy. Although truthy and falsy are unofficial terms, they are widely used in the JavaScript community.

JavaScript has a special Boolean casting function that is used to convert a value into its Boolean equivalent – essentially determining whether the passed in expression is truthy or falsy.

var empty = "";
alert(Boolean(empty));            // => false
var nonEmpty = "JavaScript is cool!";
alert(Boolean(nonEmpty));         // => true

Automatic conversions to Boolean equivalents are common in conditional statements.

var car = { make: "Toyota" };
var display = true;
if (car && display) {        // => true
car = null;
if (car) {                  // => false
   alert("drive my car");

The first if statement returns true and therefore the alert displays. The second if-statement returns false and does not get executed.

String, Boolean, and Number properties are read-only

Variables of type string, number, and Boolean have properties and methods, but they are not objects. When you read a property or method from these types, JavaScript creates a temporary object, called a wrapper object, by calling the String(), Number(), or Boolean() constructor behind the scenes. Note that you can also explicitly call these constructor functions and create wrapper objects.

var message = "Hello World";
message.howlong = message.length;  // => sets property on object
alert(message. howlong);           // => undefined

When the second statement is executed, JavaScript creates a temporary String wrapper object. Then it adds a user-defined property called howlong on it, sets its value, and subsequently discards that object. This shows that String objects are not true objects because they do not accept new properties.

In summary, you cannot set properties to numbers, strings, or Booleans; any modification on the wrapper objects is not permanent.

Number-String conversions

JavaScript offers three ways to explicitly convert a string to a number. They are the Number constructor function, parseFloat, and parseInt. The latter two functions have some special behavior. Here is an example using the Number constructor function which takes a string argument:

var num = Number("1.73");     
alert(num);                     // => 1.73

The parseFloat function converts strings to floating point numbers. It ignores any non-numeric values that appear after numeric characters:

alert(parseFloat("1.73"));      // => 1.73 
alert(parseFloat("USD 1.73"));  // => NaN
alert(parseFloat("1.73 USD"));  // => 1.73

The parseInt function converts string to integer values. It also ignores any trailing non-numeric values:

alert(parseInt("1.73"));        // => 1, rounded down
alert(parseInt("USD 1.73"));    // => NaN  
alert(parseInt("1.73 USD"));    // => 1 
alert(parseInt("0x10"));        // => 16.  interpreted as hex 

Here are some additional conversion methods: parseInt also lets you specify the base of the number. If you want JavaScript to treat your numeric string as base 10 number, pass 10 as the second parameter to parseInt(). Pass 8 if the string is an octal number.

alert(parseInt("1.73", 10));    // => 1
alert(parseInt("10", 16));      // => 16
alert(parseInt("111", 2));      // => 7  
alert(parseInt("16", 8));       // => 14

When reporting monetary values, you are likely to perform number-to-string conversions. In the output string, you may like to standardize the number of decimal places by rounding the trailing digits or padding with zeros. The Number object offers methods that you can use to convert numbers to strings. For example, the toFixed method converts it to a string while keeping a number of decimals.

var num = 7.679;
alert(num.toFixed(0));     // => "8" rounded to nearest whole number
alert(num.toFixed(2));     // => "7.68"
alert(num.toFixed(4));     // => "7.6790"

Here are two additional conversion methods: toPrecision and toExponential.

var num = 17305.73;
alert(num.toPrecision(3));      // => "1.73e+4"
alert(num.toPrecision(5));      // => "17306"
alert(num.toPrecision(6));      // => "17305.7"
alert(num.toPrecision(8));      // => "17305.730"
alert(num.toExponential(1));    // => "1.7e+4"
alert(num.toExponential(3));    // => "1.731e+4"

JavaScript Math Object

For mathematical computations you use the Math object. There is no need to create an instance of Math to access its properties and methods because it is a static object. You simply use the Math object directly and call its method or property names. Below are max, min and abs methods:

alert(Math.max(1, 2));       // => 2
alert(Math.min(1, 2));       // => 1
alert(Math.abs(-2));         // => 2

Next are some trigonometry related items: the constant PI, and sin and cos.

alert(Math.PI);                          // => value of pi
alert((180/Math.PI) * Math.sin(1));      // => 90 (degrees)
alert((180/Math.PI) * Math.cos(0));      // => 90 (degrees)

Finally some rounding methods:

alert(Math.round(Math.PI)); // => 3, round up/down to nearest whole nbr
alert(Math.floor(9.69));    // => 9, round down to nearest whole number
alert(Math.ceil(9.69));     // => 10, round up to nearest whole number

JavaScript Date Object

To perform date and time calculations you use the Date object. The Date object holds a date as the number of milliseconds that have passed since Jan 1 1970 12:00 AM UTC. If you create a new Date object it will be set to the current date and time in the browser.

var current = new Date();    
alert(current);                // => current date and time

The time zone is determined by the system settings. In the example below, let's assume that the time zone where this code is run is set to Paris i.e. UTC + 1:00. Depending on your timezone your results will differ.

// => Jan 02 2011, 6:55:42 PM local time
var date = new Date(2011, 0, 2, 18, 55, 42);   
alert(date.getDay());        // => 0.  0–Sunday, 1–Monday, and so on
alert(date.getDate());       // => 2.  2nd day of the month
alert(date.getMonth());      // => 0.  0–January, 1–February, and so on
alert(date.getFullYear());   // => 2011.
alert(date.getUTCHours());   // => 17. Paris is 1:00 hour ahead from UTC

The difference between two dates is returned in milliseconds.

// => Jan 01 2011 12:00:00 AM local time
var from = new Date(2011, 0, 1);             
// => Jan 02 2011, 6:55:42 PM local time
var to = new Date(2011, 0, 2, 18, 55, 42);   
var timeElapsed = to - from;      
alert(timeElapsed);          // => 154542000 milliseconds

Here are examples of formatting date and time. Please note that your returns will differ depending on your timezone:

// => Jan 02 2011, 6:55:42 PM local time
var date = new Date(2011, 0, 2, 18, 55, 42);   
alert(date.toString());           // => Sun Jan 2 18:55:42 CST 2011 
alert(date.toDateString());       // => Sun Jan 2 2011
alert(date.toTimeString());       // => 18:55:42 CST
alert(date.toLocaleDateString()); // => Sunday, January 02, 2011
alert(date.toLocaleTimeString()); // => 6:55:42 PM
alert(date.toUTCString());        // => Mon, 3 Jan 2011 00:55:42 UTC

Be careful when you enter an invalid date like January 32, 2011. In most of the browsers like IE, Firefox, it is silently changed to February 1.

alert(new Date(2011, 0, 32));          // => Feb 1, 2011