© Russ Ferguson and Keith Cirkel 2017
Russ Ferguson and Keith CirkelJavaScript Recipes10.1007/978-1-4302-6107-0_1

1. Working with JavaScript Datatypes

Russ Ferguson and Keith Cirkel2
(1)
Ocean, New Jersey, USA
(2)
London, UK
 
Electronic supplementary material
The online version of this chapter (doi:10.​1007/​978-1-4302-6107-0_​1) contains supplementary material, which is available to authorized users.

Assigning Variables with the var Statement

Problem

When programming (just like in algebra), you need to be able to assign a variable piece of data to a keyword that you can reference in your code, for example x = 5.

Solution

With JavaScript, variable assignment needs to be declared using a keyword, which helps to determine the behavior of a variable. The most common way to do this is with the var statement. When defining a variable, one must use the var statement to tell JavaScript you are about to declare one or more variables.

The Code

var a; // The variable "a" has been declared
var a, b; // Both the variable "a" and the variable "b" have been declared.
var a, b, c, d; // The 4 variables; "a", "b", "c" and "d" have all been declared.
var a = 1, b; // The variables "a" and "b" have been declared, and variable "a" has been assigned the number 1 and "b" is undefined.
var a = 1, b = 2; // The variables "a" and "b" have been declared, variable "a" is assigned to the number 1, and "b" is assigned to the number 2
Listing 1-1.
Assigning Variables with the var Statement

How It Works

The JavaScript interpreter will see the var keyword, followed by a set of variable names, with optionally assigned values. It knows this is a VariableDeclaration statement, and it will declare those variables, then assign them. You can now continue to use the variable names and do not have to use their values. This is very similar to how algebra works; for example, you may say a = 5, b = a/2. You’re assigning a to 5 and assigning b to half of a, which is half of 5, so b becomes 2.5. You would do this almost identically in JavaScript, but simply add the var keyword and end with a semicolon : var a = 5, b = a/2;

Solving Errors with Variable Names

Problem

You attempted to declare a variable, but during runtime your code throws an Error, not letting you assign that variable name. You are presented with one of the following errors :
SyntaxError: Unexpected token <name>
SyntaxError: Unexpected number
SyntaxError: Unexpected string
SyntaxError: Unexpected reserved word
SyntaxError: missing variable name
SyntaxError: <name> is a reserved identifier
SyntaxError: Use of reserved word '<name>'
SyntaxError: Expected an identifier but found '<name>' instead
SyntaxError: The use of a keyword for an identifier is invalid
SyntaxError: Expected identifier
SyntaxError: Expected string '<name>'
SyntaxError: Expected number '<name>'
SyntaxError: Expected an identifier but found '<name>' instead

Solution

Variable names have a strict set of rules. You must not pick a variable name that is a keyword (these are words already used in the language) or a reserved word (these are words which are reserved for future use), or literal values (the value of a literal, such as true or null). The full list of reserved words is shown in Table 1-1.
Table 1-1.
Reserved Keywords in JavaScript
break
case
catch
class
const
continue
debugger
default
delete
do
else
enum
export
extends
false
finally
for
function
if
implements
import
in
Infinity
instanceof
interface
let
NaN
new
null
package
private
protected
public
return
static
super
switch
this
throw
true
try
typeof
undefined
var
void
while
with
yield
In addition to having a set of reserved words, JavaScript has some other rules around variable naming. They can include numbers, but cannot start with a number (this would confuse them with number literals, discussed later in this chapter in longer detail in Chapter 4), they also cannot contain any spaces. Generally speaking though, the names of JavaScript variables are quite flexible—perhaps too flexible, for example you could use “ A315054_1_En_1_Figa_HTML.gif” as a variable name (but please don’t). As a good rule of thumb, it is recommended you name your variables using the English Alphabet (A-Z), avoid the use of numbers, and use camelCasing for multiple word variables.
camelCasing is where each word is given a capital letter, except for the first word. The rest of the letters are lowercase. For example if you had a variable called Number of Days, in camelCase that would be numberOfDays. As another example, a variable called Cache Control would be cacheControl. Examples of camelCasing in the real world are brands like iPhone or eBay.
While you should use camelCasing for variable names, there are a few exceptions to this best practice rule. One is with constructors (functions that create new objects with the new keyword), which should use TitleCase (camelCase but with a capital first letter). Another is constants, which should be UPPERCASE_WITH_UNDERSCORES. Of course, all of these are best practices, and so can be disobeyed, but it is strongly recommended to use them.
It is very important to note that JavaScript variable names are case sensitive, that is byteLength is a different variable than ByteLength, which is a different variable than BYTE_LENGTH and so on. This is why it is vitally important to stick to a good naming convention for your variables. It can be very easy to get caught by inconsistent naming schemes, and spend hours debugging code only to find your variable was missing an uppercase character.

The Code

Listing 1-2. Rules for Variable Names
var break = 3; // Raises a `SyntaxError: Unexpected token break`
var brake = 3; // This is fine, because "brake" is not a Reserved Keyword
var π = 3.1415926; // This works, but can be irritating to use
var A315054_1_En_1_Figa_HTML.gif = eval; // This works, but can be irritating to use
var numberOfDays = 3; // This is an ideal, readable camelCase variable name that isn't a reserved word!

How It Works

JavaScript needs to impose limits on variable names, otherwise you could accidentally override language features and functions . Some other languages, such as PHP, get around this by forcing you to prefix every variable name with a $ sign; however, this becomes very limiting, so most languages including JavaScript simply disallow a small subset of variable names. Some reserved words are not used in the language today, such as enum, but are intended to be included in the future and so become reserved as placeholders, to prevent use.

Solving Reference Errors When Declaring Variables Inside a Function’s Scope

Problem

You have attempted to declare a variable inside a function’s scope, but during runtime your code throws a ReferenceError , not letting you use that variable, or if you’re not using strict mode, your variables are undefined. Alternatively you’ve tried to assign a variable without using the var keyword. You have been presented with one of the following errors :
ReferenceError: <name> is not defined
ReferenceError: assignment to undeclared variable <name>
ReferenceError: Can't find variable: <name>

Solution

JavaScript features something called “variable scopes .” Every time a variable is declared, it is given a “scope.” Variables declared with the var keyword can only be used in the function containing them—that is to say, they are given the scope of that function. There is an additional global scope, which contains all variables that aren’t contained in functions. Variables cannot be used outside of their scope. The solution is to move them to a higher scope, i.e., out of the function. Look closely at the following examples.

The Code

function foo() { // This is a Function, which var a is wrapped in
    var a = 3; // declare variable `a` inside foo()s scope.
}
console.log(a); // Raises `ReferenceError: a is not defined` (in strict mode, returns undefined otherwise)
foo();
console.log(a); // Raises `ReferenceError: a is not defined` (in strict mode, returns undefined otherwise)
var a = 3; // declare variable `a` in the global scope
function foo() {
    a = 4; // reference the variable `a` from the global scope
}
console.log(a); // logs 3, because the variable `a` was declared in the global scope, outside of any function scopes
foo();
console.log(a); // logs 4, because the function foo(); took the globally scoped `a` and changed it to 4
var a = 3; // declare variable `a` in the global scope
function foo() {
    var a = 4; // declare variable `a` in foo()s scope, without touching the globally scoped `a`
}
console.log(a); // logs 3, because the variable `a` was declared in the global scope, outside of any function scopes
foo();
console.log(a); // logs 3, because foo() declared its own `a` variable inside its own scope, and so modified the variable belonging to foo, not the global one
Listing 1-3.
Global Variables and the Notion of Scope

How It Works

Each function is given a “scope” or “sandbox,” so that it can manage its own variables without overriding or leaking its own variables into the global scope. Variables inside of a function’s scope cannot be used outside of the function, or in other functions; this is very useful because it avoids conflicting variable names. If my function has a variable named length and so does yours, we don’t want to override each others variables with different values, so they are scoped for protection.
Function scoped variables also have an important use—they only live as long as the function runs, meaning they are cleaned from memory as soon as the function finishes. This is a very useful trick but can trip a lot of beginners up, so be careful and think hard about where you use your variables. The basic principle of scoping is similar to a “tree.” It begins with the root scope, and with each new function, a new “function scope” branch is created , functions inside functions are branches of branches, and the whole thing goes on indefinitely. Consider the code in Listing 1-4.
function foo() {
    var a = 1;
    function bar() {
        var b = 2;
        function baz() {
            console.log(a, b);
        }
    }
}
function bing() {
    var a = 1;
    function boo() {
        console.log(a);
    }
}
Listing 1-4.
A “Functional Scope” Example
This code can be expressed as a tree of scopes (see Figure 1-1).
A315054_1_En_1_Fig1_HTML.jpg
Figure 1-1.
A “functional scope” tree of Listing 1-4
From the Figure 1-1, you can see the global scope holds the two functions: foo() and bing() . foo() has its own scope, which holds the a variable and the bar() function. bar() has its own scope, containing b and baz(). bing() has its own scope, containing a and boo().
It is important to note that the scope has an upwards chain, meaning baz() can access its sibling, b, as well as its parents bar(), a, and foo(). Similarly, boo() can access its sibling a and its parent bing(). However, this chain does not flow in the opposite direction, so foo() cannot access bar()’s scope of b and baz() (it can, of course, access its own scope of a and bar()). This is a pretty contrived example, but real-world codebases can have much larger and more complex scope chains than this.

Assigning Variables with the Let Statement

Caution
The let statement is an ECMAScript 6 (ES6, the new standard of JavaScript) feature. Older browsers still in use, such as Internet Explorer 10 and below or Safari 7 and below, do not support this feature (they work with the older ECMAScript 5 or ES5 standard).

Problem

When using a variable, you want its life to be shorter than the functional scope. For example, you’d like the variables life to exist within an if statement.

Solution

Not only does JavaScript have a “functional scope,” it also has another level of scope, called “block scope .” Block scoped variables offer the same semantics as function scoped variables, in that they are locked to a block, they cannot be accessed outside of a block , and they are removed from memory as soon as the block finishes executing. A block is delimited by braces ({...}), and each new set of braces is a new block scope.

The Code

let a = 4; // The variable "a" has been declared and assigned to `4`
{
    let b = 2; // The variable "b" has been declared and assigned to `2`
    console.log(b); // Logs 2
}
if (a === 4) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
    let a = 1; // The variable "a" has been redeclared in this block scope (the braces)
    console.log(a); // Logs 1
}
console.log(b); // Raises a ReferenceError in strict mode, or logs undefined
console.log(a); // Logs 4, the `let a = 1` in the block scope above was only associated with that block scope
Listing 1-5.
Assigning Variables with the Let Statement

How It Works

The JavaScript interpreter will see the let keyword, followed by a set of variable names, with optionally assigned values. It then creates each of these keywords as a variable, for the life of the “block scope .” It follows the same semantics as var, with the exception that it is tied to the block scope, not the function scope. Let variables also have another trick up their sleeve. When used in an if statement, or a for or while loop, the let variable is bound to the attached block, even though it is not inside the block itself. Take, for example, the code in Listing 1-6.
for (let i = 0, i < 4; ++i) {
    console.log(i); // Logs 0, 1, 2, and 3
}
console.log(i); // Raises a ReferenceError in strict mode, or logs undefined
// Swap two variables:
var a = 1, b = 2;
{
    let temp = a;
    a = b;
    b = temp;
}
console.log(a, b, typeof temp); // logs '2, 1, undefined'
Listing 1-6.
Letting Variables Block
This is useful because it provides another scoping layer for variables. Variables using the var keyword are accessible to the whole function’s scope. For temporary variables, such as the i in a loop (which get thrown away as soon as the loop is done) the variable would normally hang around until the end of the function’s life, which can be a nuisance. With a let variable this is very effectively solved, as the let variable only exists for the life of the loop, and is then nicely cleaned up. You can also apply this by using blocks to encapsulate temporary variables, such as the second example in Listing 1-6.

Assigning Constants with the Const Statement

Caution
The const statement is an ECMAScript 6 (ES6 , the new standard of JavaScript) feature. Older browsers still in use, such as Internet Explorer 10 and below, Safari 7 and below, and Firefox 13 and below do not support this feature (they work to the older ECMAScript 5, or ES5 standard).

Problem

You want to use a variable, but you want to ensure that it is not overridden by a new value later on in the code.

Solution

The var and let statements certainly have their uses, but both are vulnerable to being unexpectedly overridden in the life of running code. Luckily, the const statement provides you with a way of declaring a variable that is immutable; that is, it will always be assigned to its initial value, and cannot be changed, cannot be “mutated”. It is a constant. One of the things to keep in mind is that objects can be updated. Constants only work with primitive values .

The Code

var A = 3;
let B = 3;
const C = 3;
A = 4; B = 4; C = 4;
console.log(A, B, C); // Logs 4, 4, 3. `C`s value doesn't change, as it is a `const`.
Listing 1-7.
Assigning Constants with the Const Statement

How It Works

The JavaScript interpreter will see the const keyword, followed by a set of constant names, with assigned values , and set those values to the constants as read-only (immutable) . It follows the same semantics as let, including using block scoping just like let, with the exceptions that it can never be reassigned to a new value (it is immutable), and that it must be initially assigned to a value.
It is important to note that constants can never be declared without a value; this will cause a SyntaxError . Constants must always have a value assigned to them upon declaration.
const a; // Raises a SyntaxError (some browsers which have misinterpreted the ES6 spec may not raise this)
const a = 3; // Works as expected
Listing 1-8.
Attempting to Declare Constants Without Assigning Them
The spec is somewhat unclear about what precisely to do when a const is declared but not assigned, as a result, some browsers will not raise the SyntaxError, and the constant is permanently set to undefined, which is obviously pretty useless.

Creating and Using Literals

Caution
Template string literals are an ECMAScript 6 (ES6, the new standard of JavaScript) feature. Older browsers still in use, such as Internet Explorer 11 and below, Safari 7 and below do not support this feature (they work to the older ECMAScript 5, or ES5 standard). In fact, at the time of writing only the Taceur Compiler tool could support template string literals. Check http://kangax.github.io/es5-compat-table/es6/ for the current compatibility charts.

Problem

You want to create literal values of different types in JavaScript ; for example, you want to create a piece of text (string), or perhaps a number, or even a list of items (an array).

Solution

Literals are types of data that can be defined without explicitly creating some kind of object or instance . A literal can be a string (i.e., a piece of text), a decimal (base-10, 0-9), binary (base-2, 0-1), hexadecimal (base-16, 0-F), or octal (base-8, 0-7) number, a Boolean (true or false), an array (a list of other literals), an object (a named list of other literals), a regular expression (a complex text matching function), a function (a piece of code that can be repeatedly called), a template string (similar to a string, but replaces variable names with their values), as well as some standalone “primitive” values such as null and undefined. Each literal has a unique piece of syntax to denote its type, with perhaps the exception of decimal numbers.

The Code

'this is a string'; // A String literal (using Single Quotes)
"this is another string"; // A String literal (using Double Quotes)
true; // A Boolean literal
false; // A Boolean literal
3; // A Number literal
3.1415926; // Another Number literal
0b0101; // A Binary Number literal
0xFFF; // A Hexadecimal Number literal
0o888; // An Octal Number literal
[]; // An (empty) Array literal
[ 1, 2, 3, ]; // An Array literal populated with 3 Number literals
[ 'hello', 'world']; // An Array literal populated with 2 String literals
{}; // An (empty) Object literal
{ first: 1, second: 2 }; // An Object literal populated with 2 Number literals, named "first" and "second"
/abc/; // A Regular Expression literal
/^w{3,4}$/g; // A more complex Regular Expression literal
function () {}; // A Function literal
function foo() {}; // A named Function literal
null; // The null literal
undefined; // The undefined literal
`this is a template string`; // A Template String literal
`Hello #{name}
How are you?`; // A more complex Template String literal
Listing 1-9.
Literals

How It Works

The JavaScript interpreter will see each piece of unique syntax at the start of a literal; for example, a single/double quote for a string. It understands the specific rules around these and essentially creates that value as a literal instance of that type. The literals also borrow all properties from their “prototypes ,” for example everything you can do with new String('hello') you can also do with hello . Each of these literals can be assigned to a variable, or put inside an array or object. Each one has its own properties and attributes—you need to deal with each one in a different way. Chapters 3-15 guide you through how to utilize each of these types properly.

Creating Types Using Their Constructors

Problem

You want to be able to create literals more programmatically.

Solution

Some literals can also be created as instances from their constructor functions, with the new keyword. These instances allow for finer control of how they are created; however, it should be noted that some of these instances have very subtle differences to their literal counterparts. More about this later.

The Code

'hello'; // A String literal (using Single Quotes)
new String('hello'); // A String created from its constructor
[ 1, 2, 3 ]; // An Array literal with 3 Number literal values
new Array(1,2,3); // An Array created from its constructor
new Array(5); // An Array populated with 5 undefined values
/abc/; // A Regular Expression literal
new RegExp('abc'); // A Regular Expression created from its constructor
/^w{3,4}$/g; // A more complex Regular Expression literal
new RegExp('^\w{3,4}$', 'g'); // A more complex Regular Expression literal created from its constructor
function () { return 1 }; // A Function literal
new Function('return 1'); // A Function created from its constructor
{}; // An empty Object literal
new Object(); // An empty Object created from its constructor
Listing 1-10.
Literals versus Their Constructors

How It Works

JavaScript contains constructor functions, which relate to each literal. Some of these allow you to invoke them manually, which can be useful for creating these objects programmatically , especially arrays and regular expressions. You should be aware that there are subtle differences between creating instances from the constructor functions and their literal counterparts, and you should always use the literal notation over constructors, unless you have a very specific reason for using the constructors. Constructors with the new keyword will actually create objects of that particular datatype, which is different than how literals work. This means, for example, typeof new String("hi") is equal to object, while typeof "hi" is equal to "string". While the Boolean(0) or Boolean("") will equal false, Boolean(new Number(0)) or Boolean(new String("")) will equal true. More details about the differences between these are featured in the later chapters for each datatype.

Determine If a Variable Has Been Defined Using an Equality Operator

Problem

You want to determine if the variable you have created is defined.

Solution

A variable is undefined when it has been declared but has not been assigned a value, or the assigned value is the undefined literal. Just imagine that when you are declaring variables that you’re making an entry in a dictionary. Every word (variable) that you use in JavaScript is undefined until you assign it a definition or value. The same holds true for function return values: if a function has no return statement, or if the return statement is used without specifying a value (i.e., return;), then the return value has not been defined and will therefore be the undefined literal.

The Code

var a; // The Variable "a" has been declared but it
       // hasn't been assigned a definition.
var b = 5; // The variable "b" has been declared and
           // assigned the number 5 as it's definition.
if (a === undefined) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
   console.log("Variable 'a' is undefined");
} else {
   console.log("Variable 'a' is defined");
}
if (b === undefined) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
   console.log("Variable 'b' is undefined");
} else {
   console.log("Variable 'b' is defined");
}
Listing 1-11.
Determining if a Variable Has Been Defined Using an Equality Operator
The output is:
Variable 'a' is undefined
Variable 'b' is defined

How It Works

Variable a has been declared but has not been assigned a value (a definition). A variable that has not been assigned a value is automatically assigned the undefined literal. Variable b has been declared and is defined as the numeric value 5. The first if statement compares variable a to the undefined primitive value. Because variable a has not been defined, the comparison is true and the message Variable 'a' is undefined is displayed. On the other hand, variable b was defined so the same comparison to the undefined primitive value fails and the message Variable 'b' is defined is displayed.

Determining If a Variable Has Been Declared Using typeof( )

Problem

You test a variable to see if it is undefined using an equality operator and your script throws an exception because the variable has never been declared.

Solution

The typeof operator can be used to determine if a type is undefined. It returns a string indicating the type of the operand, but does not throw an error if the variable has never been declared.

The Code

// The declaration for variable a is commented out,
// therefore a has not been declared.
var a, b = 4;
if (typeof a === 'undefined') { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log("Variable 'a' is undefined");
}
if (typeof b === 'undefined') { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log("Variable 'b' is undefined");
}
Listing 1-12.
Determining If a Variable Has Been Declared Using typeof
The output is:
Variable 'a' is undefined

How It Works

Using the typeof operator is useful if a variable’s declaration status is not known, or for checking its value if it has been declared. By asserting if a variable is undefined using typeof variable === 'undefined', you can safely see if a variable has a value, without causing a ReferenceError.

Determining If a Function Defines and Returns a Value

Problem

You are using a function to perform a task and need to determine if the return value has been defined, once the operation is complete.

Solution

All functions return a value whether the original developer intended it or not. If a value was defined and passed back to the function caller, it can be assigned to a variable or used directly. A function returns undefined if a value was not returned, or the return statement inside a function is empty.

The Code

// A function with an empty return-statement
// returns undefined
function function1() {
         return;
}
// A function with no return-statement
// returns undefined
function function2() {
}
function function3() {
         return 2 + 2;
}
function function4() {
         return true;
}
function function5() {
         return {};
}
var fn1 = function1();
console.log("Function1 returns: " + fn1);         // undefined
var fn2 = function2();
console.log("Function2 returns: " + fn2);         // undefined
var fn3 = function3();
console.log("Function3 returns: " + fn3);         // 4
var fn4 = function4();
console.log("Function4 returns: " + fn4);         // true
var fn5 = function5();
console.log("Function5 returns: " + fn5);         // Object{}
// Test the return value of function1
if ( function1() === undefined ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log( "Function 1 returns undefined." );
}
else {
           console.log( "Function 1 returns a value other than undefined." );
}
// Test the return value of function2
if ( function2() === undefined ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log( "Function 2 returns undefined." );
}
else {
           console.log( "Function 2 returns a value other than undefined." );
}
// Test the return value of function3
if ( function3() === undefined ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log( "Function 3 returns undefined." );
}
else {
           console.log( "Function 3 returns a value other than undefined." );
}
// Test the return value of function4
if ( function4() === undefined ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log( "Function 4 returns undefined." );
}
else {
           console.log( "Function 4 returns a value other than undefined." );
}
// Test the return value of function5
if ( function5() === undefined ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log( "Function 5 returns undefined." );
}
else {
           console.log( "Function 5 returns a value other than undefined." );
}
Listing 1-13.
Determining If a Function Defines and Returns a Value
The output is:
Function1 returns: undefined
Function2 returns: undefined
Function3 returns: 4
Function4 returns: true
Function5 returns: [object Object]
Function 1 returns undefined.
Function 2 returns undefined.
Function 3 returns a value other than undefined.
Function 4 returns a value other than undefined.
Function 5 returns a value other than undefined.

How It Works

Five functions are defined; the first two return undefined . Function 1 explicitly returns undefined by using an empty return statement. Function 2 returns undefined implicitly by not using the return statement at all. Just as we can test the value of a variable, we can test the return value of a function using an equality operator. In many cases, functions’ return values can be treated like variables. A function’s return value can be printed to the console or used otherwise . Note that because a function is already declared, its return value is implicitly declared too—so checking the return value of a function will never raise ReferenceError, unlike variables, which may if they’re undeclared.

Determining If a Defined Variable Has a Value Using Equality Operators

Problem

You know a variable has been previously defined but aren’t certain if its value is null or if it has another value.

Solution

You can use the equality operators to test for null values just like you test for undefined variables. null is an object and has only one value in JavaScript, null. A variable that is assigned null contains no valid data of the types Array, Boolean, String, Number, Date, Template String, or Object. When you want to declare a variable and initialize it, but do not want to give it value, just assign it the value null. This is useful if you need to declare a variable now but must wait for an operation to complete before assigning a value to the variable. Such cases may include number crunching or waiting for a response from a server. If the operation fails, the variable will remain null and this failure can be detected with code.

The Code

// myvar is undefined
var myvar = undefined;
if ( myvar === undefined) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log("myvar is undefined");
}
if ( myvar === null) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log("myvar is null");
}
// myvar is null
var myvar = null;
if ( myvar === undefined) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log("myvar is undefined");
}
if ( myvar === null) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log("myvar is null");
}
var myvar = null;
// Determine if myvar is null using the bang (!) operator
if ( !myvar ) {
           console.log("The variable myvar is null or undefined");
} else {
           console.log("The variable myvar is not null or undefined");
}
Listing 1-14.
Determining If a Defined Variable Has a Value Using Equality Operators
The output is:
myvar is undefined
myvar is null
The variable myvar is null or undefined

How It Works

Because null is falsey (it is equivalent to false when coerced to a Boolean), we can determine if a variable is null by using the bang operator (!) to perform a logical NOT operation. In other words , we’re asking if the variable myvar is “not false,” meaning true. This is the simplest (shortest code) technique for determining if a variable is null.

Performing Operations If a Defined Variable Has a Value

Problem

You need to perform different operations based on the value of a variable. You may need to test that a variable is strictly equal, simply equivalent, or strictly not equal to a value.

Solution

As we have done in previous sections, we will use comparison operators to detect the value of a variable and then branch to specific code blocks based on the value of the if statements.

The Code

var myNumber = 10;
// Determine if myNumber is equivalent to the number 10
if ( myNumber === 10 ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
         console.log( "myNumber equals 10");
}
else {
         console.log( "myNumber is not equal to 10");
}
// Determine if myNumber is less than the number 10
if ( myNumber < 10 ) {
         console.log( "myNumber is less than 10");
}
else {
         console.log( "myNumber is equal to or greater than 10");
}
// Determine if myNumber is less than or equal to the number 10
if ( myNumber <= 10 ) {
         console.log( "myNumber is less than or equal to 10");
}
else {
         console.log( "myNumber is greater than 10");
}
// Determine if myNumber is greater than the number 10
if ( myNumber > 10 ) {
         console.log( "myNumber is greater than 10");
}
else {
         console.log( "myNumber is less than or equal to 10");
}
// Determine if myNumber is greater than or equal to the number 10
if ( myNumber >= 10 ) {
         console.log( "myNumber is greater than or equal to 10");
}
else {
         console.log( "myNumber is less than 10");
}
Listing 1-15.
Performing Operations If a Defined Variable Has a Value
The output is:
myNumber equals 10
myNumber is equal to or greater than 10
myNumber is less than or equal to 10
myNumber is greater than or equal to 10

How It Works

Flow control of a script is very important to all programmers. Most scripts except the simplest of examples will have flow control of some kind. This example uses if statements to compare a variable to a fixed numeric value. If the comparison is true, the first code block below the comparison is executed. If the comparison is false, that block is not executed , and the next block is compared. else blocks are executed if no other blocks in the whole if statement were true. We will take an in-depth look at expressions in Chapter 2.

What’s the Difference Between Null and Undefined ?

Problem

When working with an unfamiliar variable, you are uncertain if the variable is null or undefined and don’t know how to test the variable before working with it.

Solution

A variable is undefined only when the variable is declared but not assigned a value, or the variable has been explicitly assigned the undefined value. A variable is null only when it has been assigned the null value. This being the case, we can easily detect undefined and null variables as shown in the example. This makes null useful for explicitly representing a no-value variable, rather than a not-yet-defined variable, for example, in a function’s return statement.

The Code

var a;
var b = null;
if ( typeof a === 'undefined' ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
          console.log( "Variable a is undefined" );
}
if ( a === null ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
          console.log( "Variable a is null" );
}
if ( typeof b === 'undefined' ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
          console.log( "Variable b is undefined" );
}
if ( b === null ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
          console.log( "Variable b is null" );
}
Listing 1-16.
The Difference Between Null and Undefined
The output is:
Variable a is undefined
Variable b is null

How It Works

The typeof operator is used again as a more error-proof method of determining the type of a variable. The typeof operator returns a string label for the variable type. The operator will return the string undefined for any variable that is truly undefined.

Coercing a Boolean Variable Using the Boolean Constructor

Problem

There are many cases where you will need to coerce an existing value into a Boolean true or false value for use in an if statement or other condition statements .

Solution

Strings, numeric types, arrays, and objects can have an unlimited number of values, but the Boolean datatype can only have two: either true or false . A Boolean value indicates whether a condition, like those in an if statement, is true or not. The Boolean constructor can be used to convert any values passed into it to their Boolean equivalent.
The example in Listing 1-17 demonstrates coercion from various types into Boolean. Notice that we are not invoking a new Boolean—new Boolean()—we are instead using the Boolean constructor as a function— Boolean() —to coerce the given value into a Boolean primitive.

The Code

console.log( Boolean(-0) ); // logs false
console.log( Boolean(0) ); // logs false
console.log( Boolean(new Number(0)) ); // logs true
console.log( Boolean(1) ); // logs true
console.log( Boolean(NaN) ); // logs false
console.log( Boolean(-1) ); // logs true
console.log( Boolean(false) ); // logs false
console.log( Boolean(true) ); // logs true
console.log( Boolean(undefined) ); // logs false
console.log( Boolean(null) ); // logs false
console.log( Boolean(new String()) ); // logs true
console.log( Boolean("") ); // logs false
console.log( Boolean('a string') ); // logs true
console.log( Boolean("true") ); // logs true
console.log( Boolean("false") ); // logs true
console.log( Boolean(function () {}) ); // logs true
console.log( Boolean({}) ); // logs true
console.log( Boolean([]) ); // logs true
Listing 1-17.
Coercing a Boolean Variable Using a Boolean Constructor

How It Works

The Boolean constructor can take a single parameter and will convert it to a Boolean value internally based on the ToBoolean internal function , as part of the ECMAScript spec (specifically, section 7.1.2 of the ES6 spec, or 9.2 of the ES5 spec). If the value is 0, -0, null, false, NaN, undefined, or an empty string (''), the ToBoolean internal function will convert these to a value of false. The Boolean constructor , when used without new will simply reuse the underlying ToBoolean internal logic, as does the bang operator (!) and other logical operators, such as AND (&&) and OR (||).

Determining If a Boolean Variable Is Initialized

Problem

You need to test a variable to determine if it is a Boolean or other datatype and determine if the Boolean variable has been initialized.

Solution

Using the typeof operator, we can determine the datatype of a variable. If the variable is a Boolean value, typeof will return the string 'boolean'.

The Code

var a = Boolean(true);
var b = false;
var c = "";
var d = new Date();
if ( typeof a === 'boolean' ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log("a is a Boolean");
} else {
           console.log("a is not a Boolean");
}
if ( typeof b === 'boolean' ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log("b is a Boolean");
} else {
           console.log("b is not a Boolean");
}
if ( typeof c === 'boolean' ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log("c is a Boolean");
} else {
           console.log("c is not a Boolean");
}
if ( typeof d === 'boolean' ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
            console.log("d is a Boolean");
} else {
            console.log("d is not a Boolean");
}
Listing 1-18.
Determining If a Boolean Variable Is Initialized
The output is:
a is a Boolean
b is a Boolean
c is not a Boolean
d is not a Boolean

How It Works

The typeof operator returns the string value Boolean for Boolean objects. To determine if a variable is a Boolean , all we need to do is strictly compare the return value of the typeof operator to the string 'boolean'. Other datatypes, such as strings and numbers, return different strings that represent them.

Valid Representations of the False and True Values

Problem

You need to make a Boolean decision based on the value of a variable that is neither true nor false.

Solution

There are only two Boolean values: true and false. However, many different types such as numbers, strings, null, and undefined can be coerced to Boolean. if statements, switch statements, for statements, and while statements all coerce their given values to Booleans.

The Code

// If statements internally convert the given condition or value into Boolean values.
if (0) {
    console.log( "0 is true");
} else {
         console.log("0 is false");
}
if (-0) {
    console.log( "-0 is true" );
} else {
         console.log("-0 is false");
}
if (null) {
    console.log( "null is true" );
} else {
         console.log("null is false");
}
if (false) {
    console.log( "false is true" );
} else {
         console.log("false is false");
}
if (NaN) {
    console.log( "NaN is true" );
} else {
         console.log("NaN is false");
}
if (undefined) {
    console.log( "undefined is true" );
} else {
         console.log("undefined is false");
}
if ("") {
    console.log( "Empty String is true" );
} else {
         console.log("Empty String is false");
}
// Variable b holds the outcome of the comparison
// between Variable 'a' and the number 1.
var a = 1;
b = (a === 1);   // true
if ( b ) {
    console.log("Variable b is true");
} else {
    console.log("Variable b is false");
}
// Examples of conditional or comparative expressions
var c = 1 + 2;
var d = null;
var e = a - 3;
var f = undefined;
if (c) {
         console.log("Variable c is true");
} else {
         console.log("Variable c is false");
}
if (d) {
         console.log("Variable d is true");
} else {
         console.log("Variable d is false");
}
if (e) {
         console.log("Variable e is true");
} else {
         console.log("Variable e is false");
}
if (f) {
         console.log("Variable f is true");
} else {
         console.log("Variable f is false");
}
Listing 1-19.
Valid Representations of the False and True Values
The output is:
0 is false
-0 is false
null is false
false is false
NaN is false
undefined is false
Empty String is false
Variable b is true
Variable c is true
Variable d is false
Variable e is true
Variable f is false

How It Works

Every statement that expects a condition (if, switch, for, and while) will automatically coerce the given value into a Boolean (using the internal ToBoolean method described in Listing 1-14). If the Boolean value returned is false, the condition fails and the statement (if, switch, for, and while) is skipped. If the value is true then the block inside the statement is executed.

Coercing a String Using the String Constructor

Problem

You want to create a string representation of another value.

Solution

The string constructor takes a single parameter and will automatically convert that value into a string literal.

The Code

String("hello world"); // The String "hello world"
String(1); // The String "1"
String(false); // The String "false"
String(true); // The String "true"
String({}); // The String "[object Object]"
String([1,2,3]); // The String "1,2,3"
String(function foo() {}); // The String "function foo() {}"String(0b0101); // The String "5"
String(/abc/); // The String "/abc/"
String(undefined); // The String "undefined"
String(null); // The String "null"
// String casting can be overridden by providing the toString() method
String({ toString: function () { return 'hi!'; } }); // The String "hi!"
String({ toString: function () { return false; } }); // The String "false"
Listing 1-20.
Coercing a String Using the String Constructor

How It Works

Similarly to the Boolean constructor, the string constructor can also coerce values into its literal type. The ECMAScript spec contains an internal ToString function (ES6 section 7.1.12, ES5 section 9.8), which is used by the string constructor. It converts undefined to "undefined", null to "null", true to "true", false to "false" and number values to the string version of that number.
For other values, it checks to see if there is a toString method attached to the value. If there is one, it will use the resulting value, coerced as a string, meaning the string constructor will always return a string. Arrays have a toString function on their prototype which simply calls Array.prototype.join(',')—this is explained in Chapter 6. Using the toString method is a powerful feature of JavaScript, as it allows you to create your own objects, which can coerce to a string in a customized way.

Determining If a Variable Is a String

Problem

You need to test a variable to determine if it is a string or other datatype.

Solution

Using the typeof operator, we can determine the datatype of a variable. If the variable is a string value, typeof will return the string "string".

The Code

var a = String("I'm a String Object");
var b = "I'm a string literal";
var c = 7;
var d = new Date();
if ( typeof a === 'string' ) {
            console.log("a is a String");
} else {
            console.log("a is not a String");
}
if ( typeof b === 'string' ) {
            console.log("b is a String");
} else {
            console.log("b is not a String");
}
if ( typeof c === 'string' ) {
            console.log("c is a String");
} else {
            console.log("c is not a String");
}
if ( typeof d === 'string' ) {
            console.log("d is a String");
} else {
            console.log("d is not a String");
}
Listing 1-21.
Determining If a Variable Is a String
The output is:
a is a String
b is a String
c is not a String
d is not a String

How It Works

The typeof operator returns the value "string" for string objects and literals. To determine if a variable is a string, all you need to do is compare the return value of the typeof operator to " string ". Other datatypes such as objects and numbers return different strings that represent them.

Coercing a Numeric Value Using the Number Constructor

Problem

Sometimes you have numbers being represented as strings in your application. How can you convert these strings into actual number literals so you can use them effectively?

Solution

The number constructor takes a single parameter and will automatically convert a string parameter into a number.

The Code

var strNumber = "3.14159265";
var myNumber = Number(strNumber);
console.log("mynumber = " + myNumber);
console.log("mynumber type is " + typeof myNumber);
console.log("2 * mynumber = " + (2 * myNumber));
Listing 1-22.
Coercing a Numeric Value Using the Number Constructor
The output is:
mynumber = 3.14159265
mynumber type is number
2 * mynumber = 6.2831853

How It Works

The number constructor will attempt to convert its only parameter into a numeric value. If that is not possible , the number object will be initialized to NaN (Not a Number).

Creating a Numeric Value Using Number Literals

Caution
Binary and octal notation are ECMAScript 6 (ES6) features. Older browsers still in use, such as Internet Explorer 11 and below and Safari 7 and below, do not support this feature (they work to the ECMAScript 5, or ES5 spec).

Problem

Not all numeric values in your application will come from your user or external data. In many cases you will need to use literal or hard-coded mathematical expressions in your script.

Solution

JavaScript represents numbers using the double-precision 64-bit IEEE 754 floating-point standard. The JavaScript Number object represents all numbers as floating-point values, meaning there is no internal difference between Integers (whole numbers) and floating-point numbers.
Floating-point numbers contain a decimal portion and may be expressed in scientific notation. Also known as "E notation ," this represents "times ten raised to the power of". For example, 1.02e3 means "1.02 times 10 raised to the power of 3,” or 1020.
Numbers can be written in decimal , hexadecimal, binary, and octal. Hexadecimal and octal numbers can have negative values. Binary, hexadecimal, and octal numbers can only represent integer values; they cannot be written in E notation. When the JavaScript runtime finds one of these number literals, it will automatically convert it to the decimal, or base-10 representation (with no decimal places, of course).
Hexadecimal integers (referred to as base-16 numbers) are notated by prefixing them with a 0x. They can contain digits 0 through 9, and letters A through F only. The letters A through F represent 10 through 15 in decimal (Base-10). Using letters other than A through F will raise a SyntaxError.
Octal integers (referred to as Base-8 numbers) are notated by prefixing them with a 0o. They can contain digits 0 through 7 only. Using numbers outside of 0 through 7 will raise a SyntaxError.
Binary integers (referred to as Base-2 numbers) are notated by prefixing them with 0b. They can only contain digits 0 and 1. Using numbers outside of 0 and 1 with a binary integer will raise a SyntaxError.
Hexadecimal, binary, and octal are the most commonly used numeral systems, next to decimals, in computing. This is why they come built into the language. Examples of other popular numeral systems that you may encounter in computing, but aren’t built into JavaScript, are Base-32 (Duotrigesimal) and Base-64 (Tetrasexagesimal). Refer to Table 1-2 for a handy guide on how each of the built-in JavaScript numerals convert.
Table 1-2.
Decimal, Hexadecimal, Octal, and Binary Conversion Chart
Decimal (Base-10)
Hexadecimal (Base-16)
Octal (Base-8)
Binary (Base-2)
0
0
0
0
1
1
1
1
2
2
2
10*
3
3
3
11*
4
4
4
100*
5
5
5
101*
6
6
6
110*
7
7
7
111*
8
8
10*
1000*
9
9
11*
1001*
10
A
12*
1010*
11
B
13*
1011*
12
C
14*
1100*
13
D
15*
1101*
14
E
16*
1110*
15
F
17*
1111*
* These numbers don’t exist as single numerals, and so have to be created from multiple numerals.

The Code

// Basic arithmetic
var a = 1 + 1;
console.log( typeof a );                                            // number
console.log( "1 + 1 = " + a );                                      // 1 + 1 = 2
console.log(10 - 5.52 );                                            // 4.48
console.log(3.49 / .52 );                                           // 6.711538461538462
console.log(95.78 * 627 );                                          / 60054.06
// Comparing integer and floating-point values
console.log( 1 === 1.000 );                                         // true
console.log( typeof 1 === typeof 1.000 );                           // true
// Scientific Notation
console.log( 1e1 );                                                 // 10
console.log( 1e3 );                                                 // 1000
console.log(1.51e-6 );                                              // 0.00000151
console.log( 1.7985e19 );                                            // 17985000000000000000
// Hexadecimal Notation
console.log( 0x01 );                                              // 1
console.log( 0x1a );                                              // 26
console.log( 0xbc );                                              // 188
console.log( 0xff );                                              // 255
// Octal Notation
console.log( 0o1 );                                               // 1
console.log( 0o32 );                                              // 26
console.log( 0o274 );                                             // 188
console.log( 0o377 );                                             // 255
// Octal Notation
console.log( 0b1 );                                               // 1
console.log( 0b11010 );                                           // 26
console.log( 0o10111100 );                                        // 2134592
console.log( 0o11111111 );                                        // 2396745
Listing 1-23.
Creating a Numeric Value Using Number Literals

How It Works

This simple overview is an introduction to the basics of numeric representation and manipulation . To get the most out of number literals and the number object, make sure you read Chapter 4 to get an in-depth look at what JavaScript mathematics can really do. You will learn how to perform trigonometric, algebraic, calculus operations, and more.

Determining If a Defined Variable Is a Number

Problem

You need to test a variable to determine if it is a numeric value or another datatype.

Solution

Using the typeof operator, you can determine the datatype of a variable. If the variable is a Number value, typeof will return the string "number".

The Code

var a = Number(5.912);
var b = 4.7;
var c = "";
var d = new Date();
if ( typeof a === 'number' ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log("a is a Number");
} else {
           console.log("a is not a Number");
}
if ( typeof b === 'number' ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log("b is a Number");
} else {
           console.log("b is not a Number");
}
if ( typeof c === 'number' ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log("c is a Number");
} else {
           console.log("c is not a Number");
}
if ( typeof d === 'number' ) { // For more on the Strict Equality Operator (`===`), see Chapter 2-10
           console.log("d is a Number");
} else {
           console.log("d is not a Number");
}
Listing 1-24.
Determining If a Defined Variable Is a Number
The output is:
a is a Number
b is a Number
c is not a Number
d is not a Number

How It Works

The typeof operator returns the string value " number" for number objects. To determine if a variable is a number, all you need to do is compare the return value of the typeof operator to the string "number". Other datatypes such as strings and objects return different strings that represent them.

Dealing with NaN and Infinity

Caution
Number.isNaN() and Number.isFinite() are ES6 features. Older browsers still in use, such as Internet Explorer 11 and below and Safari 7 and below do not support this feature. However, they are supported on the global object, so for these browsers, you can use isNaN() or isFinite() (without the Number. prefix).

Problem

Sometimes you may encounter the literals `NaN` (Not a Number) and ±Infinity (`Infinity` or `-Infinity`). All of these values are the typeof number, and need extra checks to ensure the number you want is a finite number.

Solution

The number constructor has two static methods (functions attached directly to the number constructor), Number.isNaN and Number.isFinite. Both return Booleans determining if the passed parameter is NaN or ±Infinity, respectively.

The Code

var a = NaN;
var b = Infinity;
var c = -Infinity;
var d = 3;
if ( Number.isNaN(a) ) {
         console.log("a is a NaN (not a number)");
} else {
         console.log("a is a real Number, not NaN");
}
if ( Number.isFinite(b) ) {
         console.log("b is a finite Number");
} else {
         console.log("b is not a finite Number, it is either +Infinity or -Infinity");
}
if ( Number.isFinite(c) ) {
         console.log("c is a finite Number");
} else {
         console.log("c is not a finite Number, it is either +Infinity or -Infinity");
}
if ( Number.isNaN(d) ) {
         console.log("d is a NaN (not a number)");
} else {
         console.log("d is a real Number, not NaN");
}
if ( Number.isFinite(d) ) {
         console.log("d is a finite Number");
} else {
         console.log("d is not a finite Number, it is either +Infinity or -Infinity");
}
Listing 1-25.
Dealing with NaN and Infinity
The output is:
a is a NaN (not a number)
b is not a finite Number, it is either +Infinity or -Infinity
c is not a finite Number, it is either +Infinity or -Infinity
d is a real Number, not NaN
d is a finite Number

How It Works

NaN and ±Infinity are Number objects , which makes dealing with them difficult to detect; however, the two methods Number.isNaN() and Number.isFinite() are specifically built to detect these two edge cases. They are also available on the global object, meaning one can write, for example window.isNaN() or more simply isNaN(). It is especially important when taking user input as numbers, to check if the number is NaN.

Generating a Date Using the Date Object

Problem

You need to generate a date or timestamp for your application. You may need to pass this value back to the server or simply use it client-side.

Solution

It’s easy to create a timestamp with the date constructor; all you need to do is create an instance of the Date object without any parameters and assign it to a variable. The date constructor is also useful for recording timespans such as the length of time required for an operation to complete.

The Code

// The current date and time
// Wed Apr 10 2013 15:01:06 GMT-0400 (Eastern Daylight Time)
var today = new Date();
console.log(today);
// Thu Mar 14 2013 03:14:15 GMT-0400 (Eastern Daylight Time)
var dateOne = new Date("March 14, 2013 03:14:15");
console.log(dateOne);
// Wed Apr 10 2013 00:00:00 GMT-0400 (Eastern Daylight Time)
var dateTwo = new Date(2013,03,10);
console.log(dateTwo);
// Thu Mar 14 2013 03:14:15 GMT-0400 (Eastern Daylight Time)
var dateThree = new Date(2013,02,14,3,14,15);
console.log(dateThree);
// Working with Date components
var date = today.getDate();                                             // 13
var month = today.getMonth();                                           // 3
var year = today.getFullYear();                                         // 2013
console.log(date + "/" + month + "/" + year);
// Determine the duration of an event
var start = Date.now();
alert("Wait a few seconds then click OK");
var time = Date.now() - start;
console.log( "The operation took " + time + " milliseconds" );
Listing 1-26.
Generating a Date Using the Date Object
The output is:
Sun Dec 15 2013 23:46:08 GMT+0000 (GMT) // (this output may be different based on your timezone!)
Thu Mar 14 2013 03:14:15 GMT+0000 (GMT)
Wed Apr 10 2013 00:00:00 GMT+0100 (BST) // (this output may be different based on your timezone!)
Thu Mar 14 2013 03:14:15 GMT+0000 (GMT)
15/11/2013 // (this output may be different based on your locale!)
The operation took 1326 milliseconds

How It Works

The JavaScript Date object offers many powerful functions such as measuring a timespan, converting times from one time zone to another, adding and subtracting moments in time, and more . Be sure to read Chapter 6 about dates and time, where the topic is covered in much more detail.

Generating a Date with a Date String

Problem

You have been given a date string from a server, client-side database or possibly generated from user input and need to manipulate it by using Date object methods.

Solution

The Date object constructor can accept a string that’s RFC 2822 (for example "Fri, 24 Jan 2014 21:18:23 +0000"), or RFC 3339 compliant (for example, "2014-01-24T21:18:23+00:00"). We’ll pass the date string into the date constructor to create a Date object instance.

The Code

var myDateString = "January 16, 1975 17:07:00";
var myDate = new Date(myDateString);
console.log(myDate);
myDate.setMonth(2);
console.log(myDate);
myDate.setHours(10);
console.log(myDate);
myDate.setMinutes(51);
console.log(myDate);
myDate.setSeconds(59);
console.log(myDate);
var myDateString = "1985-04-12T23:20:50.52Z";
var myDate = new Date(myDateString);
console.log(myDate);
myDate.setMonth(2);
console.log(myDate);
myDate.setHours(10);
console.log(myDate);
myDate.setMinutes(51);
console.log(myDate);
myDate.setSeconds(59);
console.log(myDate);
Listing 1-27.
Generating a Date with a Date String
The output is:
Thu Jan 16 1975 17:07:00 GMT+0000 (GMT)
Sun Mar 16 1975 17:07:00 GMT+0100 (GMT)
Sun Mar 16 1975 10:07:00 GMT+0100 (GMT)
Sun Mar 16 1975 10:51:00 GMT+0100 (GMT)
Sun Mar 16 1975 10:51:59 GMT+0100 (GMT)
Sat Apr 13 1985 00:20:50 GMT+0100 (BST)
Wed Mar 13 1985 00:20:50 GMT+0000 (GMT)
Wed Mar 13 1985 10:20:50 GMT+0000 (GMT)
Wed Mar 13 1985 10:51:50 GMT+0000 (GMT)
Wed Mar 13 1985 10:51:59 GMT+0000 (GMT)

How It Works

The JavaScript Date object will attempt to parse many types of date strings, most notably RFC 3339 and RFC 2822 formatted date strings. This can be very useful as a tool for receiving dates from the server side. RFC 3339 strings are the recommended format for receiving and sending dates from the server side.

Determining If a Defined Variable Is a Date

Problem

You need to test a variable to determine if it is a Date object or another datatype.

Solution

We can’t use the typeof operator to return the variable’s type because typeof will return the string "object" for a Date instance (as it is not a literal). Instead we’ll use the instanceof operator to determine if a variable is an instance of the Date object .

The Code

var a = new Date();
var b = 3.14;
var c = "I'm a string";
if (a instanceof Date) {
           console.log("a is a Date");
} else {
           console.log("a is not a Date");
}
if (b instanceof Date) {
           console.log("b is a Date");
} else {
           console.log("b is not a Date");
}
if (c instanceof Date) {
           console.log("c is a Date");
}
else {
           console.log("c is not a Date");
}
Listing 1-28.
Determining If a Defined Variable Is a Date
The output is:
a is a Date
b is not a Date
c is not a Date

How It Works

The instanceof operator determines if a variable is an instance of an object. In this example, various variables are tested to see if they are instances of the Date object. If a variable is an instance of the Date object, the instanceof operator returns true, otherwise false.

Creating an Object and Assigning Properties

Problem

You are required to create an object and give it some properties to use object-oriented practices in your code base.

Solution

Objects are collections of methods and properties. A method is a function in an object. A property is one or more values or objects in an object. JavaScript supports its own internal objects, objects that you create, and host objects.
To create your own objects, you first create an object literal, and then populate it with properties and methods using the well-known dot notation.

The Code

// Create a House object
var House = {};
House.address = "123 Main Street, Podunkville, NC 28328";
House.area = 2800;
House.constructionDate = new Date(1991,0,16);
// The Architecture object contains structural information about the House
House.architecture = {};
House.architecture.floorPlan =
              "http://upload.wikimedia.org/wikipedia/commons/b/b8/HouseFlrPlan.svg";
House.architecture.style = "American FourSquare";
House.architecture.doorsExternal = ["Living Room","Kitchen","Foyer"];
House.architecture.rooms = ["Kitchen","Living Room","Bathroom", "Guest Bedroom", "Secondary Bedroom", "Master Bedroom", "Master Bathroom"];
House.architecture.windows = ["Kitchen (2)","Living Room (2)","Bathroom (1)", "Guest Bedroom (1)", "Secondary Bedroom (1)", "Master Bedroom (1)", "Master Bathroom (1)"];
// House owner object
House.owner = {};
House.owner.name = "Matthew Stephen Skipper";
House.owner.phone = "123-456-7890";
// Display basic house data
console.log( "House at: " + House.address );
console.log( "Built on: " + House.constructionDate );
console.log( "Area: " + House.area + " square feet" );
// Display house owner data
console.log( " House Owner" );
console.log( "Name: " + House.owner.name );
console.log( "Phone: " + House.owner.phone );
// Display house architecture data
console.log( " House Architecture" );
console.log( "Area: " + House.area + " square feet" );
console.log( "Floor Plan URL: " + House.architecture.floorPlan );
console.log( "Style: " + House.architecture.style );
console.log( "External Doors: " + House.architecture.doorsExternal );
console.log( "Rooms: " + House.architecture.rooms );
console.log( "Windows: " + House.architecture.windows );
Listing 1-29.
Creating an Object and Assigning Properties
The output is:
House at: 123 Main Street, Podunkville, NC 28328
Built on: Wed Jan 16 1991 00:00:00 GMT-0500 (Eastern Standard Time)
Area: 2800 square feet
House Owner
Name: Matthew Stephen Skipper
Phone: 123-456-7890
House Architecture
Area: 2800 square feet
Floor Plan URL: http://upload.wikimedia.org/wikipedia/commons/b/b8/HouseFlrPlan.svg
Style: American FourSquare
External Doors: Living Room,Kitchen,Foyer
Rooms: Kitchen,Living Room,Bathroom,Guest Bedroom,Secondary Bedroom,Master Bedroom,Master Bathroom
Windows: Kitchen (2),Living Room (2),Bathroom (1),Guest Bedroom (1),Secondary Bedroom (1),Master Bedroom (1),Master Bathroom (1)

How It Works

The object created is a very simple representation of a house, its owner, and architecture. The house object contains five properties: address, area, constructionDate, architecture, and owner. The architecture property is another custom object with various properties about the house. The owner property is a third custom object containing data about the owner.
This house object is very simple and has no methods. However, it does show the basics of object creation and JavaScript object-oriented programming (OOP) . Objects and object-oriented programming are discussed in much more detail in Chapter 9.

Determining If a Defined Variable Is an Object

Problem

You need to test a variable to determine if it is an object or another datatype.

Solution

Using the typeof operator, we can determine the datatype of a variable. If the variable is an object, typeof will return the string "object".

The Code

var a = {};
var b = "I'm a string";
var c = 7;
if ( typeof a === 'object' ) {
            console.log("a is an Object");
} else {
            console.log("a is not an Object");
}
if ( typeof b === 'object' ) {
            console.log("b is an Object");
} else {
               console.log("b is not an Object");
}
if ( typeof c === 'object' ) {
            console.log("c is an Object");
} else {
            console.log("c is not an Object");
}
Listing 1-30.
Determining If a Defined Variable Is an Object
The output is:
a is an Object
b is not an Object
c is not an Object

How It Works

The typeof operator returns the string " object" for all objects derived from the built-in "object" object. Other datatypes such as strings and numbers return a string that represents them.

Determining If an Object Is an Instance

Problem

You need to determine if an object, such as a Date object, is an instance of a constructor, or an instance of the Object constructor; however, typeof returns the "object" value for all of these.

Solution

If you have an object, such as a Date object, and using typeof returns "object", but you still want to assert that the object is an instance of a constructor you can use the instanceof keyword.

The Code

var date = new Date();
var error = new Error();
var blob =  new Blob();
var object = new Object();
typeof date; // Returns "object"
typeof error; // Returns "object"
typeof blob; // Returns "object"
if ( date instanceof Date ) {
            console.log("date is a Date instance");
} else if ( date instanceof Error ) {
            console.log("date is an Error instance");
} else if ( date instanceof Blob ) {
            console.log("date is a Blob instance");
} else {
            console.log("date is an unknown instance");
}
if ( error instanceof Date ) {
            console.log("error is a Date instance");
} else if ( error instanceof Error ) {
            console.log("error is an Error instance");
} else if ( error instanceof Blob ) {
            console.log("error is a Blob instance");
} else {
            console.log("error is an unknown instance");
}
if ( blob instanceof Date ) {
            console.log("blob is a Date instance");
} else if ( blob instanceof Error ) {
            console.log("blob is an Error instance");
} else if ( blob instanceof Blob ) {
            console.log("blob is a Blob instance");
} else {
            console.log("blob is an unknown instance");
}
if ( object instanceof Date ) {
            console.log("object is a Date instance");
} else if ( object instanceof Error ) {
            console.log("object is an Error instance");
} else if ( object instanceof Blob ) {
            console.log("object is a Blob instance");
} else {
            console.log("object is an unknown instance");
}
Listing 1-31.
Differences Between Objects and Instances
The output is:
date is a Date instance
error is an Error instance
blob is a Blob instance
object is an unknown instance

How It Works

The instanceof operator is a useful tool for detecting instances of constructors, especially when you want to determine the finer points of an objects inheritance. It is vitally important to remember that instanceof will not work on any literals, such as number literals or string literals. As a rule of thumb, instanceof only works on values that have a typeof of ”object”, so you could be ultra cautious by checking the typeof a value, followed by checking instanceof the object, only if the typeof is ”object”.

Determining an Object’s Direct Instance with the Constructor Property

Problem

Some objects are created from the result of a constructor (such as Date), but they also inherit from their parent constructor objects. For example, a Date object will return true for instanceof Date, but will also return true for instanceof Object. This becomes a problem when trying to find the direct descendant of an object.

Solution

Every object that has a constructor and can be created by using the new keyword will have a constructor property. This is set to the constructor function, so for example new Date()`s constructor property is Date.

The Code

var date = new Date();
var error = new Error();
var blob =  new Blob();
var object = {};
if ( date.constructor === Date ) {
    console.log("date is a Date instance");
} else if ( date.constructor === Error ) {
    console.log("date is an Error instance");
} else if ( date.constructor === Blob ) {
    console.log("date is a Blob instance");
} else {
    console.log("date is an unknown instance");
}
if ( error.constructor === Date ) {
    console.log("error is a Date instance");
} else if ( error.constructor === Error ) {
    console.log("error is an Error instance");
} else if ( error.constructor === Blob ) {
    console.log("error is a Blob instance");
} else {
    console.log("error is an unknown instance");
}
if ( blob.constructor === Date ) {
    console.log("blob is a Date instance");
} else if ( blob.constructor === Error ) {
    console.log("blob is an Error instance");
} else if ( blob.constructor === Blob ) {
    console.log("blob is a Blob instance");
} else {
    console.log("blob is an unknown instance");
}
if ( object.constructor === Date ) {
    console.log("object is a Date instance");
} else if ( object.constructor === Error ) {
    console.log("object is an Error instance");
} else if ( object.constructor === Blob ) {
    console.log("object is a Blob instance");
} else {
    console.log("object is an unknown instance");
}
Listing 1-32.
Determining an Object’s Direct Instance with the Constructor Property
The output is:
date is a Date instance
error is an Error instance
blob is a Blob instance
object is an unknown instance

How It Works

The constructor property is very useful for determining the direct descendant of an object. It is also useful for getting the constructor itself, which can be useful for cloning an instance or making new instances of the same type. It also illustrates the main difference between instanceof and constructor.

Determining If Something Is a Plain Object

Problem

You want to be able to assert that an object is not a descendant of a resulting constructor function, and instead asserting that an object is a plain object—one that was created using new Object() or an object literal ({}). instanceof will assert that the object is an instance of the object constructor. instanceof also asserts on any descendants of the object’s constructor such as the Date instances.

Solution

Just like in Listing 1-30, determining the direct descendant of an object should use the .constructor property. Determining if an object is a “plain” object (e.g., is not an instance of another constructor, such as date) requires the same process, even for object literals ({}).

The Code

var date = new Date();
var error = new Error();
var object = new Object();
var plainObject = {};
if ( date.constructor === Object ) {
    console.log("date is a plain object");
} else {
    console.log("date is not a plain object");
}
if ( error.constructor === Object ) {
    console.log("error is a plain object");
} else {
    console.log("error is not a plain object");
}
if ( object.constructor === Object ) {
    console.log("object is a plain object");
} else {
    console.log("object is not a plain object");
}
if ( plainObject.constructor === Object ) {
    console.log("plainObject is a plain object");
} else {
    console.log("plainObject is not a plain object");
}
Listing 1-33.
Determining If Something Is a Plain Object
The output is:
date is not a plain object
error is not a plain object
object is a plain object
plainObject is a plain object

How It Works

This is another important example of how the constructor property can sometimes be more useful than instanceof. The instanceof property will “walk the prototype chain”; that is, it will check not only the direct descendant, but the descendant of that, and that, and that, and so on. This means objects like Date are instances of Object (in fact, nearly everything is), however “plain” objects are the only objects where the .constructor property should be Object.

Creating an Array and Assigning and Retrieving Values

Problem

You need to create a list of values and store them in an ordered manner.

Solution

Using arrays is the best way to create an ordered list of values. Each value has a unique, numerical identifier and so, unlike objects, there is an explicit order to arrays.

The Code

var register = ['Annie', 'Cathy', 'Jessica', 'Sally'];
console.log(register[0]);
console.log(register[1]);
console.log(register[2]);
console.log(register[3]);
var places = ['First', 'Second', 'Third'];
console.log(places.length);
console.log(places[2]);
var bytes = new Array(2);
console.log(bytes.length);
console.log(bytes[0]);
Listing 1-34.
Creating an Array and Assigning and Retrieving Values
The output is:
Annie
Cathy
Jessica
Sally
3
Third
2
`undefined`

How It Works

Arrays are ordered lists of values . You can get to any individual value inside an array by using the staple-notation ([ and ]) with a numeric index of the key. The numerical index starts from 0 and counts up by 1 for each new value in the array. Arrays also include a .length property, which is set to the total number of items in the array. Arrays can be created with an initial length, by using the array constructor with the new keyword, and a length parameter. For example, new Array(3) will create an array with three undefined values in it.

Choosing Between Objects and Arrays

Problem

You are unsure when to use an object over an array, or are unsure of the merits of using either one.

Solution

Both arrays and objects store values against keys—they are “key-value stores”. The benefits of an array over an object are that the keys are predictable sequential numbers for each new item in the array, and that they explicitly maintain their sort order. Objects, on the other hand, do not have an explicit sort order and have unpredictable keys, they also cannot determine their length easily. An array’s key sequence is strictly sequential, so this has a side effect that if you create new values with large key numbers, the previous empty keys are backfilled to be undefined values.
The benefit of objects is that keys can be given a name decided by you, which can be very useful for object-oriented programming. Typically you would use objects for storing some kind of record, e.g., attributes about a person or place. You would likely use arrays for lists, perhaps a list of people or rankings. Refer to Table 1-3 for an object-array comparison.:
Table 1-3.
Objects versus Arrays Comparison
 
Objects
Arrays
Key Types
String
Number
Key Sequence
Up to the user
Sequential numbers
Key Predictability
Low
High
Lowest Key Value
Unknown
0
Highest Key Value
Unknown
theArray.length - 1
Value
Any
Any
Duplicate Values Allowed
Yes
Yes
Duplicate Keys Allowed
No
No

Creating a Regular Expression Literal

Problem

You need to be able to match a string against a particular pattern and need a concise way to do it.

Solution

Using regular expressions is the most powerful way to match patterns or test for patterns against a string value. It is a powerful tool that exists in many programming languages, including Ruby, C++11, Java, and Perl, and is even built into command-line tools such as Awk and Sed.

The Code

var testString = 'hello world';
if ( /hello/.test(testString) ) {
    console.log('testString contains "hello"!');
} else {
    console.log('testString does not contain "hello"');
}
if ( /world/.test(testString) ) {
    console.log('testString contains "world"!');
} else {
    console.log('testString does not contain "world"');
}
var testStringMatch = testString.match(/(w+)+/g); // A complex pattern!
if ( testStringMatch ) {
    console.log('testString contains ' + testStringMatch.length + ' words!');
} else {
    console.log('testString does not contain any words');
}
Listing 1-35.
Creating a Regular Expression Literal
The output is:
testString contains "hello"!
testString contains "world"!
testString contains 2 words!

How It Works

Regular expressions are almost a miniature language alongside JavaScript (as well as many other languages), which allow for very powerful string finding and matching. The syntax is very complex, but with it comes a lot of power. Not only can you match parts of a string, as in the first two examples, but you can also match complex patterns such as words, number patterns, word boundaries, character ranges, and a lot more. You can also extract parts of a string based on these patterns or replace parts of a string. Regular expressions are covered in extensive detail in Chapter 20.

Injecting Variables into a String with Template Literals

Caution
Template literals are an ECMAScript 6 (ES6) feature. Older browsers still in use, such as Internet Explorer 11 and below and Safari 7 and below, do not support this feature (they work off of the ECMAScript 5, or ES5 standard). In fact, at the time of writing only the Taceur Compiler tool could support template string literals. Check out http://kangax.github.io/es5-compat-table/es6/ for the current compatibility charts.

Problem

You want to do variable substitution inside of a string.

Solution

JavaScript ES6 features template literals, which fix a wide range of issues with existing JavaScript strings, the biggest of which is injecting variables into strings. Template literals use backticks (` and `), whereas normal strings use quotes ("" or '').

The Code

var name = 'Bob';
console.log( 'Hello ' + name + '!' ); // The old way to do this, cumbersome and error prone
console.log( `Hello ${name}!` ); // Template Literals, shorter, more succinct, and less error prone
var otherName = 'Mary';
var thirdName = 'Jim';
console.log( 'Hello ' + otherName + ', how is ' + thirdName + '?' ); // Can get very messy
console.log( `Hello ${otherName}, how is ${thirdName}?` ); // Much cleaner
Listing 1-36.
Injecting Variables into a String with Template Literals
The output is:
Hello Bob!
Hello Bob!
Hello Mary, how is Jim?
Hello Mary, how is Jim?

How It Works

Template string literals are specially tuned to let the JavaScript interpreter know that variable substitution needs to take place. Every time a template substitution (${}) is encountered, it will inject the known variable in its place, as you’d expect. The same scoping rules for variables apply here, as they do everywhere else. Template string literals are much more powerful than simple variable substitution—they behave very differently from strings with regard to escaping characters, and can be passed into custom functions to build complex formatting and template engines. Template string literals are covered in Chapter 14 of this book.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.107.229