JavaScript Fundamentals
JavaScript programs can be inserted almost anywhere into an HTML document using
the <script> tag.
The <script> tag contains JavaScript code which is automatically executed when
the browser processes the tag.
<script type="text/javascript"><!--
...
//--></script>
External Scripts
<script src="/path/to/[Link]"></script>
<script src="[Link]
script>
“use strict”
when ECMAScript 5 (ES5) appeared. It added new features to the language and
modified some of the existing ones. To keep the old code working, most such
modifications are off by default. You need to explicitly enable them with a special
directive: "use strict".
// note: no "use strict" in this example
num = 5; // the variable "num" is created if it didn't exist
alert(num); // 5
"use strict";
num = 5; // error: num is not defined
Var and let
let user = 'John', age = 25, message = 'Hello';
let user = 'John';
let age = 25;
let message = 'Hello';
var message = 'Hello';
alert, prompt, confirm
alert("Hello");
let age = prompt('How old are you?', 100);
let isBoss = confirm("Are you the boss?");
Type Conversions
let age = Number("an arbitrary string instead of a number");
alert(age); // NaN, conversion failed
alert( Number(" 123 ") ); // 123
alert( Number("123z") ); // NaN (error reading a number at "z")
alert( Number(true) ); // 1
alert( Number(false) ); // 0
alert( Boolean(1) ); // true
alert( Boolean(0) ); // false
alert( Boolean("hello") ); // true
alert( Boolean("") ); // false
alert( Boolean("0") ); // true
alert( Boolean(" ") ); // spaces, also true (any non-empty string is true)
Basic operators, maths
let x = 1;
x = -x;
alert( x ); // -1, unary negation was applied
let x = 1, y = 3;
alert( y - x ); // 2, binary minus subtracts values
alert( 5 % 2 ); // 1, the remainder of 5 divided by 2
alert( 8 % 3 ); // 2, the remainder of 8 divided by 3
alert( 8 % 4 ); // 0, the remainder of 8 divided by 4
alert( 2 ** 2 ); // 2² = 4
alert( 2 ** 3 ); // 2³ = 8
alert( 2 ** 4 ); // 2⁴ = 16
alert( 4 ** (1/2) ); // 2 (power of 1/2 is the same as a square root)
alert( 8 ** (1/3) ); // 2 (power of 1/3 is the same as a cubic root)
alert( '1' + 2 ); // "12"
alert( 2 + '1' ); // "21"
alert(2 + 2 + '1' ); // "41" and not "221"
alert('1' + 2 + 2); // "122" and not "14"
alert( 6 - '2' ); // 4, converts '2' to a number
alert( '6' / '2' ); // 3, converts both operands to numbers
Comparisons
alert( 2 > 1 ); // true (correct)
alert( 2 == 1 ); // false (wrong)
alert( 2 != 1 ); // true (correct)
alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
1. G is the same as G.
2. l is the same as l.
3. o is greater than e. Stop here. The first string is greater.
alert( 'Bee' > 'Be' ); // true
alert( '2' > 1 ); // true, string '2' becomes a number 2
alert( '01' == 1 ); // true, string '01' becomes a number 1
alert( true == 1 ); // true
alert( false == 0 ); // true
let a = 0;
alert( Boolean(a) ); // false
let b = "0";
alert( Boolean(b) ); // true
alert(a == b); // true!
alert( 0 == false ); // true
alert( '' == false ); // true
A strict equality operator === checks the equality without type
conversion.
alert( 0 === false ); // false, because the types are different
let firstName = "";
let lastName = "";
let nickName = "SuperCoder";
var xyz = firstname || ‘No Name’
alert( firstName || lastName || nickName || "Anonymous"); // SuperCoder
let user;
alert(user ?? "Anonymous"); // Anonymous (user is undefined)
let user = "John";
alert(user ?? "Anonymous"); // John (user is not null/undefined)
let firstName = null;
let lastName = null;
let nickName = "Supercoder";
// shows the first defined value:
Let zycdsgsd = firstName ?? ‘No Name’
alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder
let firstName = null;
let lastName = null;
let nickName = "Supercoder";
// shows the first truthy value:
alert(firstName || lastName || nickName || "Anonymous"); // Supercoder
let height = 0;
alert(height || 100); // 100
alert(height ?? 100); // 0
The height || 100 checks height for being a falsy value, and it’s 0, falsy
indeed.
o so the result of || is the second argument, 100.
The height ?? 100 checks height for being null/undefined, and it’s not,
o so the result is height “as is”, that is 0.
While loop
let i = 0;
while (i < 3) { // shows 0, then 1, then 2
alert( i );
i++;
}
let i = 3;
while (i) { // when i becomes 0, the condition becomes falsy, and the loop stops
alert( i );
i--;
}
let i = 0;
do {
alert( i );
i++;
} while (i < 3);
for (let i = 0; i < 3; i++) { // shows 0, then 1, then 2
alert(i);
}
let a = 2 + 2;
switch (a) {
case 3:
alert( 'Too small' );
break;
case 4:
alert( 'Exactly!' );
break;
case 5:
alert( 'Too big' );
break;
default:
alert( "I don't know such values" );
}
switch (browser) {
case 'Edge':
alert( "You've got the Edge!" );
break;
case 'Chrome':
case 'Firefox':
case 'Safari':
case 'Opera':
alert( 'Okay we support these browsers too' );
break;
default:
alert( 'We hope that this page looks ok!' );
}
function showMessage() {
alert( 'Hello everyone!' );
}
showMessage();
let userName = 'John';
function showMessage() {
let message = 'Hello, ' + userName;
alert(message);
}
showMessage(); // Hello, John
function showMessage(from, text) { // parameters: from, text
alert(from + ': ' + text);
}
showMessage('Ann', 'Hello!'); // Ann: Hello!
function checkAge(age) {
if (age >= 18) {
return true;
} else {
return confirm('Do you have permission from your parents?');
}
}
let age = prompt('How old are you?', 18);
if ( checkAge(age) ) {
alert( 'Access granted' );
} else {
alert( 'Access denied' );
}
function sayHi() {
alert( "Hello" );
}
sayHi();
let sayHi = function() {
alert( "Hello" );
};
sayHi();
function sayHi() { // (1) create
alert( "Hello" );
}
let func = sayHi; // (2) copy
func(); // Hello // (3) run the copy (it works)!
sayHi(); // Hello // this still works too (why wouldn't it)
Call back functions
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
function showOk() {
alert( "You agreed." );
}
function showCancel() {
alert( "You canceled the execution." );
}
// usage: functions showOk, showCancel are passed as arguments to ask
ask("Do you agree?", showOk, showCancel);
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
ask(
"Do you agree?",
function() { alert("You agreed."); },
function() { alert("You canceled the execution."); }
);
Arrow functions
Function sum(a, b) {
Let c = a + b;
}
let sum = (a, b) => a + b;
/* This arrow function is a shorter form of:
let sum = function(a, b) {
return a + b;
};
*/
alert( sum(1, 2) ); // 3
let sum = (a, b) => { // the curly brace opens a multiline function
let result = a + b;
return result; // if we use curly braces, then we need an explicit "return"
};
alert( sum(1, 2) ); // 3
Debugger
function hello(name) {
let phrase = `Hello, ${name}!`;
debugger; // <-- the debugger stops here
say(phrase);
}
Comments
// This code will do this thing (...) and that thing (...)
// ...and who knows what else...
/**
* Returns x raised to the n-th power.
*
* @param {number} x The number to raise.
* @param {number} n The power, must be a natural number.
* @return {number} x raised to the n-th power.
*/
let user = new Object(); // "object constructor" syntax
let user = {}; // "object literal" syntax
let user = { // an object
name: "John", // by key "name" store value "John"
age: 30 // by key "age" store value 30
};
Object References and copying
primitive, such as a string.
Here we put a copy of message into phrase:
let message = "Hello!";
let phrase = message;
message=”hello”
As a result we have two independent variables, each one storing the string "Hello!".
let user = { name: "John" };
let admin = user; // copy the reference
let user = { name: 'John' };
let admin = user;
[Link] = 'Pete'; // changed by the "admin" reference
alert([Link]); // 'Pete', changes are seen from the "user" reference
let user = {
name: "John",
age: 30
};
[Link] = function() {
alert("Hello!");
};
[Link](); // Hello!
let user = {
name: "John",
age: 30,
sayHi() {
// "this" is the "current object"
alert([Link]);
}
};
[Link](); // John
let str = "Hello";
alert( [Link]() ); // HELLO
let n = 1.23456;
alert( [Link](2) ); // 1.23
let num = Number("123"); // convert a string to number
Strings can be enclosed within either single quotes, double quotes or backticks:
let single = 'single-quoted';
let double = "double-quoted";
let backticks = `backticks`;
let abc = `${ single }${ double } `
function sum(a, b) {
return a + b;
}
alert(`1 + 2 = ${sum(1, 2)}.`); // 1 + 2 = 3.
let fruits = ["Apple", "Orange", "Pear"];
alert( [Link]() ); // remove "Pear" and alert it
alert( fruits ); // Apple, Orange
let fruits = ["Apple", "Orange"];
[Link]("Pear");
alert( fruits ); // Apple, Orange, Pear
let fruits = ["Apple", "Orange", "Pear"];
alert( [Link]() ); // remove Apple and alert it
alert( fruits ); // Orange, Pear
let fruits = ["Orange", "Pear"];
[Link]('Apple');
alert( fruits ); // Apple, Orange, Pear
let fruits = ["Apple"];
[Link]("Orange", "Peach");
[Link]("Pineapple", "Lemon");
// ["Pineapple", "Lemon", "Apple", "Orange", "Peach"]
alert( fruits );
let fruits = ["Banana"]
let arr = fruits; // copy by reference (two variables reference the same array)
alert( arr === fruits ); // true
[Link]("Pear"); // modify the array by reference
alert( fruits ); // Banana, Pear - 2 items now
let arr = ["I", "go", "home"];
delete arr[1]; // remove "go"
alert( arr[1] ); // undefined
// now arr = ["I", , "home"];
alert( [Link] ); // 3
let arr = ["I", "study", "JavaScript"];
[Link](1, 1); // from index 1 remove 1 element
alert( arr ); // ["I", "JavaScript"]
let arr = [1, 2];
// create an array from: arr and [3,4]
alert( [Link]([3, 4]) ); // 1,2,3,4
let arr = [1, 0, false];
alert( [Link](0) ); // 1
alert( [Link](false) ); // 2
alert( [Link](null) ); // -1
alert( [Link](1) ); // true
0 1 2 3
let fruits = ['Apple', 'Orange', 'Apple', ‘Apple’]
alert( [Link]('Apple') ); // 0 (first Apple)
alert( [Link]('Apple') ); // 3 (last Apple)
export class user {
id: string;
}
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"},
{id: 10, name: "John"},
];
firstorDefault
let user = [Link](item => [Link] == 10);
alert([Link]); // John
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"},
{id: 4, name: "John"}
];
// Find the index of the first John
alert([Link](user => [Link] == 'John')); // 0
// Find the index of the last John
alert([Link](user => [Link] == 'John')); // 3
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];
// returns array of the first two users
let someUsers = [Link](item => [Link] < 3);
someUsers = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
];
alert([Link]); // 2
let lengths = ["kjhkgj", "wsetwetwetwt", "awetwtwet"].map(item => [Link]);
alert(lengths); // 5,7,6
someUsers = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
];
[Link](m => [Link])
let arr = [ 1, 2, 15 ];
[Link](function(a, b) { return a - b; }); //ascending
alert(arr); // 1, 2, 15
[Link](function(a, b) { return b - a; }); //descending
[Link]( (a, b) => a - b );
let countries = ['Österreich', 'Andorra', 'Vietnam'];
alert( [Link]( (a, b) => a > b ? 1 : -1) ); // Andorra, Vietnam, Österreich
(wrong)
alert( [Link]( (a, b) => [Link](b) ) ); // Andorra,Österreich,Vietnam
(correct!)
let arr = [1, 2, 3, 4, 5];
[Link]();
alert( arr ); // 5,4,3,2,1
let names = 'Bilbo, Gandalf, Nazgul';
let arr = [Link](', ');
for (let name of arr) {
alert( `A message to ${name}.` ); // A message to Bilbo (and other names)
}
let str = "test";
alert( [Link]('') ); // [‘t’,’e’,’s’,’t’]
var abc = ‘Hi All good morning’,
alert([Link](‘ ’)) // HI, All, Good, Morning
let arr = ['Bilbo', 'Gandalf', 'Nazgul'];
let str = [Link](';'); // glue the array into a string using ;
alert( str ); // Bilbo;Gandalf;Nazgul
var abc =[ ‘HI’, ‘All’, ‘Good’, ‘Morning’];
alert([Link](‘ ’)) // Hi All Good Morning
let arr = [1, 2, 3, 4, 5];
let result = [Link]((sum, current) => sum + current, 0);
alert(result); // 15
MAP is a collection of keyed data items, just like an Object. But the main difference
is that Map allows keys of any type.
let map = new Map();
[Link]('1', 'str1'); // a string key
[Link](1, 'num1'); // a numeric key
[Link](true, 'bool1'); // a boolean key
// remember the regular Object? it would convert keys to string
// Map keeps the type, so these two are different:
alert( [Link](1) ); // 'num1'
alert( [Link]('1') ); // 'str1'
alert( [Link] ); // 3
let now = new Date();
alert( now ); // shows current date/time
Spread parameters
function sumAll(...args) { // args is the name for the array
let sum = 0;
for (let arg of args) sum += arg;
return sum;
}
alert( sumAll(1) ); // 1
alert( sumAll(1, 2) ); // 3
alert( sumAll(1, 2, 3) ); // 6
function sumAll(fName, lName,...args) { // args is the name for the array
let sum = 0;
for (let arg of args) sum += arg;
return sum;
}
function showName(firstName, lastName, ...titles) {
alert( firstName + ' ' + lastName ); // Julius Caesar
// the rest go into titles array
// i.e. titles = ["Consul", "Imperator"]
alert( titles[0] ); // Consul
alert( titles[1] ); // Imperator
alert( [Link] ); // 2
}
showName("Julius", "Caesar", "Consul", "Imperator", ‘’);
function sayHi() {
alert('Hello');
}
setTimeout(sayHi, 1000);
Above code calls sayHi() after one second
// repeat with the interval of 2 seconds
let timerId = setInterval(() => alert('tick'), 2000);
try {
alert('Start of try runs'); // (1) <--
// ...no errors here
alert('End of try runs'); // (2) <--
} catch (err) {
alert('Catch is ignored, because there are no errors'); // (3)
}
try {
alert('Start of try runs'); // (1) <--
lalala; // error, variable is not defined!
alert('End of try (never reached)'); // (2)
} catch (err) {
alert(`Error has occurred!`); // (3) <--
}
Attributes and Properties
<body something="non-standard">
<script>
alert([Link]('something')); // non-standard
</script>
</body>
<!-- mark the div to show "name" here -->
<div show-info="name"></div>
<!-- and age here -->
<div show-info="age"></div>
<input type=”” show-info=”name”>
<script>
// the code finds an element with the mark and shows what's requested
let user = {
name: "Pete",
age: 25
};
for(let div of [Link]('[show-info]')) {
// insert the corresponding info into the field
let field = [Link]('show-info');
[Link] = user[field]; // first Pete into "name", then 25 into "age"
}
for(let txt of [Link]('[show-info]')) {
// insert the corresponding info into the field
let field = [Link]('show-info');
[Link] = user[field]; // first Pete into "name", then 25 into "age"
</script>
<div id="elem">
<div id="elem-content">Element</div>
</div>
<script>
// get the element
let elem = [Link]('elem');
// make its background red
[Link] = 'red';
</script>
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<script>
let div = [Link]('div');
[Link] = "alert";
[Link] = "<strong>Hi there!</strong> You've read an important
message.";
[Link](div);
</script>
output
<body>
<div class=”alert”> "<strong>Hi there!</strong> You've read an important
message.</div>
</body>
<script>
function countRabbits() {
for(let i=1; i<=3; i++) {
alert("Rabbit number " + i);
}
}
</script>
<input type="button" onclick="countRabbits()" value="Count rabbits!">
<input id="elem" type="button" value="Click me">
<script>
[Link] = function() {
alert('Thank you');
};
</script>
<input type="button" id="button" value="Button">
<script>
[Link] = function() {
alert('Click!');
};
</script>
<input type="text" onchange="alert([Link])">
<input type="button" value="Button">
<select onchange="alert([Link])">
<option value="">Select something</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
Document Content Load
[Link]("DOMContentLoaded", ready);
// not "[Link] = ..."
For instance:
<script>
function ready() {
alert('DOM is ready');
// image is not yet loaded (unless it was cached), so the size is 0x0
alert(`Image size: ${[Link]}x${[Link]}`);
}
[Link]("DOMContentLoaded", ready);
</script>
<img id="img" src="[Link]
In the example, the DOMContentLoaded handler runs when the document is loaded,
so it can see all the elements, including <img> below.
Onload
The load event on the window object triggers when the whole page is loaded
including styles, images and other resources. This event is available via
the onload property.
The example below correctly shows image sizes, because [Link] waits for
all images:
<script>
[Link] = function() { // can also use [Link]('load',
(event) => {
alert('Page loaded');
// image is loaded at this time
alert(`Image size: ${[Link]}x${[Link]}`);
};
</script>
<img id="img" src="[Link]
Form properities and methods
<form name="my">
<input name="one" value="1">
<input name="two" value="2">
</form>
{
One: 1,
Two: 2
}
<script>
// get the form
let form = [Link]; // <form name="my"> element
// get the element
let elem = [Link]; // <input name="one"> element
alert([Link]); // 1
</script>
<form>
<input type="radio" name="age" value="10">
<input type="radio" name="age" value="20">
</form>
<script>
let form = [Link][0];
let ageElems = [Link];
alert(ageElems[0]); // [object HTMLInputElement]
</script>
Onfocus
<style>
.invalid { border-color: red; }
#error { color: red }
</style>
Your email please: <input type="email" id="input">
<div id="error"></div>
<script>
[Link] = function() {
if () { // not email
[Link]('invalid');
[Link] = 'Please enter a correct email.'
}
};
[Link] = function() {
if ([Link]('invalid')) {
// remove the "error" indication, because the user wants to re-enter something
[Link]('invalid');
[Link] = "";
}
};
</script>
Onblur
<style>
.error {
background: red;
}
</style>
Your email please: <input type="email" id="input">
<input type="text" style="width:220px" placeholder="make email invalid and try
to focus here">
<script>
[Link] = function() {
if () { // not email
// show the error
[Link]("error");
// ...and put the focus back
[Link]();
} else {
[Link]("error");
}
};
</script>
Onchange
<input type="text" onchange="alert([Link])">
<input type="button" value="Button">
<select onchange="alert([Link])">
<option value="">Select something</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
Input event
<input type="text" id="input"> oninput: <span id="result"></span>
<script>
[Link] = function() {
[Link] = [Link];
};
</script>
Oncut, onpaste, oncopy
<input type="text" id="input">
<script>
[Link] = function(event) {
alert("paste: " + [Link]('text/plain'));
[Link]();
};
[Link] = [Link] = function(event) {
alert([Link] + '-' + [Link]());
[Link]();
};
</script>
Onsubmit
<form onsubmit="alert('submit!');return false">
First: Enter in the input field <input type="text" value="text"><br>
Second: Click "submit": <input type="submit" value="Submit">
</form>
<!-- mark the div to show "name" here -->
<div show-info="name"></div>
<!-- and age here -->
<div show-info="age"></div>
<script>
// the code finds an element with the mark and shows what's requested
let user = {
name: "Pete",
age: 25
};
for(let div of [Link]('[show-info]')) {
// insert the corresponding info into the field
let field = [Link]('show-info');
[Link] = user[field]; // first Pete into "name", then 25 into "age"
}
</script>
<style>
/* styles rely on the custom attribute "order-state" */
.order[order-state="new"] {
color: green;
}
.order[order-state="pending"] {
color: blue;
}
.order[order-state="canceled"] {
color: red;
}
</style>
<div class="order" order-state="new">
A new order.
</div>
<div class="order" order-state="pending">
A pending order.
</div>
<div class="order" order-state="canceled">
A canceled order.
</div>
[Link] = "[Link] // redirect the browser to another URL
[Link]("[Link] "test", "width=200,height=100");