JavaScript is an interpreted (or just-in-time compiled) programming language with first-class functions.
It's a prototype-based, multi-paradigm, single-threaded, dynamic language, supporting object-oriented, imperative, and declarative (e.g. functional) programming styles.
It's most known as the scripting language for the Web.
When a web page is loaded in the browser, our code is running inside an execution environment (the browser tab).
A very common use of JavaScript is to dynamically modify HTML and CSS to update a user interface.
Although it started as a Web technology, JavaScript has since grown to be much more than that, and is now commonly found in both the client and server sides.
The most known tool for backend development in JS is Node.js.
Node is an open-source, cross-platform, back-end JavaScript runtime environment.
Node.js is built on Chrome's V8 engine (the JavaScript's interpreter built into the Google Chrome browser).
Node uses an event-drive, non-blocking I/O model that makes it lightweight and efficient.
PROS | CONS |
---|---|
- Fast Execution - Beginner friendly - Well documented - Language features like first-class functions, closures, prototypes, and object/array literals. |
- Public code - Compatibility issues (DOM) - Language features like implied globals, complex this binding, type coercion, falsy values, function scope, and others. |
Because JavaScript is deployed as source code, it will be publicly available.
One technique used to counteract this is to obfuscate the deployed code, making it vary hard to read and reverse-engineer.
// ORIGINAL CODE
console.log("Hello World!");
// OBFUSCATED CODE
var _0x5a9b=['1048708KvhfyS','Hello\x20World!','578650mpMCkd','693503mORuho','1548500vucrDU','867922wMLRDy','log','249059jGyHKq','1kVGFPF','118484jhQJRL'];var _0x24a4f2=_0x138d;
function _0x138d(_0x1dcd90,_0x44da07){return _0x138d=
function(_0x5a9b54,_0x138dcf){_0x5a9b54=_0x5a9b54-0x74;var _0x3f9394=_0x5a9b[_0x5a9b54];return _0x3f9394;},_0x138d(_0x1dcd90,_0x44da07);}(var _0x5b0577=_0x138d;
while(!![]){try{
var _0x1b7606=-parseInt(_0x5b0577(0x77))+-parseInt(_0x5b0577(0x7c))+-parseInt(_0x5b0577(0x79))+parseInt(_0x5b0577(0x7a))*parseInt(_0x5b0577(0x75))+-parseInt(_0x5b0577(0x7b))+parseInt(_0x5b0577(0x74))+parseInt(_0x5b0577(0x76));
if(_0x1b7606===_0xee4c5f)break;else _0x2a8c05['push'](_0x2a8c05['shift']());}
catch(_0x2fb212){_0x2a8c05['push'](_0x2a8c05['shift']());}}}(_0x5a9b,0x82fa0),console[_0x24a4f2(0x78)](_0x24a4f2(0x7d)));
BROWSER
EDITOR
NODE.JS
In JavaScript, a primitive is data that is not an object and has no methods. Everything that doesn't fall into this category is a structural data type, i.e., an object.
The available types are:
JavaScript is a loosely typed and dynamic language.
var a = 18; // a is a number
a = 2.6; // a is still a number
a = 'one'; // a is a string
a = true; // a is a boolean
The typeof operator returns a string indicating the type of the operand.
var a = 18;
console.log(typeof a);
// expected output: "number"
console.log(typeof 'number');
// expected output: "string"
console.log(typeof true);
// expected output: "boolean"
console.log(typeof b);
// expected output: "undefined", because b hasn't been declared
var c = null;
console.log(typeof c);
// expected output: "object"
Converting a value from one type to another is called casting when done explicitly, and coercion when done implicitly.
Type coercion is one of JavaScript's main features.
console.log(1 + 2 + '3'); // What's the result?
Coercion can be disabled on a boolean expression with the === operator, instead of the == operator.
Variables, typeof, and type coercion
In computer science, an object is a value in memory which is possibly referenced by an identifier (variable).
In JavaScript, objects can be seen as a collection of properties.
var obj = {
a: 23,
b: 'Tokyo',
c: {
d: true
}
};
There are multiple ways to access/modify an object's property.
var myObj = {
anotherObj: {
a: 12,
b: 'bicycle'
},
2: 'sunglasses'
};
console.log(myObj.anotherObj);
// { a: 12, b: 'bicycle' }
console.log(myObj['anotherObj']['a']);
console.log(myObj.anotherObj.a);
// 12
console.log(myObj[2]);
// sunglasses
console.log(myObj.2);
// ERROR
It is possible to add a new property to an already declared object.
var myObj = {
anotherObj: {
a: 12,
b: 'bicycle'
},
2: 'sunglasses'
};
myObj.newProperty = 'wow';
Object.defineProperty( myObj, "anotherKey", {
value: "used if we want to have more control over our property's behaviour",
writable: true,
enumerable: true,
configurable: true
});
It's also possible to delete a property.
var myObj = {
anotherObj: {
a: 12,
b: 'bicycle'
},
2: 'sunglasses'
};
delete myObj.anotherObj;
Objects
In JavaScript, functions are ordinary objects with the
additional capability of being callable.
function returnRandomNumber(min, max) {
return Math.random() * (max - min) + min;
}
function printName(name) {
console.log(name);
}
printName.property = "hello world";
typeof returnRandomNumber; // "function"
typeof returnRandomNumber(); // "number"
typeof printName.property; // "string"
typeof printName(); // "undefined"
Arguments is an array like object containing all passed arguments into the function.
function action(a) {
console.log(a + 1, arguments);
}
// Can you guess the output?
action();
action(1);
action('ey');
Arguments is an array like object containing all passed arguments into the function.
function action(a) {
console.log(a + 1, arguments);
}
// Can you guess the output?
action();
action(1);
action('ey');
Arguments contains a numerical property for each argument passed to the function.
The arguments object IS NOT an array!
function myFunction(x, y) {
console.log(x);
console.log(y);
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
console.log(arguments['0']);
}
// what will the output be?
myFunction(1, 2, 3, 4);
Arrow functions provide a compact syntax for writing functions.
var operation = (num1, num2, operation) => {
return operation(num1, num2);
}
var adding = (num1, num2) => {
return num1 + num2;
}
console.log(operation(2, 5, adding));
// 7
A higher order function returns a function or receives one as argument.
var doOperation = (num1, num2, operation) => {
return operation(num1, num2);
}
var adding = (num1, num2) => {
return num1 + num2;
}
console.log(doOperation(2, 5, adding));
// 7
doOperation() is a higher order function
operation() is a callback function
A higher order function returns a function or receives one as argument.
// RETURNING A FUNCTION
var multiplication = (num1) => {
return function (num2) {
return num1 * num2;
}
}
var double = multiplication(2);
console.log(double(5));
// 10
Functions
Arrays are list-like objects. These objects have methods to perform traversal and mutation operations.
An array's length can change at any time and data can be stored at non-contiguous locations.
var players = ['Kane', 'Chiesa', 'Sterling', 'Insigne'];
console.loh(players.length);
// 4
Array items are accessed using their index position.
var players = ['Kane', 'Chiesa', 'Sterling', 'Insigne'];
console.log(players[0]);
// Kane
console.log(players[players.length - 1]);
// Insigne
players[0] = 'Spinazzola';
console.log(players[0]);
// Spinazzola
console.log(players.at(1));
// Chiesa
Array items can be added directly or using an array method.
var players = ['Kane', 'Chiesa', 'Sterling', 'Insigne'];
// DIRECTLY
players[4] = 'Spinazzola';
players[10] = 'Verratti';
// ADDING TO THE END OF THE ARRAY
players.push('Saka');
// ADDING TO THE BEGINNING OF THE ARRAY
players.unshift('Rashford');
Array items can be removed using array methods.
var players = ['Kane', 'Chiesa', 'Sterling', 'Insigne', 'Spinazzola', 'Saka'];
// REMOVING FROM THE END OF THE ARRAY
players.pop();
// REMOVING FROM THE BEGINNING OF THE ARRAY
players.shift();
// REMOVE FROM SPECIFIC INDEX
var position = players.indexOf('Sterling');
players.splice(position, 1);
// REMOVE MULTIPLE ITEMS BY INDEX
let removedItems = players.splice(1, 2);
// this will remove two items starting at index 1
console.log(players);
// ['Kane', 'Insigne', 'Spinazzola', 'Saka']
console.log(removedItems);
// ["Chiesa", "Sterling"]
Array items can be removed using array methods.
var players = ['Kane', 'Chiesa', 'Sterling', 'Insigne', 'Spinazzola', 'Saka'];
players.forEach(function(item, index) {
console.log(item, index)
});
// Kane 0
// Chiesa 1
// Sterling 2
// ...
var months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// ["Dec", "Feb", "Jan", "March"]
const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// [1, 100000, 21, 30, 4]
var result = players
.filter(player => player.startsWith('S'))
.map(player => player.toUpperCase())
.reduce((acc, player) => acc + player + ' ', '');
console.log(result);
// CONCATENATION
var array1 = ['a', 'b', 'c'];
var array2 = array1.concat(['d', 'e', 'f']);
console.log(array2);
// ["a", "b", "c", "d", "e", "f"]
// JOINING ELEMENTS INTO A STRING
console.log(array2.join());
// a,b,c,d,e,f
console.log(array2.join('-'));
// a-b-c-d-e-f
// RERVERSING THE ELEMENTS IN AN ARRAY
var reversed = array1.reverse();
console.log('reversed:', reversed);
// "reversed: ["c", "b", "a"]"
console.log('array1:', array1);
// "array1: ["c", "b", "a"]"
var brands = ['Hermes', 'Chanel', 'Prada', 'Burberry', 'Versace'];
// SLICING
console.log(brands.slice(2));
// ["Prada", "Burberry", "Versace"]
console.log(brands.slice(1, 5));
// ["Chanel", "Prada", "Burberry", "Versace"]
console.log(brands.slice(-2));
// ["Burberry", "Versace"]
// FILLING
console.log(brands.fill('', 2));
// ["Hermes", "Chanel", "", "", ""]
//
console.log(brands.fill('', 2, 4));
// ["Hermes", "Chanel", "", "", "Versace"]
var array1 = [10, 122, 2, 189, 442];
// FINDING AN ELEMENT
var result1 = array1.find(element => element > 10);
console.log(result1);
// 122
var result2 = array1.find(element => element > 500);
console.log(result2);
// undefined
// CHECK IF ELEMENT IS PRESENT
console.log(array1.includes(2));
// true
Arrays
Arrays (Pass The Tests)
Scope refers to the region of our code where a variable is valid/accessible.
Global variables live through the entire execution of the program,
and can be accessed and altered anywhere.
Variables defined outside a function or without the var keyword will be bound to the Global Scope.
var name = 'Sarah'; // global variable
function doStuff() {
console.log(name); // Sarah
doSomethingElse();
console.log(nam2); // Liam
}
function doSomethingElse() {
name2 = 'Liam'; // implied global, as soon as doSomethingElse is invoked
}
Before ES6 existed, JavaScript had a way to prevent implied globals: strict mode.
"use strict";
var name = 'Sarah'; // global variable
function doStuff() {
console.log(name); // Sarah
doSomethingElse();
console.log(name2); // WON'T EVEN GET HERE
}
function doSomethingElse() {
name2 = 'Liam'; // ERROR
}
Local variables exist only within the function body
of which they are defined.
In JavaScript, local scope is bound to function, not block!
var name = 'Sarah'; // global variable
function doStuff() {
console.log(name); // Sarah
doSomethingElse();
if (name) {
var exists = true;
}
console.log(exists); // true
console.log(name2); // ERROR
}
function doSomethingElse() {
var name2 = 'Liam'; // local variable
}
In JavaScript, a variable defined outside a function can be accessible inside another function defined after the variable declaration. The opposite is not true.
var firstFunction = (par1) => {
var mySpecialVar = "hi!";
return function (par2) {
console.log(mySpecialVar);
console.log(par1);
console.log(par2);
}
}
var secondFunction = firstFunction(2);
secondFunction(2); // hi! 2 2
// even though mySpecialVar is part of the firstFunction's local scope
// because we need its value in secondFunction, it becomes a part of secondFunction's lexical scope
Declarations are always processed before any code is executed. This is called hoisting.
sayHelloToJonny(); // prints Hello Peter
function sayHelloToPeter() {
var name = "Peter";
console.log("Hello", name);
}
Variables declared with let or const are not hoisted.
Variables declared with const can't be reassigned.
// DECLARING A VARIABLE IN ES5
var studentName = "Philip";
// DECLARING A VARIABLE IN ES6
let anotherStudentName = "Mark";
const yetAnotherStudentName = "James";
Scopes and Hoisting
JavaScript has the Boolean, Number and String objects that wrap around primitive values.
var name = "Rod";
console.log(name.toUpperCase());
// JS creates a wrapper --> new String("Rod").toUpperCase();
Primitive Wrappers