Primitive types are the basic types. One important fact is that variables of these types are passed by value to functions.
var number = 10
var string = 'hello'
var otherString = "world"
var boolean = false || true
var bigint = 10_000_000_000_000_000_000_000_000_000n
var symbol = Symbol('name')
function plusOne(n) {
n = n + 1
return n
}
asser(number !== plusOne(number)) // number from outside the function is not mutated (changed)
Object types allow us to create data structures and functions.
var object = {} // All objects inherits the "prototype" of the Object class
var array = []
var function = function () {}
Can be individually created, i.e. without be part of an object. When a function is member of an object, it's called a method.
// Function Declaration
function sum(x, y) {
return x + y
}
// Function Expression
const minus = function (x, y) {
return x - y
}
// Function Expression with an Arrow function
const times = (x, y) => x * y
Acronym for JavaScrit Object Notation. It's a standard to translate text into JavaScript objects and vice-versa. Accessible through the JSON
global object. JSON is the web standard for communication with servers, like a restful API or any other service. Also is the standard to send messages between workers (a kind of JavaScript thread). But can used whenever it makes sense.
const object = { name: "Alexandre" }
const stringified = JSON.stringify(object) // translates an object into a JSON string
const newObject = JSON.parse(stringified) // parses a string into a JavaScript object
const sum = 2 + 2;
const minus = 2 - 2;
const times = 2 * 2;
const power = 2 ** 2; // Math.power(2, 2);
const divide = 2 / 2;
const rest = 3.0 % 2.0;
const loseComparison = 2 == '2'; // true
const tightComparison = 2 === '2';
if (loseComparion === true) {
console.log('That is true');
}
if (tightComparison !== true) {
console.log('That is different');
}
if (true && true) {
// Executes
}
if (false || true) {
// Executes
}
// Good advice, to create a meaningful variable to make things
const isSomethingTrue = 2 === 2 && 3 === 3;
if (isSomethingTrue) {
// Executes if true
}
function sum(a,b) { console.log('sum'); return a+b; }
function minus(a,b) { console.log('minus'); return a-b; }
if (sum(2,2) > 0 && minus(2-2) >= 0) {
// Executes both sum and minus
}
// Executes on sum, as the comparison is false, the second part of the if
// is not executed
if (sum(0,0) > 0 && minus(2-2) >= 0) {
}
// Both functions are called, but the it doesn't enter the if block
if (sum(0,0) > 0 & minus(2-2) >= 0) {
}
switch (typeof prop) {
case 'undefined':
weight += 0;
break; // Very Important!!
case 'boolean':
weight += 1;
break;
default:
break;
}
// Good practice, to return instead of break
function getWeight() {
switch (type) {
case 'undefined':
return 0;
case 'boolean':
return 1;
case 'number':
return 2;
case 'string':
return 3;
default:
return null;
}
}
function
in JS is a type and a value.
function sum(a, b) {
return a + b;
}
sum (2 + 2); // Works
const minus = function minus(a, b) {
return a - b;
}
minus(1 - 1); // Works!
// Without a name
const times = function (a, b) {
return a * b;
}
times(1 - 1); // Works!
const divide = (a, b) => {
return a / b;
}
divide(4, 2);
const power = (a, b) => a ** b;
power (2, 2); // Works!
function compute(fn, a, b) {
return fn(a, b);
}
compute(sum, 2, 2); // Works!
function loadWeatherForecast(city, callback) {
// calls the external service
const request = fetch(`https://weather.com/${city}`); // Promise
request
.then(function(response) {
return response.json();
})
.then(function(weather) {
callback(null, weather);
}) // If ok
.catch(function(err) {
callback(err);
}) // If error
.finally(); // Always calls, after either then or catch executed
}
// Somewhere in our application
loadWeatherForecast('Redding', function (err, weather) {
if (err) {
// oh crap
return;
}
// We're good. Do something with weather
});
// Don't use function as classes
function Calculator() {
this.sum = function () {}
this.result = 0;
}
// Use class
class Calculator {
#result = 0;
constructor() {
}
sum = function (a, b) {
this.#result = a + b;
return this.#result;
}
}
// Pure function
function sum(a, b) {
return a + b;
}
// Arrow function
const minus = () => {
}
const outsideValue = 1;
var result;
function compute(a, b, operator = '+') { // Outer Lexical context (outter onion layer)
var result = 0;
this.result = 0;
var outter = this;
return function() { // Inner context
// This `this` is different than the `this` from Outter context
this.result = operator === '+' ? a + b : a - b;
// Now with a reference of `outter` we can change the outter result
outter.result = operator === '+' ? a + b : a - b;
// outsideValue ...// Works, we could use it here
let result = operator === '+' ? a + b : a - b;
return result;
}
}
// With arrow function, there's a new execution block, but not a new context (no different `this`)
var result;
const compute = (a, b, operator = '+') => { // Outer context (outter onion layer)
var result = 0;
this.result = 0; // `this` is from the outside scope
var outter = this;
return () => { // Inner context
this.result = operator === '+' ? a + b : a - b;
outter.result = operator === '+' ? a + b : a - b;
let result;
if (operator === '+') {
var var1 = 0;
const var2 = 0;
result = a + b;
} else {
result = a - b;
}
console.log(var1); // Ok
console.log(var2); // Error
return result;
}
}