JavaScript Language Quick Start

FMZQuant - Jun 5 - - Dev Community

Background

This section gives a little background on JavaScript to help you understand why it is the way it is.

JavaScript Versus ECMAScript

ECMAScript is the official name for JavaScript. A new name became necessary because there is a trademark on JavaScript (held originally by Sun, now by Oracle). At the moment, Mozilla is one of the few companies allowed to officially use the name JavaScript because it received a license long ago. For common usage, these rules apply:

  • JavaScript means the programming language.
  • ECMAScript is the name used by the language specification. Therefore, whenever referring to versions of the language, people say ECMAScript. The current version of JavaScript is ECMAScript 5; ECMAScript 6 is currently being developed. ## Influences and Nature of the Language JavaScript’s creator, Brendan Eich, had no choice but to create the language very quickly (or other, worse technologies would have been adopted by Netscape). He borrowed from several programming languages: Java (syntax, primitive values versus objects), Scheme and AWK (first-class functions), Self (prototypal inheritance), and Perl and Python (strings, arrays, and regular expressions).

JavaScript did not have exception handling until ECMAScript 3, which explains why the language so often automatically converts values and so often fails silently: it initially couldn’t throw exceptions.

On one hand, JavaScript has quirks and is missing quite a bit of functionality (block-scoped variables, modules, support for subclassing, etc.). On the other hand, it has several powerful features that allow you to work around these problems. In other languages, you learn language features. In JavaScript, you often learn patterns instead.

Given its influences, it is no surprise that JavaScript enables a programming style that is a mixture of functional programming (higher-order functions; built-in map, reduce, etc.) and object-oriented programming (objects, inheritance).

Syntax

This section explains basic syntactic principles of JavaScript.

An Overview of the Syntax

A few examples of syntax:

// Two slashes start single-line comments

var x;  // declaring a variable

x = 3 + y;  // assigning a value to the variable `x`

foo(x, y);  // calling function `foo` with parameters `x` and `y`
obj.bar(3);  // calling method `bar` of object `obj`

// A conditional statement
if (x === 0) {  // Is `x` equal to zero?
    x = 123;
}

// Defining function `baz` with parameters `a` and `b`
function baz(a, b) {
    return a + b;
}
Enter fullscreen mode Exit fullscreen mode

Note the two different uses of the equals sign:

  • A single equals sign (=) is used to assign a value to a variable.
  • A triple equals sign (===) is used to compare two values (see Equality Operators).

Statements Versus Expressions

To understand JavaScript’s syntax, you should know that it has two major syntactic categories: statements and expressions:

  • Statements “do things.” A program is a sequence of statements. Here is an example of a statement, which declares (creates) a variable foo:
var foo;
Enter fullscreen mode Exit fullscreen mode
  • Expressions produce values. They are function arguments, the right side of an assignment, etc. Here’s an example of an expression:
3 * 7
Enter fullscreen mode Exit fullscreen mode

The distinction between statements and expressions is best illustrated by the fact that JavaScript has two different ways to do if-then-else—either as a statement:

var x;
if (y >= 0) {
    x = y;
} else {
    x = -y;
}
Enter fullscreen mode Exit fullscreen mode

or as an expression:

var x = y >= 0 ? y : -y;
Enter fullscreen mode Exit fullscreen mode

You can use the latter as a function argument (but not the former):

myFunction(y >= 0 ? y : -y)
Enter fullscreen mode Exit fullscreen mode

Finally, wherever JavaScript expects a statement, you can also use an expression; for example:

foo(7, 1);
Enter fullscreen mode Exit fullscreen mode

The whole line is a statement (a so-called expression statement), but the function call foo(7, 1) is an expression.

Semicolons

Semicolons are optional in JavaScript. However, I recommend always including them, because otherwise JavaScript can guess wrong about the end of a statement. The details are explained in Automatic Semicolon Insertion.

Semicolons terminate statements, but not blocks. There is one case where you will see a semicolon after a block: a function expression is an expression that ends with a block. If such an expression comes last in a statement, it is followed by a semicolon:

// Pattern: var _ = ___;
var x = 3 * 7;
var f = function () { };  // function expr. inside var decl.
Enter fullscreen mode Exit fullscreen mode

Comments

JavaScript has two kinds of comments: single-line comments and multiline comments. Single-line comments start with // and are terminated by the end of the line:

x++; // single-line comment
Enter fullscreen mode Exit fullscreen mode

Multiline comments are delimited by /* and */:

/* This is
   a multiline
   comment.
 */
Enter fullscreen mode Exit fullscreen mode

Variables and Assignment

Variables in JavaScript are declared before they are used:

var foo;  // declare variable `foo`
Enter fullscreen mode Exit fullscreen mode

Assignment

You can declare a variable and assign a value at the same time:

var foo = 6;
Enter fullscreen mode Exit fullscreen mode

You can also assign a value to an existing variable:

foo = 4;  // change variable `foo`
Enter fullscreen mode Exit fullscreen mode

Compound Assignment Operators

There are compound assignment operators such as +=. The following two assignments are equivalent:

x += 1;
x = x + 1;
Enter fullscreen mode Exit fullscreen mode

Identifiers and Variable Names

Identifiers are names that play various syntactic roles in JavaScript. For example, the name of a variable is an identifier. Identifiers are case sensitive.

Roughly, the first character of an identifier can be any Unicode letter, a dollar sign ($), or an underscore (_). Subsequent characters can additionally be any Unicode digit. Thus, the following are all legal identifiers:

arg0
_tmp
$elem
π
Enter fullscreen mode Exit fullscreen mode

The following identifiers are reserved words—they are part of the syntax and can’t be used as variable names (including function names and parameter names):

Image description

The following three identifiers are not reserved words, but you should treat them as if they were:

Image description

Lastly, you should also stay away from the names of standard global variables. You can use them for local variables without breaking anything, but your code still becomes confusing.

Values

JavaScript has many values that we have come to expect from programming languages: booleans, numbers, strings, arrays, and so on. All values in JavaScript have properties.Each property has a key (or name) and a value. You can think of properties like fields of a record. You use the dot (.) operator to read a property:

value.propKey
Enter fullscreen mode Exit fullscreen mode

For example, the string 'abc' has the property length:

> var str = 'abc';
> str.length
3
Enter fullscreen mode Exit fullscreen mode

The preceding can also be written as:

> 'abc'.length
3
The dot operator is also used to assign a value to a property:

> var obj = {};  // empty object
> obj.foo = 123; // create property `foo`, set it to 123
123
> obj.foo
123
Enter fullscreen mode Exit fullscreen mode

And you can use it to invoke methods:

> 'hello'.toUpperCase()
'HELLO'
Enter fullscreen mode Exit fullscreen mode

In the preceding example, we have invoked the method toUpperCase() on the value 'hello'.

Primitive Values Versus Objects

JavaScript makes a somewhat arbitrary distinction between values:

  • The primitive values are booleans, numbers, strings, null, and undefined.
  • All other values are objects. A major difference between the two is how they are compared; each object has a unique identity and is only (strictly) equal to itself:
> var obj1 = {};  // an empty object
> var obj2 = {};  // another empty object
> obj1 === obj2
false
> obj1 === obj1
true
Enter fullscreen mode Exit fullscreen mode

In contrast, all primitive values encoding the same value are considered the same:

> var prim1 = 123;
> var prim2 = 123;
> prim1 === prim2
true
Enter fullscreen mode Exit fullscreen mode

The next two sections explain primitive values and objects in more detail.

Primitive Values

The following are all of the primitive values (or primitives for short):

  • Booleans: true, false (see Booleans)
  • Numbers: 1736, 1.351 (see Numbers)
  • Strings: 'abc', "abc" (see Strings)
  • Two “nonvalues”: undefined, null (see undefined and null) Primitives have the following characteristics:

Compared by value

The “content” is compared:

> 3 === 3
true
> 'abc' === 'abc'
true
Enter fullscreen mode Exit fullscreen mode

Always immutable

Properties can’t be changed, added, or removed:

> var str = 'abc';

> str.length = 1; // try to change property `length`
> str.length      // ⇒ no effect
3

> str.foo = 3; // try to create property `foo`
> str.foo      // ⇒ no effect, unknown property
undefined
Enter fullscreen mode Exit fullscreen mode

(Reading an unknown property always returns undefined.)

Objects

All nonprimitive values are objects. The most common kinds of objects are:

  • Plain objects, which can be created by object literals (see Single Objects):
{
    firstName: 'Jane',
    lastName: 'Doe'
}
Enter fullscreen mode Exit fullscreen mode

The preceding object has two properties: the value of property firstName is 'Jane' and the value of property lastName is 'Doe'.

  • Arrays, which can be created by array literals (see Arrays):
[ 'apple', 'banana', 'cherry' ]
Enter fullscreen mode Exit fullscreen mode

The preceding array has three elements that can be accessed via numeric indices. For example, the index of 'apple' is 0.

  • Regular expressions, which can be created by regular expression literals (see Regular Expressions):
/^a+b+$/
Enter fullscreen mode Exit fullscreen mode

Objects have the following characteristics:

Compared by reference

Identities are compared; every value has its own identity:

> ({} === {})  // two different empty objects
false

> var obj1 = {};
> var obj2 = obj1;
> obj1 === obj2
true
Enter fullscreen mode Exit fullscreen mode

Mutable by default

You can normally freely change, add, and remove properties (see Single Objects):

> var obj = {};
> obj.foo = 123; // add property `foo`
> obj.foo
123
Enter fullscreen mode Exit fullscreen mode

Undefined and null

Most programming languages have values denoting missing information. JavaScript has two such “nonvalues,” undefined and null:

undefined means “no value.” Uninitialized variables are undefined:

> var foo;
> foo
undefined
Enter fullscreen mode Exit fullscreen mode

Missing parameters are undefined:

> function f(x) { return x }
> f()
undefined
Enter fullscreen mode Exit fullscreen mode

If you read a nonexistent property, you get undefined:

> var obj = {}; // empty object
> obj.foo
undefined
Enter fullscreen mode Exit fullscreen mode
  • null means “no object.” It is used as a nonvalue whenever an object is expected (parameters, last in a chain of objects, etc.). ## WARNING undefined and null have no properties, not even standard methods such as toString().

Checking for undefined or null

Functions normally allow you to indicate a missing value via either undefined or null. You can do the same via an explicit check:

if (x === undefined || x === null) {
    ...
}
Enter fullscreen mode Exit fullscreen mode

You can also exploit the fact that both undefined and null are considered false:

if (!x) {
    ...
}
Enter fullscreen mode Exit fullscreen mode

WARNING

false, 0, NaN, and '' are also considered false (see Truthy and Falsy).

Categorizing Values Using typeof and instanceof

There are two operators for categorizing values: typeof is mainly used for primitive values, while instanceof is used for objects.
typeof looks like this:

typeof value
Enter fullscreen mode Exit fullscreen mode

It returns a string describing the “type” of value. Here are some examples:

> typeof true
'boolean'
> typeof 'abc'
'string'
> typeof {} // empty object literal
'object'
> typeof [] // empty array literal
'object'
Enter fullscreen mode Exit fullscreen mode

The following table lists all results of typeof:

Image description

typeof null returning 'object' is a bug that can’t be fixed, because it would break existing code. It does not mean that null is an object.

instanceof looks like this:

value instanceof Constr
Enter fullscreen mode Exit fullscreen mode

It returns true if value is an object that has been created by the constructor Constr (see Constructors: Factories for Objects). Here are some examples:

> var b = new Bar();  // object created by constructor Bar
> b instanceof Bar
true

> {} instanceof Object
true
> [] instanceof Array
true
> [] instanceof Object  // Array is a subconstructor of Object
true

> undefined instanceof Object
false
> null instanceof Object
false
Enter fullscreen mode Exit fullscreen mode

Booleans

The primitive boolean type comprises the values true and false. The following operators produce booleans:

  • Binary logical operators: && (And), || (Or)
  • Prefix logical operator: ! (Not)
  • Comparison operators:Equality operators: ===, !==, ==, !=
  • Ordering operators (for strings and numbers): >, >=, <, <=

Truthy and Falsy

Whenever JavaScript expects a boolean value (e.g., for the condition of an if statement), any value can be used. It will be interpreted as either true or false. The following values are interpreted as false:

  • undefined, null
  • Boolean: false
  • Number: 0, NaN
  • String: '' All other values (including all objects!) are considered true. Values interpreted as false are called falsy, and values interpreted as true are called truthy. Boolean(), called as a function, converts its parameter to a boolean. You can use it to test how a value is interpreted:
> Boolean(undefined)
false
> Boolean(0)
false
> Boolean(3)
true
> Boolean({}) // empty object
true
> Boolean([]) // empty array
true
Enter fullscreen mode Exit fullscreen mode

Binary Logical Operators

Binary logical operators in JavaScript are short-circuiting. That is, if the first operand suffices for determining the result, the second operand is not evaluated. For example, in the following expressions, the function foo() is never called:

false && foo()
true  || foo()
Enter fullscreen mode Exit fullscreen mode

Furthermore, binary logical operators return either one of their operands—which may or may not be a boolean. A check for truthiness is used to determine which one:

And (&&)

If the first operand is falsy, return it. Otherwise, return the second operand:

> NaN && 'abc'
NaN
> 123 && 'abc'
'abc'
Enter fullscreen mode Exit fullscreen mode

Or (||)

If the first operand is truthy, return it. Otherwise, return the second operand:

> 'abc' || 123
'abc'
> '' || 123
123
Enter fullscreen mode Exit fullscreen mode

Equality Operators

JavaScript has two kinds of equality:

  • Normal, or “lenient,” (in)equality: == and !=
  • Strict (in)equality: === and !== Normal equality considers (too) many values to be equal (the details are explained in Normal (Lenient) Equality (==, !=)), which can hide bugs. Therefore, always using strict equality is recommended.

Numbers

All numbers in JavaScript are floating-point:

> 1 === 1.0
true
Enter fullscreen mode Exit fullscreen mode

Special numbers include the following:

NaN (“not a number”)
An error value:

> Number('xyz')  // 'xyz' can’t be converted to a number
NaN
Enter fullscreen mode Exit fullscreen mode

Infinity
Also mostly an error value:

> 3 / 0
Infinity
> Math.pow(2, 1024)  // number too large
Infinity
Enter fullscreen mode Exit fullscreen mode

Infinity is larger than any other number (except NaN). Similarly, -Infinity is smaller than any other number (except NaN). That makes these numbers useful as default values (e.g., when you are looking for a minimum or a maximum).

Operators

JavaScript has the following arithmetic operators (see Arithmetic Operators):

  • Addition: number1 + number2
  • Subtraction: number1 - number2
  • Multiplication: number1 * number2
  • Division: number1 / number2
  • Remainder: number1 % number2
  • Increment: ++variable, variable++
  • Decrement: --variable, variable--
  • Negate: -value
  • Convert to number: +value The global object Math (see Math) provides more arithmetic operations, via functions.

JavaScript also has operators for bitwise operations (e.g., bitwise And; see Bitwise Operators).

Strings

Strings can be created directly via string literals. Those literals are delimited by single or double quotes. The backslash () escapes characters and produces a few control characters. Here are some examples:

'abc'
"abc"

'Did she say "Hello"?'
"Did she say \"Hello\"?"

'That\'s nice!'
"That's nice!"

'Line 1\nLine 2'  // newline
'Backlash: \\'
Enter fullscreen mode Exit fullscreen mode

Single characters are accessed via square brackets:

> var str = 'abc';
> str[1]
'b'
Enter fullscreen mode Exit fullscreen mode

The property length counts the number of characters in the string:

> 'abc'.length
3
Enter fullscreen mode Exit fullscreen mode

Like all primitives, strings are immutable; you need to create a new string if you want to change an existing one.

String Operators

Strings are concatenated via the plus (+) operator, which converts the other operand to a string if one of the operands is a string:

> var messageCount = 3;
> 'You have ' + messageCount + ' messages'
'You have 3 messages'
Enter fullscreen mode Exit fullscreen mode

To concatenate strings in multiple steps, use the += operator:

> var str = '';
> str += 'Multiple ';
> str += 'pieces ';
> str += 'are concatenated.';
> str
'Multiple pieces are concatenated.'
Enter fullscreen mode Exit fullscreen mode

String Methods

Strings have many useful methods (see String Prototype Methods). Here are some examples:

> 'abc'.slice(1)  // copy a substring
'bc'
> 'abc'.slice(1, 2)
'b'

> '\t xyz  '.trim()  // trim whitespace
'xyz'

> 'mjölnir'.toUpperCase()
'MJÖLNIR'

> 'abc'.indexOf('b')  // find a string
1
> 'abc'.indexOf('x')
-1
Enter fullscreen mode Exit fullscreen mode

Statements

Conditionals and loops in JavaScript are introduced in the following sections.

Conditionals

The if statement has a then clause and an optional else clause that are executed depending on a boolean condition:

if (myvar === 0) {
    // then
}

if (myvar === 0) {
    // then
} else {
    // else
}

if (myvar === 0) {
    // then
} else if (myvar === 1) {
    // else-if
} else if (myvar === 2) {
    // else-if
} else {
    // else
}
Enter fullscreen mode Exit fullscreen mode

I recommend always using braces (they denote blocks of zero or more statements). But you don’t have to do so if a clause is only a single statement (the same holds for the control flow statements for and while):

if (x < 0) return -x;
Enter fullscreen mode Exit fullscreen mode

The following is a switch statement. The value of fruit decides which case is executed:

switch (fruit) {
    case 'banana':
        // ...
        break;
    case 'apple':
        // ...
        break;
    default:  // all other cases
        // ...
}
Enter fullscreen mode Exit fullscreen mode

The “operand” after case can be any expression; it is compared via === with the parameter of switch.

Loops

The for loop has the following format:

for (⟦«init»⟧; ⟦«condition»⟧; ⟦«post_iteration»⟧)
    «statement»
Enter fullscreen mode Exit fullscreen mode

init is executed at the beginning of the loop. condition is checked before each loop iteration; if it becomes false, then the loop is terminated. post_iteration is executed after each loop iteration.

This example prints all elements of the array arr on the console:

for (var i=0; i < arr.length; i++) {
    console.log(arr[i]);
}
Enter fullscreen mode Exit fullscreen mode

The while loop continues looping over its body while its condition holds:

// Same as for loop above:
var i = 0;
while (i < arr.length) {
    console.log(arr[i]);
    i++;
}
Enter fullscreen mode Exit fullscreen mode

The do-while loop continues looping over its body while its condition holds. As the condition follows the body, the body is always executed at least once:

do {
    // ...
} while (condition);
Enter fullscreen mode Exit fullscreen mode

In all loops:

  • break leaves the loop.
  • continue starts a new loop iteration.

Functions

One way of defining a function is via a function declaration:

function add(param1, param2) {
    return param1 + param2;
}
Enter fullscreen mode Exit fullscreen mode

The preceding code defines a function, add, that has two parameters, param1 and param2, and returns the sum of both parameters. This is how you call that function:

> add(6, 1)
7
> add('a', 'b')
'ab'
Enter fullscreen mode Exit fullscreen mode

Another way of defining add() is by assigning a function expression to a variable add:

var add = function (param1, param2) {
    return param1 + param2;
};
Enter fullscreen mode Exit fullscreen mode

A function expression produces a value and can thus be used to directly pass functions as arguments to other functions:

someOtherFunction(function (p1, p2) { ... });
Enter fullscreen mode Exit fullscreen mode

Function Declarations Are Hoisted

Function declarations are hoisted—moved in their entirety to the beginning of the current scope. That allows you to refer to functions that are declared later:

function foo() {
    bar();  // OK, bar is hoisted
    function bar() {
        ...
    }
}
Enter fullscreen mode Exit fullscreen mode

Note that while var declarations are also hoisted (see Variables Are Hoisted), assignments performed by them are not:

function foo() {
    bar();  // Not OK, bar is still undefined
    var bar = function () {
        // ...
    };
}
Enter fullscreen mode Exit fullscreen mode

The Special Variable arguments

You can call any function in JavaScript with an arbitrary amount of arguments; the language will never complain. It will, however, make all parameters available via the special variable arguments. arguments looks like an array, but has none of the array methods:

> function f() { return arguments }
> var args = f('a', 'b', 'c');
> args.length
3
> args[0]  // read element at index 0
'a'
Enter fullscreen mode Exit fullscreen mode

Too Many or Too Few Arguments

Let’s use the following function to explore how too many or too few parameters are handled in JavaScript (the function toArray() is shown in Converting arguments to an Array):

function f(x, y) {
    console.log(x, y);
    return toArray(arguments);
}
Enter fullscreen mode Exit fullscreen mode

Additional parameters will be ignored (except by arguments):

> f('a', 'b', 'c')
a b
[ 'a', 'b', 'c' ]
Enter fullscreen mode Exit fullscreen mode

Missing parameters will get the value undefined:

> f('a')
a undefined
[ 'a' ]
> f()
undefined undefined
[]
Enter fullscreen mode Exit fullscreen mode

Optional Parameters

The following is a common pattern for assigning default values to parameters:

function pair(x, y) {
    x = x || 0;  // (1)
    y = y || 0;
    return [ x, y ];
}
Enter fullscreen mode Exit fullscreen mode

In line (1), the || operator returns x if it is truthy (not null, undefined, etc.). Otherwise, it returns the second operand:

> pair()
[ 0, 0 ]
> pair(3)
[ 3, 0 ]
> pair(3, 5)
[ 3, 5 ]
Enter fullscreen mode Exit fullscreen mode

Enforcing an Arity

If you want to enforce an arity (a specific number of parameters), you can check arguments.length:

function pair(x, y) {
    if (arguments.length !== 2) {
        throw new Error('Need exactly 2 arguments');
    }
    ...
}
Enter fullscreen mode Exit fullscreen mode

Converting arguments to an Array

arguments is not an array, it is only array-like (see Array-Like Objects and Generic Methods). It has a property length, and you can access its elements via indices in square brackets. You cannot, however, remove elements or invoke any of the array methods on it. Thus, you sometimes need to convert arguments to an array, which is what the following function does (it is explained in Array-Like Objects and Generic Methods):

function toArray(arrayLikeObject) {
    return Array.prototype.slice.call(arrayLikeObject);
}
Enter fullscreen mode Exit fullscreen mode

Exception Handling

The most common way to handle exceptions (see Chapter 14) is as follows:

function getPerson(id) {
    if (id < 0) {
        throw new Error('ID must not be negative: '+id);
    }
    return { id: id }; // normally: retrieved from database
}

function getPersons(ids) {
    var result = [];
    ids.forEach(function (id) {
        try {
            var person = getPerson(id);
            result.push(person);
        } catch (exception) {
            console.log(exception);
        }
    });
    return result;
}
Enter fullscreen mode Exit fullscreen mode

The try clause surrounds critical code, and the catch clause is executed if an exception is thrown inside the try clause. Using the preceding code:

> getPersons([2, -5, 137])
[Error: ID must not be negative: -5]
[ { id: 2 }, { id: 137 } ]
Enter fullscreen mode Exit fullscreen mode

Strict Mode

Strict mode (see Strict Mode) enables more warnings and makes JavaScript a cleaner language (nonstrict mode is sometimes called “sloppy mode”). To switch it on, type the following line first in a JavaScript file or a tag:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>'use strict'; </code></pre></div> <p></p> <p>You can also enable strict mode per function:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>function functionInStrictMode() { 'use strict'; } </code></pre></div> <p></p> <h2> <a name="variable-scoping-and-closures" href="#variable-scoping-and-closures" class="anchor"> </a> Variable Scoping and Closures </h2> <p>In JavaScript, you declare variables via var before using them:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; var x; &gt; x undefined &gt; y ReferenceError: y is not defined </code></pre></div> <p></p> <p>You can declare and initialize several variables with a single var statement:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>var x = 1, y = 2, z = 3; </code></pre></div> <p></p> <p>But I recommend using one statement per variable (the reason is explained in Syntax). Thus, I would rewrite the previous statement to:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>var x = 1; var y = 2; var z = 3; </code></pre></div> <p></p> <p>Because of hoisting (see Variables Are Hoisted), it is usually best to declare variables at the beginning of a function.</p> <h2> <a name="variables-are-functionscoped" href="#variables-are-functionscoped" class="anchor"> </a> Variables Are Function-Scoped </h2> <p>The scope of a variable is always the complete function (as opposed to the current block). For example:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>function foo() { var x = -512; if (x &lt; 0) { // (1) var tmp = -x; ... } console.log(tmp); // 512 } </code></pre></div> <p></p> <p>We can see that the variable tmp is not restricted to the block starting in line (1); it exists until the end of the function.</p> <h2> <a name="variables-are-hoisted" href="#variables-are-hoisted" class="anchor"> </a> Variables Are Hoisted </h2> <p>Each variable declaration is hoisted: the declaration is moved to the beginning of the function, but assignments that it makes stay put. As an example, consider the variable declaration in line (1) in the following function:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>function foo() { console.log(tmp); // undefined if (false) { var tmp = 3; // (1) } } </code></pre></div> <p></p> <p>Internally, the preceding function is executed like this:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>function foo() { var tmp; // hoisted declaration console.log(tmp); if (false) { tmp = 3; // assignment stays put } } </code></pre></div> <p></p> <h2> <a name="closures" href="#closures" class="anchor"> </a> Closures </h2> <p>Each function stays connected to the variables of the functions that surround it, even after it leaves the scope in which it was created. For example:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>function createIncrementor(start) { return function () { // (1) start++; return start; } } </code></pre></div> <p></p> <p>The function starting in line (1) leaves the context in which it was created, but stays connected to a live version of start:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; var inc = createIncrementor(5); &gt; inc() 6 &gt; inc() 7 &gt; inc() 8 </code></pre></div> <p></p> <p>A closure is a function plus the connection to the variables of its surrounding scopes. Thus, what createIncrementor() returns is a closure.</p> <h2> <a name="the-iife-pattern-introducing-a-new-scope" href="#the-iife-pattern-introducing-a-new-scope" class="anchor"> </a> The IIFE Pattern: Introducing a New Scope </h2> <p>Sometimes you want to introduce a new variable scope—for example, to prevent a variable from becoming global. In JavaScript, you can’t use a block to do so; you must use a function. But there is a pattern for using a function in a block-like manner. It is called IIFE (immediately invoked function expression, pronounced “iffy”):<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>(function () { // open IIFE var tmp = ...; // not a global variable }()); // close IIFE </code></pre></div> <p></p> <p>Be sure to type the preceding example exactly as shown (apart from the comments). An IIFE is a function expression that is called immediately after you define it. Inside the function, a new scope exists, preventing tmp from becoming global. Consult Introducing a New Scope via an IIFE for details on IIFEs.</p> <h2> <a name="iife-use-case-inadvertent-sharing-via-closures" href="#iife-use-case-inadvertent-sharing-via-closures" class="anchor"> </a> IIFE use case: inadvertent sharing via closures </h2> <p>Closures keep their connections to outer variables, which is sometimes not what you want:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>var result = []; for (var i=0; i &lt; 5; i++) { result.push(function () { return i }); // (1) } console.log(result[1]()); // 5 (not 1) console.log(result[3]()); // 5 (not 3) </code></pre></div> <p></p> <p>The value returned in line (1) is always the current value of i, not the value it had when the function was created. After the loop is finished, i has the value 5, which is why all functions in the array return that value. If you want the function in line (1) to receive a snapshot of the current value of i, you can use an IIFE:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>for (var i=0; i &lt; 5; i++) { (function () { var i2 = i; // copy current i result.push(function () { return i2 }); }()); } </code></pre></div> <p></p> <h2> <a name="objects-and-constructors" href="#objects-and-constructors" class="anchor"> </a> Objects and Constructors </h2> <p>This section covers two basic object-oriented mechanisms of JavaScript: single objects and constructors (which are factories for objects, similar to classes in other languages).</p> <h3> <a name="single-objects" href="#single-objects" class="anchor"> </a> Single Objects </h3> <p>Like all values, objects have properties. You could, in fact, consider an object to be a set of properties, where each property is a (key, value) pair. The key is a string, and the value is any JavaScript value.</p> <p>In JavaScript, you can directly create plain objects, via object literals:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>'use strict'; var jane = { name: 'Jane', describe: function () { return 'Person named '+this.name; } }; </code></pre></div> <p></p> <p>The preceding object has the properties name and describe. You can read (“get”) and write (“set”) properties:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; jane.name // get 'Jane' &gt; jane.name = 'John'; // set &gt; jane.newProperty = 'abc'; // property created automatically </code></pre></div> <p></p> <p>Function-valued properties such as describe are called methods. They use this to refer to the object that was used to call them:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; jane.describe() // call method 'Person named John' &gt; jane.name = 'Jane'; &gt; jane.describe() 'Person named Jane' </code></pre></div> <p></p> <p>The in operator checks whether a property exists:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; 'newProperty' in jane true &gt; 'foo' in jane false </code></pre></div> <p></p> <p>If you read a property that does not exist, you get the value undefined. Hence, the previous two checks could also be performed like this:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; jane.newProperty !== undefined true &gt; jane.foo !== undefined false </code></pre></div> <p></p> <p>The delete operator removes a property:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; delete jane.newProperty true &gt; 'newProperty' in jane false </code></pre></div> <p></p> <h3> <a name="arbitrary-property-keys" href="#arbitrary-property-keys" class="anchor"> </a> Arbitrary Property Keys </h3> <p>A property key can be any string. So far, we have seen property keys in object literals and after the dot operator. However, you can use them that way only if they are identifiers (see Identifiers and Variable Names). If you want to use other strings as keys, you have to quote them in an object literal and use square brackets to get and set the property:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; var obj = { 'not an identifier': 123 }; &gt; obj['not an identifier'] 123 &gt; obj['not an identifier'] = 456; </code></pre></div> <p></p> <p>Square brackets also allow you to compute the key of a property:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; var obj = { hello: 'world' }; &gt; var x = 'hello'; &gt; obj[x] 'world' &gt; obj['hel'+'lo'] 'world' </code></pre></div> <p></p> <h3> <a name="extracting-methods" href="#extracting-methods" class="anchor"> </a> Extracting Methods </h3> <p>If you extract a method, it loses its connection with the object. On its own, the function is not a method anymore, and this has the value undefined (in strict mode).</p> <p>As an example, let’s go back to the earlier object jane:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>'use strict'; var jane = { name: 'Jane', describe: function () { return 'Person named '+this.name; } }; </code></pre></div> <p></p> <p>We want to extract the method describe from jane, put it into a variable func, and call it. However, that doesn’t work:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; var func = jane.describe; &gt; func() TypeError: Cannot read property 'name' of undefined </code></pre></div> <p></p> <p>The solution is to use the method bind() that all functions have. It creates a new function whose this always has the given value:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; var func2 = jane.describe.bind(jane); &gt; func2() 'Person named Jane' </code></pre></div> <p></p> <h3> <a name="functions-inside-a-method" href="#functions-inside-a-method" class="anchor"> </a> Functions Inside a Method </h3> <p>Every function has its own special variable this. This is inconvenient if you nest a function inside a method, because you can’t access the method’s this from the function. The following is an example where we call forEach with a function to iterate over an array:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>var jane = { name: 'Jane', friends: [ 'Tarzan', 'Cheeta' ], logHiToFriends: function () { 'use strict'; this.friends.forEach(function (friend) { // `this` is undefined here console.log(this.name+' says hi to '+friend); }); } } </code></pre></div> <p></p> <p>Calling logHiToFriends produces an error:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; jane.logHiToFriends() TypeError: Cannot read property 'name' of undefined </code></pre></div> <p></p> <p>Let’s look at two ways of fixing this. First, we could store this in a different variable:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>logHiToFriends: function () { 'use strict'; var that = this; this.friends.forEach(function (friend) { console.log(that.name+' says hi to '+friend); }); } </code></pre></div> <p></p> <p>Or, forEach has a second parameter that allows you to provide a value for this:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>logHiToFriends: function () { 'use strict'; this.friends.forEach(function (friend) { console.log(this.name+' says hi to '+friend); }, this); } </code></pre></div> <p></p> <p>Function expressions are often used as arguments in function calls in JavaScript. Always be careful when you refer to this from one of those function expressions.</p> <h2> <a name="constructors-factories-for-objects" href="#constructors-factories-for-objects" class="anchor"> </a> Constructors: Factories for Objects </h2> <p>Until now, you may think that JavaScript objects are only maps from strings to values, a notion suggested by JavaScript’s object literals, which look like the map/dictionary literals of other languages. However, JavaScript objects also support a feature that is truly object-oriented: inheritance. This section does not fully explain how JavaScript inheritance works, but it shows you a simple pattern to get you started. Consult Chapter 17 if you want to know more.</p> <p>In addition to being “real” functions and methods, functions play another role in JavaScript: they become constructors—factories for objects—if invoked via the new operator. Constructors are thus a rough analog to classes in other languages. By convention, the names of constructors start with capital letters. For example:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>// Set up instance data function Point(x, y) { this.x = x; this.y = y; } // Methods Point.prototype.dist = function () { return Math.sqrt(this.x*this.x + this.y*this.y); }; </code></pre></div> <p></p> <p>We can see that a constructor has two parts. First, the function Point sets up the instance data. Second, the property Point.prototype contains an object with the methods. The former data is specific to each instance, while the latter data is shared among all instances.</p> <p>To use Point, we invoke it via the new operator:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; var p = new Point(3, 5); &gt; p.x 3 &gt; p.dist() 5.830951894845301 </code></pre></div> <p></p> <p>p is an instance of Point:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; p instanceof Point true </code></pre></div> <p></p> <h3> <a name="arrays" href="#arrays" class="anchor"> </a> Arrays </h3> <p>Arrays are sequences of elements that can be accessed via integer indices starting at zero.</p> <h3> <a name="array-literals" href="#array-literals" class="anchor"> </a> Array Literals </h3> <p>Array literals are handy for creating arrays:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; var arr = [ 'a', 'b', 'c' ]; </code></pre></div> <p></p> <p>The preceding array has three elements: the strings &#39;a&#39;, &#39;b&#39;, and &#39;c&#39;. You can access them via integer indices:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; arr[0] 'a' &gt; arr[0] = 'x'; &gt; arr [ 'x', 'b', 'c' ] </code></pre></div> <p></p> <p>The length property indicates how many elements an array has. You can use it to append elements and to remove elements:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; var arr = ['a', 'b']; &gt; arr.length 2 &gt; arr[arr.length] = 'c'; &gt; arr [ 'a', 'b', 'c' ] &gt; arr.length 3 &gt; arr.length = 1; &gt; arr [ 'a' ] </code></pre></div> <p></p> <p>The in operator works for arrays, too:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; var arr = [ 'a', 'b', 'c' ]; &gt; 1 in arr // is there an element at index 1? true &gt; 5 in arr // is there an element at index 5? false </code></pre></div> <p></p> <p>Note that arrays are objects and can thus have object properties:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; var arr = []; &gt; arr.foo = 123; &gt; arr.foo 123 </code></pre></div> <p></p> <h3> <a name="array-methods" href="#array-methods" class="anchor"> </a> Array Methods </h3> <p>Arrays have many methods (see Array Prototype Methods). Here are a few examples:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; var arr = [ 'a', 'b', 'c' ]; &gt; arr.slice(1, 2) // copy elements [ 'b' ] &gt; arr.slice(1) [ 'b', 'c' ] &gt; arr.push('x') // append an element 4 &gt; arr [ 'a', 'b', 'c', 'x' ] &gt; arr.pop() // remove last element 'x' &gt; arr [ 'a', 'b', 'c' ] &gt; arr.shift() // remove first element 'a' &gt; arr [ 'b', 'c' ] &gt; arr.unshift('x') // prepend an element 3 &gt; arr [ 'x', 'b', 'c' ] &gt; arr.indexOf('b') // find the index of an element 1 &gt; arr.indexOf('y') -1 &gt; arr.join('-') // all elements in a single string 'x-b-c' &gt; arr.join('') 'xbc' &gt; arr.join() 'x,b,c' </code></pre></div> <p></p> <h3> <a name="iterating-over-arrays" href="#iterating-over-arrays" class="anchor"> </a> Iterating over Arrays </h3> <p>There are several array methods for iterating over elements (see Iteration (Nondestructive)). The two most important ones are forEach and map.</p> <p>forEach iterates over an array and hands the current element and its index to a function:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>[ 'a', 'b', 'c' ].forEach( function (elem, index) { // (1) console.log(index + '. ' + elem); }); </code></pre></div> <p></p> <p>The preceding code produces the following output:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>0. a 1. b 2. c </code></pre></div> <p></p> <p>Note that the function in line (1) is free to ignore arguments. It could, for example, only have the parameter elem.</p> <p>map creates a new array by applying a function to each element of an existing array:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; [1,2,3].map(function (x) { return x*x }) [ 1, 4, 9 ] </code></pre></div> <p></p> <h3> <a name="regular-expressions" href="#regular-expressions" class="anchor"> </a> Regular Expressions </h3> <p>JavaScript has built-in support for regular expressions. They are delimited by slashes:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>/^abc$/ /[A-Za-z0-9]+/ </code></pre></div> <p></p> <h3> <a name="method-test-is-there-a-match" href="#method-test-is-there-a-match" class="anchor"> </a> Method test(): Is There a Match? </h3> <p></p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; /^a+b+$/.test('aaab') true &gt; /^a+b+$/.test('aaa') false </code></pre></div> <p></p> <h3> <a name="method-exec-match-and-capture-groups" href="#method-exec-match-and-capture-groups" class="anchor"> </a> Method exec(): Match and Capture Groups </h3> <p></p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; /a(b+)a/.exec('_abbba_aba_') [ 'abbba', 'bbb' ] </code></pre></div> <p></p> <p>The returned array contains the complete match at index 0, the capture of the first group at index 1, and so on. There is a way (discussed in RegExp.prototype.exec: Capture Groups) to invoke this method repeatedly to get all matches.</p> <h3> <a name="method-replace-search-and-replace" href="#method-replace-search-and-replace" class="anchor"> </a> Method replace(): Search and Replace </h3> <p></p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; '&lt;a&gt; &lt;bbb&gt;'.replace(/&lt;(.*?)&gt;/g, '[$1]') '[a] [bbb]' </code></pre></div> <p></p> <p>The first parameter of replace must be a regular expression with a /g flag; otherwise, only the first occurrence is replaced. There is also a way (as discussed in String.prototype.replace: Search and Replace) to use a function to compute the replacement.</p> <h2> <a name="math" href="#math" class="anchor"> </a> Math </h2> <p>Math is an object with arithmetic functions. Here are some examples:<br> </p> <div class="highlight"><pre class="highlight plaintext"><code>&gt; Math.abs(-2) 2 &gt; Math.pow(3, 2) // 3 to the power of 2 9 &gt; Math.max(2, -1, 5) 5 &gt; Math.round(1.9) 2 &gt; Math.PI // pre-defined constant for π 3.141592653589793 &gt; Math.cos(Math.PI) // compute the cosine for 180° -1 </code></pre></div> <p></p> <p>From: <a href="https://blog.mathquant.com/2019/04/26/4-1-javascript-language-quick-start.html">https://blog.mathquant.com/2019/04/26/4-1-javascript-language-quick-start.html</a></p>

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .