Hello World
-
The
type
andlanguage
attributes are not required. -
The benefit of a separate file is that the browser will download it and store it in its cache. Other pages that reference the same script will take it from the cache instead of downloading it, so the file is actually downloaded only once.
-
If
src
is set, the script content is ignored.<script src="file.js"> alert(1); // the content is ignored, because src is set </script>
Semicolons
In most cases, a newline implies a semicolon. But “in most cases” does not mean “always”!
There are cases when a newline does not mean a semicolon. For example:
alert(3 +
1
+ 2);
Now let’s remove the semicolon after the alert
:
alert("Hello")
[1, 2].forEach(alert);
JavaScript does not assume a semicolon before square brackets [...]
. So, the code in the last example is treated as a single statement.
alert("Hello")[1, 2].forEach(alert);
We recommend putting semicolons between statements even if they are separated by newlines. This rule is widely adopted by the community.
Strict Mode
Modern JavaScript supports “classes” and “modules” – advanced language structures (we’ll surely get to them), that enable use strict
automatically. So we don’t need to add the "use strict"
directive, if we use them.
So, for now "use strict";
is a welcome guest at the top of your scripts. Later, when your code is all in classes and modules, you may omit it.
Data Types
We can put any type in a variable. For example, a variable can at one moment be a string and then store a number:
// no error
let message = "hello";
message = 123456;
Programming languages that allow such things, such as JavaScript, are called “dynamically typed”, meaning that there exist data types, but variables are not bound to any of them.
Number
Besides regular numbers, there are so-called “special numeric values” which also belong to this data type: Infinity
, -Infinity
and NaN
:
-
Infinity
: represents the mathematical Infinity ∞. It is a special value that’s greater than any number. -
NaN
: represents a computational error.NaN
is sticky. Any further mathematical operation onNaN
returnsNaN
:alert( NaN + 1 ); // NaN alert( 3 * NaN ); // NaN alert( "not a number" / 2 - 1 ); // NaN
So, if there’s a NaN
somewhere in a mathematical expression, it propagates to the whole result (there’s only one exception to that: NaN ** 0
is 1
).
BigInt
The “number” type cannot safely represent integer values larger than (253-1)
(that’s 9007199254740991
), or less than -(253-1)
for negatives.
To be really precise, the “number” type can store larger integers (up to 1.7976931348623157 * 10308
), but outside of the safe integer range ±(253-1)
there’ll be a precision error, because not all digits fit into the fixed 64-bit storage. So an “approximate” value may be stored.
For example, these two numbers (right above the safe range) are the same:
console.log(9007199254740991 + 1); // 9007199254740992
console.log(9007199254740991 + 2); // 9007199254740992
BigInt
type was recently added to the language to represent integers of arbitrary length.
A BigInt
value is created by appending n
to the end of an integer:
// the "n" at the end means it's a BigInt
const bigInt = 1234567890123456789012345678901234567890n;
Null and Undefined
Normally, one uses null
to assign an “empty” or “unknown” value to a variable, while undefined
is reserved as a default initial value for unassigned things.
Objects and Symbols
All other types are called “primitive” because their values can contain only a single thing (be it a string or a number or whatever). In contrast, objects are used to store collections of data and more complex entities.
Typeof
The result of typeof null
is "object"
. That’s an officially recognized error in typeof
, coming from very early days of JavaScript and kept for compatibility.
Functions belong to the object type. But typeof
treats them differently, returning "function"
.
Info
You may also come across another syntax:
typeof(x)
. It’s the same astypeof x
.To put it clear:
typeof
is an operator, not a function. The parentheses here aren’t a part oftypeof
. It’s the kind of parentheses used for mathematical grouping.
Alert, Prompt and Confirm
All these methods are modal: they pause script execution and don’t allow the visitor to interact with the rest of the page until the window has been dismissed.
Type Conversion
Numeric Conversion
– Occurs in math operations. Can be performed with Number(value)
.
The conversion follows the rules:
Value | Becomes… |
---|---|
undefined | NaN |
null | 0 |
true and false | 1 and 0 |
string | Whitespaces (includes spaces, tabs \t , newlines \n etc.) from the start and end are removed. If the remaining string is empty, the result is 0 . Otherwise, the number is “read” from the string. An error gives NaN . |
Examples:
alert( Number(" 123 ") ); // 123
alert( Number("123z") ); // NaN (error reading a number at "z")
alert( Number(true) ); // 1
alert( Number(false) ); // 0
Boolean Conversion
– Occurs in logical operations. Can be performed with Boolean(value)
.
Follows the rules:
Value | Becomes… |
---|---|
0 , null , undefined , NaN , "" | false |
any other value | true |
Space characters are trimmed off string start and end when a string is converted to a number. Here the whole string consists of space characters, such as \t
, \n
and a “regular” space between them. So, similarly to an empty string, it becomes 0
.
Example:
" \t \n" - 2 = -2 // (7)
On the other hand, the equality check ==
for undefined
and null
is defined such that, without any conversions, they equal each other and don’t equal anything else. That’s why (2) null == 0
is false in the following example:
alert( null > 0 ); // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true
Operators
Unary operators are higher than corresponding binary ones.
Example:
// both values converted to numbers before the binary plus
alert( +apples + +oranges ); // 5
Increment/decrement
The prefix form returns the new value while the postfix form returns the old value (prior to increment/decrement).
To see the difference, here’s an example:
let counter = 1;
let a = ++counter; // (*)
alert(a); // 2
Now, let’s use the postfix form:
let counter = 1;
let a = counter++; // (*) changed ++counter to counter++
alert(a); // 1
To summarize:
If the result of increment/decrement is not used, there is no difference in which form to use:
let counter = 0;
counter++;
++counter;
alert( counter ); // 2, the lines above did the same
If we’d like to increase a value and immediately use the result of the operator, we need the prefix form:
let counter = 0;
alert( ++counter ); // 1
If we’d like to increment a value but use its previous value, we need the postfix form:
let counter = 0;
alert( counter++ ); // 0
The operators ++/--
can be used inside expressions as well. Their precedence is higher than most other arithmetical operations.
OR and AND
Precedence of AND &&
is higher than OR ||
The precedence of AND &&
operator is higher than OR ||
.
So the code a && b || c && d
is essentially the same as if the &&
expressions were in parentheses: (a && b) || (c && d)
.
Nullish
The important difference between ||
and ??
is that:
||
returns the first truthy value.??
returns the first defined value.
For example, consider this:
let height = 0;
alert(height || 100); // 100
alert(height ?? 100); // 0
The precedence of the ??
operator is the same as ||
. That means that, just like ||
, the nullish coalescing operator ??
is evaluated before =
and ?
, but after most other operations, such as +
, *
.
Resources
- https://javascript.info/first-steps
- https://javascript.info/data-types
- https://javascript.info/object-basics
- https://javascript.info/async
- https://javascript.info/error-handling
- https://javascript.info/fetch
- https://javascript.info/fetch-api
- https://javascript.info/fetch-crossorigin
- https://javascript.info/formdata
- https://javascript.info/document
- https://javascript.info/events
- https://javascript.info/event-details
- https://javascript.info/forms-controls
- https://javascript.info/loadin