A review of many of the building blocks of JavaScript.
Although ECMAScript 6 (ES6) is the latest standard, adopted in June of 2015, we'll mostly focus on features from the ES5 standard. Some of the references in this document may include descriptions of ES6 features. These features will usually be denoted with (new in ECMAScript 6)
in the main text or with a flask icon in the navigation sidebar.
let
and const
are the primary ES6 features introduced in this training. In order to to use these features, we'll need to be in strict mode.
By the end of this lesson, students should be able to:
- List all 5 JavaScript primitives and give an example of each
- Identify the operator in an expression and explain what it does
- Define variable and contrast with value
- Evaluate simple JavaScript by inspection
- Write simple scripts that use flow control
- Fork this repository (link in slack).
- Change to the directory
~/wdi/training
. - Clone the fork.
cd
into the cloned repository
Then:
$ git branch training
$ git checkout training
$ atom .
$ npm install
Note: when creating and then immediately switching to a branch you can use git checkout -b <new branch name>
.
ES5 has 5 primitive types: Number
, String
, Boolean
, null
, and undefined
.
Type | Examples |
---|---|
Number | -0 , NaN , Infinity |
String | '' , "The non-empty string." |
Boolean | true , false |
null | null |
undefined | undefined |
Primitive types represent immutable values. We'll contrast this with reference types in a later lesson.
The types Number and String both have large sets of possible values. Boolean has only two values and null and undefined each have just one.
The ES6 primitive type Symbol
is intentionally omitted.
Literals represent specific values in the source code. Some examples are 1
, 'A string'
, null
.
> dob;
Variables need to be declared.
> let dob;
Variables name storage for the value they contain. Because JavaScript is a dynamically typed language, you can assign a value of one type to a variable and then later assign a value of a different type to that same variable.
In JavaScript, null
represents the explicitly omitted value, whereas undefined
represents the default omitted value. Variables that have been declared but are uninitialized or unset have the value undefined
.
Operators come in three classes, unary, binary (the most common), and ternary (there is only one).
Operator precedence determines the order in which operators are evaluated. Operators with higher precedence are evaluated first.
Associativity determines the order in which operators of the same precedence are processed.
The following table lists a subset of the JavaScript operators from higher to lower precedence.
Type | Associativity | Operators |
---|---|---|
grouping | n/a | () |
postfix increment | n/a | ++ -- |
negation, numeric conversion, prefix increment, type |
right-to-left | ! - + ++ -- typeof |
multiplication, division | left-to-right | * / % |
addition, subtraction | left-to-right | + - |
relation, instance | left-to-right | < <= > ``>= instanceof` |
strict equality | left-to-right | === ``!===` |
logical and | left-to-right | && |
logical or | left-to-right | || |
conditional | right-to-left | ?: |
assignment | right-to-left | = += -= *= /= %= |
An expression is a combination of literals, variables, operators, function invocations and sub-expressions that are interpreted and produce a value. Not all such combinations produce sensible results.
The simplest expression is a variable or literal followed by a semicolon. More complicated expressions are formed by combining simpler expressions using operators.
An expression with all of the variables replaced with literals that are equal to the values of the variables will produce the same result.
We'll use Node.js as a REPL and script runner to evaluate expressions and explore JavaScript features.
- Read
- Evaluate
- Loop
$ node
> 'use strict';
>
What other tools could we use as a JavaScript REPL?
Are there benefits or drawbacks to using one over another?
What about a script runner?
Benefits or drawbacks with the options available?
Assignment changes the value of a variable.
let height;
height;
height = 77;
height;
let name;
name = 'Antony';
name;
Remember: JavaScript variables are untyped.
height = 76;
height = 'Antony';
Although it doesn't cause an error, avoid confusing code like the above.
Note: The increment and decrement operators assign their operand.
Constants must be initialized, assigned a value, when created. Uninitialized constants are a syntax error in Firefox. In Chrome or node they will always have the value undefined
.
const pi = 3.14159265359; // rounded
pi;
const e;
e = 2.71828182846; // rounded
e;
Simple calculations:
5 + 3;
7 - 2;
11 % 5;
Expressions with variables only change values with assignment.
height - 1;
height;
Now let's compare some common methods of counting.
let i;
i = 0;
i = i + 1;
i = 0;
i += 1;
++i;
i++;
i;
let givenName;
let surname;
let fullName;
givenName = 'Antony';
surname = 'Donovan';
fullName = givenName + ' ' + surname;
A boolean expression is a comparison (e.g. >
, >=
, ===
) or any value interpreted as a boolean. We'll use that fact when we get to flow control. Boolean expression combine using the logical and &&
and logical ||
operators.
let height = 62;
height === 60;
height > 72;
height = 76;
height > 72;
height > 72 && height < 78;
The logical operators 'short circuit', which means they stop evaluating operands as soon as the expression is false
for &&
, or true for ||
.
What do you think of when you here 'truthy' and 'falsy'?
The falsy list (everything else in JavaScript is truthy),
false
undefined
null
0 // and -0
NaN
'' // and "" - the empty string
Note: The negation of a truthy value is false
and the negation of a falsy value is true
.
let truthy;
let falsy;
truthy = 'A non-empty string';
falsy = 0;
!truthy;
!falsy;
The unary +
operator attempts to convert its operand to a Number. If unsuccessful the result is NaN
.
If either operand of the binary +
operator is a string the operator converts the other operator to a string. Some results of this conversion are more useful than others.
Note the different between 3 + 5 + ' times';
and 'times ' + 3 + 5
;?
The unary !
operator converts its operand to a boolean value.
For non-strict-equality comparisons with numbers, boolean values are coerced to 1
or 0
(from true
or false
respectively).
The if
statement:
'use strict';
//We'll learn about require later in the course
const ask = require('../lib/ask.js');
let name = ask('What\'s your name? ');
if (name === 'Antony') {
console.log('Hi, Antony!');
} else if (name === 'Jason') {
console.log('Hi, Jason!');
} else {
console.log('Hi, stranger.');
}
The while
loop:
'use strict';
//We'll learn about require later in the course
const ask = require('./ask.js');
let count = 0;
let answer = '';
while (answer !== 'Antony') {
answer = ask('Guess my name? ');
count = count + 1;
}
console.log('You got it in ' + count + ' tries!');
The for
loop:
for (let i = 0; i < 10; i++) {
console.log(i);
}
which is - almost - equivalent to:
let i = 0;
while (i < 10) {
console.log(i);
i++;
}
Nesting conditionals in loops:
for (let i = 0; i < 10; i++) {
if (i===5) {
console.log('five!');
}
}
See the following sections at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide
- Grammar and types
- Control flow and error handling
- Loops and iteration
- Expressions and operators
- Number and dates
- Text formatting