Credits / Notes taken from:
var
, let
, const
$
or _
toFixed
/toPrecision
if else
, switch
, for
, for in
, for of
loop, while
, do/while
loop, break
objects
shift
/unshift
, push
/pop
, splice
/slice
, includes
Rest
operator (...
) and Spread
(...
) operatoryield
)index.html
, open it in browser (Chrome), and press CTRL+SHIFT+J
to open the console:
<!-- index.html -->
<script>
console.log("hello, world");
</script>
Tools->Build System->New build system
, paste this this and save it as nodejs.sublime-build
:
{
"cmd": ["C:/Program Files/nodejs/node.exe", "$file"],
"selector": "source.js"
}
Select Tools->Build System->nodejs
and now you can run your .js
file inside SublimeText by pressing CTRL+B
Use Codepen.io, Create->Pen->JS Windows
.
Use Scrimba.com, Create account, Log in, press +
button, select javascript template
and playground
.
Use Stackblitz, Create account, Log in, Create new project in JavaScript.
var
, let
, const
ES2015 introduced two important new JavaScript keywords: let and const, before that only var
was availale to use.
var
can be used globally in the entire document/entire enclosing function.let
is defined within it’s scope (or to the immediate enclosing block denoted by { }
/ or let
is block-scoped
):
console.log(a); // shows undefined, if `a` wasn't declared next lines, it will show ReferenceError: a is not defined
{
var a = 321;
let b = 123;
console.log(b); // shows 123
};
console.log(a); // shows 321
console.log(b); // ReferenceError: a is not defined
More info and debates about let
vs var
here
const
“variables” behave like let variables (block-scoped), except they cannot be reassigned (cannot change their value later)
const x = 10;
// Here x is 10
{
const x = 2;
// Here x is 2
}
// Here x is 10
$
or _
JavaScript treats $
and _
as if they were letters of the alphabet, so identifiers containing $
are valid variable names.
Now multiple libraries are providing their own version of the $() function, so many now provide the option to turn off that definition in order to avoid clashes. Using the dollar sign is not very common in JavaScript, but professional programmers often use it as an alias for the main function in a JavaScript library. In the JavaScript library jQuery, for instance, the main function $ is used to select HTML elements. In jQuery $("p")
; means “select all p elements”.
Of course, you don’t need to use a library to be able to use $(). All you need to substitute $() for document.getElementById() is to add a definition of the $() function to your code as follows:
function $(x) {return document.getElementById(x);}
$("demo").innerHTML = "My First JavaScript";
// instead of
// document.getElementById("demo").innerHTML = "My First JavaScript";
And the HTML part:
<body>
<p id="demo"></p>
</body>
Since JavaScript treats underscore as a letter, identifiers containing _ are valid variable names. Using the underscore is not very common in JavaScript, but a convention among professional programmers is to use it as an alias for “private (hidden)” variables (objects or methods). This is a quick and easy way to immediately identify a private class member, and it is so widely used, that almost every programmer will recognize it.
Note that again, as with $, the use of _ is merely a convention and is not enforced by JavaScript itself.
JavaScript has dynamic types. This means that the same variable can be used to hold different data types.
var x; // Now x is undefined
x = 5; // Now x is a Number
x = "John"; // Now x is a String
Strings
var str1 = "It's a string"; // Using double quotes
var str2 = 'Hello "Anne"'; // Using single quotes
let phrase = `can embed another ${str1} using $`;
Double and single quotes are “simple” quotes. There’s practically no difference between them in JavaScript.
Backticks are “extended functionality” quotes. They allow us to embed variables and expressions into a string by wrapping them in ${…}.
let name = "John";
alert( `Hello, ${name}!` ); // Hello, John!
alert( `the result is ${1 + 2}` ); // the result is 3
Numbers
(There’s only one data type for numbers: float)var x1 = 34.00; // float with decimals
var x2 = 34; // float without decimals
var y = 123e5; // 12300000
var z = 123e-5; // 0.00123
BigInt
in JavaScript, the “number” type cannot represent integer values larger than 2^53-1
(that’s 9007199254740991
), or less than -2^53-1
for negatives.// the "n" at the end means it's a BigInt
const bigInt = 1234567890123456789012345678901234567890n;
Booleans
: true
or false
(not capitalized)let nameFieldChecked = true; // yes, name field is checked
let ageFieldChecked = false; // no, age field is not checked
let isGreater = 4 > 1;
null
value. More info here
undefined
value More info here
Arrays
and Arrays methods
JavaScript arrays are written with square brackets. Array items are separated by commas.
var cars = ["Saab", "Volvo", 23];
var myNestedArray = [["universe", 42], ["everything", 7.2]]
symbol
The symbol type is used to create unique identifiers for objects. We have to mention it here for the sake of completeness, but also postpone the details till we know objects.
JavaScript Objects
JavaScript objects are written with curly braces {}
. Object properties are written as name:value pairs, separated by commas.
var personObj = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};
// The object (person) in the example above has 4 properties: firstName, lastName, age, and eyeColor.
// Check if object has a specific property
personObj.hasOwnProperty("age"); // true
personObj.hasOwnProperty("address"); // false
typeoff
operator More info here
You can use the JavaScript typeof operator to find the type of a JavaScript variable.
It supports two forms of syntax: As an operator: typeof x
. As a function: typeof(x)
. In other words, it works with parentheses or without them. The result is the same.typeof undefined // "undefined"
typeof 0 // "number"
typeof 10n // "bigint"
typeof true // "boolean"
typeof "foo" // "string"
typeof Symbol("id") // "symbol"
typeof {name:'John', age:34} // "object"
typeof Math // "object" (1)
typeof null // "object" (2)
// Unfortunately, in JavaScript, the data type of null is an object
typeof alert // "function" (3)
typeof function myFunc(){} // "function"
typeof typeof 123 // "string"
typeof NaN // "number"
typeof [1,2,3] // "object"
// In JavaScript, arrays are technically objects; just with special behaviours and abilities
JavaScript Classes
(introduced in ES2015 (ES6))typeof class Foo {} // "function"
Before Classes, to make an inheritable object, we would have to use a function
function Dog() { }
Dog.prototype.bark = function() {
alert("woof!");
}
const snoopy = new Dog();
snoopy.bark() // alert("woof!")
With Classes, we can create the same object this way
class Dog {
bark() {
alert("woof!");
}
}
const snoopy = new Dog();
snoopy.bark() // alert("woof!")
/* Undefined */
typeof undefined === 'undefined'; // true
typeof declaredButUndefinedVariable === 'undefined'; // true
typeof undeclaredVariable === 'undefined'; // true
/* Numbers */
typeof 4.42 // 'number'
typeof 5 === "number" // true
typeof(42) === 'number' // true
typeof Infinity === 'number' // true
typeof NaN === 'number'; // true, despite being "Not-A-Number"
/* Strings */
typeof 'Hello' // 'string'
typeof 'Hello' === 'string' // true
typeof '' === 'string' // true
typeof '1' === 'string'; // true, note that a number within a string is still typeof string
typeof String(1) === 'string'; // true, String converts anything into a string, safer than toString
/* Booleans */
typeof true // "boolean"
typeof false === "boolean" // true
typeof Boolean(1) === 'boolean'; // Boolean() will convert values based on if they're truthy or falsy
typeof !!(1) === 'boolean'; // two calls of the ! (logical NOT) operator are equivalent to Boolean()
typeof null === 'object' // true
+
-
*
**
/
%
++
--
and Comparisons+
Additionx = 10 + 5;// x = 10
x = 5 + '5'; // x = 55
x = '5' + 6 + 7; // x = 567
x = 5 + 6 + '7'; // x = 117
x = 5 + '6' + 7; // x = 567
-
Substractionx = 10 - 5; // x = 5
x = 5 - '5'; // x = 0
x = '5' - 6 - 7; // x = -8
x = 5 - 6 - '7'; // x = -8
x = 5 - '6' - 7; // x = -8
x = 5 - '6' - '7'; // x = -17 ..Nice
*
Multiplicationx = 5 * 10; // x = 50
x = '5' * 5; // x = 25 lol ok... expected `55555` but ok..
x = 5 * '10'; // x = 50
2 * [1, 2]; // NaN
2 * ['7']; // 14 ..Nice
2.0 * 2.5; // 5
**
Exponentiation (introduced in ES2016)5 ** 2; // 25
5 ** 3; // 125
5 ** '3'; // 125
'5' ** 3; // 125 I'm doing this just to be sure...
2 ** [4]; // 16
/
Division8 / 2; // 4
8 / 3; // 2.6666666666666665
10 / '2' // 5
10 / '3' // 3.3333333333333335
4.4 / 2 // 2.2
4.4 / 2.0 // 2.2
%
Modulus (Division Remainder)12 % 3 // 0
'10' % 3 // 1
++
/--
Increment / DecrementJavaScript | Assignment | Operators |
---|---|---|
Operator | Example | Same As |
= | x = y | x = y |
+= | x += y | x = x + y |
-= | x -= y | x = x - y |
*= | x *= y | x = x * y |
/= | x /= y | x = x / y |
%= | x %= y | x = x % y |
**= | x **= y | x = x ** y |
Operator | Description |
---|---|
== | equal to |
=== | equal value and equal type |
!= | not equal |
!== | not equal value or not equal type |
> | greater than |
< | less than |
>= | greater than or equal to |
<= | less than or equal to |
? | ternary operator |
Operator | Description |
---|---|
&& | logical and |
|| | logical or |
! | logical not |
CODE | OUTPUT |
---|---|
' or " | escape single or double quote |
\\ | escape backslash |
\n | newline |
\r | carriage return |
\t | tab (horizontal tabulator lel) |
\v | tab (vertical tabulator) |
\b | backspace |
\f | form feed |
// Strings Can be Objects
// strings can also be defined as objects with the keyword new:
var x = "John";
var y1 = new String("John");
var y2 = new String("John");
// typeof x will return string
// typeof y1 will return object
// However, don't create strings as objects. It slows down execution speed.
// The new keyword complicates the code and can produce some unexpected results:
// (y1 === y2) is false because x and y are different objects
var txt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
console.log(txt.length); // 26
console.log('aaa'.length); // 3
indexOf()
method returns the index of (position of) the first occurrence of a specified text in a string. Returns -1 if no occurence is found."Phonenumber1,Phonenumber2".indexOf(',') // 12
"Phonenumber1".indexOf(',') // -1
Manual implementation of indexOf()
(source)
function indexOfAlternative(str, query) {
for(var i = 0; i < str.length; i++) {
for(var q = 0; q < query.length; q++) {
if (str[i+q] !== query[q]) { break; }
if (q === query.length - 1) { return i; }
}
}
return -1;
}
Random application for indexOf - split a string by the first occurence of a character into an array that contains 2 elements:
var splitStringInArrByFirstMatch = function(str, characterToMatch) {
characterToMatchIdx = str.indexOf(characterToMatch)
if (characterToMatchIdx === -1) {
return [str]
} else {
return [str.slice(0, characterToMatchIdx), str.slice(characterToMatchIdx)];
}
}
console.log(splitStringInArrByFirstMatch("075123", ",")); // [ '075123' ]
console.log(splitStringInArrByFirstMatch("075123,1123", ",")); // [ '075123', ',1123' ]
console.log(splitStringInArrByFirstMatch("075123,1123,12345", ",")); // [ '075123', ',1123,12345' ]
console.log(splitStringInArrByFirstMatch("prefix-phone-number-digits", "-")); // [ 'prefix', '-phone-number-digits' ]
console.log(splitStringInArrByFirstMatch("+41-075-123-1234", "-")); // [ '+41', '-075-123-1234' ]
lastIndexOf()
method returns the index of the last occurrence of a specified text in a string"Please locate where 'locate' occurs!".indexOf("locate"); // 7
"Please locate where 'locate' occurs!".lastIndexOf("locate"); // 21
// Both indexOf(), and lastIndexOf() return -1 if the text is not found.
"Please locate where 'locate' occurs!".lastIndexOf("NotInString"); // -1
// Both methods accept a second parameter as the starting position for the search:
"Please locate where 'locate' occurs!".indexOf("locate", 15); // 21
console.log("Please locate where 'locate' occurs!".search("locate")); // 7
// search() seems to be the same as indexOf()
console.log("Please locate where 'locate' occurs!".search("banana")); // -1
// Returns -1 if substring is not found in string
search()
method cannot take a second start position argument, but can take regular expressionsindexOf()
method cannot take powerful search values (regular expressions)slice(start, end
), substring(start, end)
, substr(start, length)
slice()
extracts a part of a string and returns the extracted part in a new string.var str = "0123456789012345678";
var str = "Apple, Banana, Kiwi";
var res = str.slice(7, 13); // 'Banana'
// In Python, we would use str[7:13]
// If a parameter is negative, the position is counted from the end of the string
str.slice(-12, -6); // 'Banana'
// If you omit the second parameter, the method will slice out the rest of the string
str.slice(7); // 'Banana, Kiwi'
// In Python, we would use str[7:]
// Counting from the end:
str.slice(-12); // 'Banana, Kiwi'
str.slice(-4); // 'Kiwi'
substring()
is similar to slice(), but cannot accept negative indexesvar str = "Apple, Banana, Kiwi";
str.substring(0, 5); // 'Apple'
str.substring(12, 7); // 'Banan' .. interesting
substr()
is similar to slice(), but the second parameter specifies the length of the extracted partvar str = "0123456789012345678";
var str = "Apple, Banana, Kiwi";
str.substr(7, 6); // 'Banana'
str.substr(15, 4); // 'Kiwi'
// If you omit the second parameter, substr() will slice out the rest of the string
// If the first parameter is negative, the position counts from the end of the string.
str.substr(-4); // Kiwi
replace()
method replaces a specified value with another value in a string. By default, the replace() method replaces only the first matchlet str = "Hi Adam. Adam?";
str.replace("Adam", "Louis"); // "Hi Louis. Adam?"
replace()
method is case sensitive, but you can use a regular expression with an /i flag (insensitive). Regular expressions are written without quotes!
str = "visit Google!";
var n = str.replace(/GOOGLE/i, "W3Schools");
To replace all matches, use a regular expression with a /g flag (global match):
let str = "Hi Adam. Adam?";
str.replace(/Adam/g, "Louis"); // "Hi Louis. Louis?"
More on regular expressions here, but it’s not the time yet, so don’t click it.
"HELLO CAN YOU HEAR ME?".toLowerCase() // 'hello can you hear me?'
"no?".toUpperCase() // 'NO?'
var text1 = "Hello";
var text2 = "World";
var text3 = text1.concat(" ", text2); // 'Hello World'
var text4 = text1.concat(" ", text2, ' ', "I guess"); // "Hello World I guess"
var text = "Hello" + " " + "World!";
var text = "Hello".concat(" ", "World!"); // will do the same
All string methods return a new string. They don’t modify the original string.
Formally said: Strings are immutable: Strings cannot be changed, only replaced.
var str = " Hello World! ";
console.log(str.trim()); // Hello World!
// The trim() method is not supported in Internet Explorer 8 (2009) or lower
charAt()
, charCodeAt()
or [ ]
(Property access)
charAt()
returns the character at a specified index (position) in a stringcharCodeAt()
returns the unicode of the character at a specified index in a string[ ]
property access on strings is available from ECMASCript 5 (2009)var str = "HELLO WORLD";
str.charAt(0); // 'H'
str.charCodeAt(0); // returns 72
str[0]; // 'H'
str[str.length - 1]; // last letter 'D'
// If no character is found, [ ] returns undefined, while charAt() returns an empty string
// It is read only. str[0] = "A" gives no error (but does not work!).. strings are immutable
// [ ] does not work in Internet Explorer 7 or earlier (2006)
// If you want to work with a string as an array, you can convert it to an array (like in Python)
var txt = "a,b,c,d,e"; // String
txt.split(","); // Split on commas [ 'a', 'b', 'c', 'd', 'e' ]
"a b c d".split(" "); // Split on spaces [ 'a', 'b', 'c', 'd' ]
var txt = "abcdef";
txt.split('b'); // [ 'a', 'cdef' ]
// If the separator is "", the returned array will be an array of single characters
txt.split(''); // [ 'a', 'b', 'c', 'd', 'e', 'f' ]
// If the separator is omitted, the returned array will contain the whole string in index [0].
txt.split(); // [ 'abcdef' ]
let str = "Hello";
str.repeat(3); // 'HelloHelloHello'
includes
, match
var str = "Hello world, welcome to the universe.";
str.includes("world"); // true
match
method searches a string for a match against a regular expression, and returns the matches, as an Array objectvar str = "The rain in SPAIN stays mainly in the plain";
str.match(/ain/g); // [ 'ain', 'ain', 'ain' ]
Note: If the regular expression does not include the g
modifier (to perform a global search), the match()
method will return only the first match in the string. This method returns null
if no match is found.
const person = {
name: "Ben",
age: 37
};
const greeting = `Hello, ${person.name}!
Your age is ${person.age}.`; // Note the use of backticks
// With backticks, we can put variables right in the string using $
// We can also make multi-line strings without using / as separator
// Also. you don't have to escape any quotation marks ' ', " "
One more example using Template Literals vs. not using them:
const count = 3
const user = 'Benny Doe'
const span = 2
function pluralize(text, count) {
if (count === 1) {
return text
}
return text + 's'
}
// WITHOUT Template Literals:
const result = count + ' ' + pluralize('blog post', count)
+ ' were written by ' + name
+ ' in a span of ' + span
+ ' ' + pluralize('week', span) + '.';
// WITH Template Literals:
const result = `${count} ${pluralize('blog post', count)} were written by ${name} in a span of ${span} ${pluralize('week', span)}.`
Another example using Template Literals:
const result = {
success: ["max-length", "no-amd", "prefer-arrow-functions"],
failure: ["no-var", "var-on-top", "linebreak"],
skipped: ["no-extra-semi", "no-dup-keys"]
};
function makeList(arr) {
const failureItems = [];
for (let i = 0; i < arr.length; i++) {
failureItems.push(`<li class="text-warning">${arr[i]}</li>`)
}
return failureItems;
}
const failuresList = makeList(result.failure);
/*
['<li class="text-warning">no-var</li>',
'<li class="text-warning">var-on-top</li>',
'<li class="text-warning">linebreak</li>']
*/
toFixed
/toPrecision
JavaScript interprets numeric constants as:
0xFF
)020
)binary (base 2) if prefixed by 0b or 0B (0b1001
)
toString()
method to output numbers from base 2 up to base 36:// toString() method can be used only with a DEFINED variable!!!
// 54.toString() will give SyntaxError: Invalid or unexpected token
// Convert DEC -> BIN
var x = 17; x.toString(2) // '10001'
// Convert DEC -> HEX
var x = 17; x.toString(16) // '11'
// Convert DEC -> OCT
var x = 17; x.toString(8) // '21'
// Convert BIN -> DEC
var y = 0b110; y.toString(10) // '6'
// Convert BIN -> HEX
var y = 0b1110; y.toString(16) // 'e' (why lowercase tho)
// Convert HEX -> DEC
var z = 0xF; z.toString(10) // '15'
// Convert HEX -> BIN
var z = 0xF; z.toString(2) // '1111'
We can also convert using parseInt()
:
// Another method to convert BIN -> DEC using parseInt()
var x = parseInt("11", 2); // x = 3
var x = parseInt("110", 2); // x = 6
// HEX -> DEC
console.log(parseInt("f", 16));// x = 15
Differences between parseInt()
and Number()
to convert String->Int
Infinity
(or -Infinity
) is the value JavaScript will return if you calculate a number outside the largest possible number.var myNumber = 2;
while (myNumber != Infinity) { // Execute until Infinity
myNumber = myNumber * myNumber;
}
// Division by 0 (zero) also generates Infinity:
var x = 2 / 0; // x will be Infinity
var y = -2 / 0; // y will be -Infinity
// Infinity is a number:
typeof Infinity; // returns "number"... Weirdly enough...
Oook, infinity
, best desigh choice ever you’d say. But how do you actually catch division by zero then?
// check with an if statement
if (n === 0 || isNaN(n)) {
vax result = number / n;
}
// or check with isFinite(), if return false, then handle it appropriately
// or...
function notZero(n) {
n = +n; // Coerce to number.
if (!n) { // Matches +0, -0, NaN
throw new Error('Invalid dividend ' + n);
}
return n;
}
var result = numerator / notZero(denominator)
var x = 123;
var y = new Number(123);
// typeof x returns number
// typeof y returns object
// However, do not create Number objects. It slows down execution speed
toFixed()
returns the rounded number with a specified number of decimalsvar x = 9.656;
console.log(x.toFixed(0)); // returns 10
console.log(x.toFixed(2)); // returns 9.66
console.log(x.toFixed(3)); // returns 9.656
console.log(x.toFixed(6)); // returns 9.656000
toPrecision()
returns the rounded number with a specified length of the numbervar x = 9.656;
x.toPrecision(); // 9.656
x.toPrecision(2); // 9.7
x.toPrecision(3); // 9.66
x.toPrecision(6); // 9.65600
In short: toFixed(n)
provides n
length after the decimal point; toPrecision(x)
provides x
total length of number.
Math.PI.toFixed(2); // "3.14"
Math.PI.toPrecision(2); // "3.1"
// Furthermore, toPrecision will yield scientific notation if there are more integer digits in the number than the specified precision.
(Math.PI * 10).toPrecision(2); // "31"
(Math.PI * 100).toPrecision(2); // "3.1e+2"
var x = 0.1;
var y = 0.2;
var z = x + y // the result in z will not be 0.3 but 0.30000000000000004
To solve this we use:
var z = (x * 10 + y * 10) / 10; // z will be 0.3
// or if we know what result to expect:
var z = (x + y).toFixed(1);
MAX_VALUE
, MAX_VALUE
, POSITIVE_INFINITY
, NEGATIVE_INFINITY
, NaN
MAX_VALUE
: Returns the largest number possible in JavaScriptMIN_VALUE
: Returns the smallest number possible in JavaScriptPOSITIVE_INFINITY
: Represents infinity (returned on overflow)NEGATIVE_INFINITY
: Represents negative infinity (returned on overflow)NaN
: Represents a “Not-a-Number” valuevar x = Number.MAX_VALUE; // 1.7976931348623157e+308
var x = Number.MIN_VALUE; // 5e-324
var x = Number.POSITIVE_INFINITY; // Infinity
// Number Properties Cannot be Used on Variables
var x = 6; var y = x.MAX_VALUE; // y becomes undefined
if else
, switch
, for
, for in
, for of
loop, while
, do/while
loop, break
if else
if (condition1) {
// code
} else if (condition2) {
// code
} else {
// code
}
Inline if
(or Ternary Operator):
a ? b : c // is rougly the same as if (a) { b; } else { c; }
// and
(a && b) || c // is rougly the same as a ? b : c
// Eg
var c = (a < b) ? "a is less than b" : "a is not less than b";
// condition ? codeblock_if_condition_is_met : codeblock_if_condition_is_not_met;
// for more statements: if elseif else
var variable = (condition) ? (true block) : ((condition2) ? (true block2) : (else block2))
// same as
a === "a" ? do something
: a === "b" ? do something
: do something
// another eg.
function checkSign(num) {
return num > 0 ? "positive" : num < 0 ? "negative" : "zero";
}
switch
switch(expression) {
case x:
// code block
break;
case y:
// code block
break;
default:
// code block
}
// In this example case 4 and 5 share the same code block, and 0 and 6 share another code block:
switch (new Date().getDay()) {
case 4:
case 5:
text = "Soon it is Weekend";
break;
case 0:
case 6:
text = "It is Weekend";
break;
default:
text = "Looking forward to the Weekend";
}
<body>
<p id="demo"></p>
<script>
var x = 0; // will show Off
var x = '0'; // will show No value found
switch (x) {
case 0:
text = "Off";
break;
case 1:
text = "On";
break;
default:
text = "No value found";
}
document.getElementById("demo").innerHTML = text;
</script>
</body>
for
- loops through a block of code a number of timesfor/in
- loops through the properties of an objectfor/of
- loops through the values of an iterable objectwhile
- loops through a block of code while a specified condition is truedo/while
- also loops through a block of code while a specified condition is truefor
loopfor (statement 1; statement 2; statement 3) {
// code block to be executed
}
// <p id="demo"></p>
var text = "";
for (let i = 0; i < 8; i++) {
text += "The number is " + i + "<br>";
}
document.getElementById("demo").innerHTML = text;
statement1
from for(statement 1; statement 2; statement 3){}
, is used to initialize variables. It’s optional if variables are declared and defined earlier.var cars = ["BMW", "Volvo", "Saab", "Ford"];
var len, text;
for (let i = 0, len = cars.length, text = ""; i < len; i++) {
text += cars[i] + "<br>";
}
document.getElementById("demo").innerHTML = text;
// Looping over an array
var myArr = [9, 10, 11, 12];
var mySum = 0;
for (let i = 0; i < myArr.length; i++) {
mySum += 0 myArr[i];
}
statement2
is used to evaluate the condition of the initial variable. It’s also optional, you can omit it in order to create an infinite loop, where you must provide a break
inside.
statement3
increments/decrements the value of the initial variable (i--
, i += 5
). It could also be optional/omitted if you increment the values inside the loop.
Example: Solving FizzBuzz:
const FizzBuzzBazz = (num) => {
for (let i = 0; i <= num; i++) {
let output = "";
if (i % 3 === 0) {
output += "Fizz";
}
if (i % 5 === 0) {
output += "Buzz";
}
if (i % 7 === 0) {
output += "Bazz";
}
if (output == "") {
output = i;
}
console.log(output);
}
}
FizzBuzzBazz(18);
for...in
loops through the properties of an objectvar txt = "";
var person = {fname:"John", lname:"Doe", age:25};
var x;
for (x in person) {
txt += person[x] + " ";
}
document.getElementById("demo").innerHTML = txt; // John Doe 25
var txt = "";
var persons = [
{fname:"Jane", lname:"Doe", age:23},
{fname:"John", lname:"Doe", age:27},
{fname:"Albert", lname:"Doa", age:24}
];
var x;
for (x in persons) {
txt += persons[x].fname + " " + persons[x].lname + " " + persons[x].age + "<br>";
}
document.getElementById("demo").innerHTML = txt; // Jane Doe 23 John Doe 27 Albert Doa 24
for...of
loops through the values of an iterable objectsvar cars = ['BMW', 'Volvo', 'Mini'];
var x;
for (x of cars) {
document.write(x + "<br >"); // BMW Volvo Mini
}
// using for x IN cars
for (x in cars) {
document.write(x + "<br >"); // 0 1 2
}
// looping over a String
var txt = 'JavaScript';
for (let x of txt) {
document.write(x + "<br >");
}
while
loop, do while
loopvar text = "";
var i = 0;
while (i < 10) {
text += "<br>The number is " + i;
i++;
}
document.getElementById("demo").innerHTML = text;
// If you forget to increase the variable used in the condition, the loop will never end.
// This will crash your browser.. yep I can confirm, chrome tab freezes.
var myArray = [];
var i = 0;
while (i < 5) {
myArray.push(i);
i++;
}
do {} while ();
do {
text += "The number is " + i;
i++;
}
while (i < 10);
A while
loop is much the same as a for
loop, with statement 1 and statement 3 omitted:
var cars = ["BMW", "Volvo", "Saab", "Ford"];
var i = 0;
var text = "";
for (;cars[i];) {
text += cars[i] + "<br>";
i++;
}
// same as
while (cars[i]) {
text += cars[i] + "<br>";
i++;
}
break
and continue
statementThe break
statement can also be used to jump out of a loop and continues executing the code after the loop (if any).
for (i = 0; i < 10; i++) {
if (i === 3) { break; }
text += "The number is " + i + "<br>";
}
The continue
statement breaks one iteration (in the loop), if a specified condition occurs, and continues with the next iteration in the loop.
for (i = 0; i < 6; i++) {
if (i === 3) { continue; }
text += "The number is " + i + "<br>";
}
// This example skips the value of 3: will show 0 1 2 4 5
objects
:apples
property:let foods = {
apples: 25,
oranges: 32,
plums: 28
}
console.log(foods['apples']); // 25
console.log(foods.apples); // 25
busy
property of the nested onlineStatus
object, we use dot notation to reference the property:let userActivity = {
id: 23894201352,
date: 'January 1, 2017',
data: {
totalUsers: 51,
online: 42
}
};
userActivity.data.online = 45;
userActivity['data']['online'] = 45;
// Both methods work
delete
keyword to remove the oranges, plums, and strawberries keys from the foods object:let foods = {
apples: 25,
oranges: 32,
plums: 28,
bananas: 13,
grapes: 35,
strawberries: 27
};
delete foods.oranges;
delete foods.plums;
delete foods.strawberries;
console.log(foods); // { apples: 25, bananas: 13, grapes: 35 }
delete foods;
console.log(foods); // { apples: 25, bananas: 13, grapes: 35 } IT DOESN'T DELETE THE OBJECT
online
property is set to true
using a for...in
statement:true + true // 2
users = {
Alan: {
online: false
},
Jeff: {
online: true
},
Sarah: {
online: false
}
}
function countOnline(usersObj) {
let cnt = 0;
for (let user in usersObj) {
cnt += (usersObj[user]['online'])
}
return cnt;
}
console.log(countOnline(users)) // 1
Object.keys()
:let users = {
Alan: {
age: 27,
online: false
},
Jeff: {
age: 32,
online: true
},
Sarah: {
age: 48,
online: false
}
};
console.log(Object.keys(users));// [ 'Alan', 'Jeff', 'Sarah' ]
user
object and adds the name of the friend
argument to the array stored in user.data.friends and returns that array.let user = {
name: 'Kenneth',
age: 28,
data: {
username: 'kennethCodesAllDay',
joinDate: 'March 26, 2016',
organization: 'freeCodeCamp',
friends: [
'Sam',
'Kira',
'Tomo'
],
location: {
city: 'San Francisco',
state: 'CA',
country: 'USA'
}
}
};
function addFriend(userObj, friend) {
userObj.data.friends.push(friend);
return userObj.data.friends
}
console.log(addFriend(user, 'Pete')); // [ 'Sam', 'Kira', 'Tomo', 'Pete' ]
let duck = {
name: "Aflac",
numLegs: 2,
sayName: function() {return "The name of this duck is " + this.name + ".";}
sayLegs: () => {return `This duck has ${this.numLegs} legs.`;}
};
duck.sayName(); // "The name of this duck is Aflac."
function Dog() {
this.name = "Albert";
this.color = "brown";
this.numLegs = 3;
// "this" inside the constructor always refers to the object being created
}
let whiteDoggie = new Dog();
whiteDoggie.color = 'white';
Ofc we can extend our constructors to receive argument and pass values while we creating a new object:
function Dog(name, color) {
this.name = name;
this.color = color;
}
let terrier = new Dog('Coco', 'white');
// We can also verify an object's constructor with instanceof (name without with camelCase...)
console.log(terrier instanceof Dog); // => true
function Bird(name) {
this.name = name;
this.numLegs = 2;
}
let canary = new Bird("Tweety");
let ownProps = [];
for (let property in canary) {
if(canary.hasOwnProperty(property)) {
ownProps.push(property);
}
}
console.log(ownProps); // [ 'name', 'numLegs' ]
console.log(duck.numLegs); // prints 2
console.log(canary.numLegs); // prints 2
// We can solve with prototype
function Bird(name) {
this.name = name; // own property
Bird.prototype.numLegs = 2; // Note we don't use this (that's a own property, not a prototype)
}
Bird.prototype.numLegs = 2; // We can also define our prototype property outside our constructor
/* Extract an object "own properties" and "prototype properties" */
let ownProps = [];
let prototypeProps = [];
for (let property in duck) {
if(duck.hasOwnProperty(property)) {
ownProps.push(property);
} else {
prototypeProps.push(property);
}
}
console.log(ownProps); // prints ["name"]
console.log(prototypeProps); // prints ["numLegs"]
We can also find out what kind of object we have using myNewObj.constructor === ObjectConstructorFunction
..
let duck = new Bird();
let beagle = new Dog();
console.log(duck.constructor === Bird); //prints true
console.log(beagle.constructor === Dog); //prints true
function Dog(name) {
this.name = name;
}
Dog.prototype = {
constructor: Dog, // we also need to define the constructor property
numLegs: 2,
eat: function() {
console.log("nom nom nom");
},
describe: function() {
console.log("My name is " + this.name);
}
};
shift
/unshift
, push
/pop
, splice
/slice
, includes
:cars.length; // 3
cars[length - 1]; // 23 last element of array
console.log(myNestedArray[0]); // [ 'universe', 42 ]
console.log(myNestedArray[0][1]); // 42
myNestedArray[0] = "not anymore"; // [ 'not anymore', [ 'everything', 7.2 ] ]
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.shift(); // Removes the first element "Banana" from fruits
console.log(fruits) // ["Orange", "Apple", "Mango"]
fruits.unshift("Lemon"); // Adds a new element "Lemon" to fruits as first element
console.log(fruits) // [ 'Lemon', 'Orange', 'Apple', 'Mango' ]
fruits.pop(); // Removes the last element ("Mango") from fruits
// Also, you can store the value of popped element: "Mango"
// var x = fruits.pop();
fruits.push("Kiwi"); // Adds a new element ("Kiwi") to end of fruits ['Orange', 'Kiwi']
// Also: The push() method returns the new array length, interesting feature.
// var x = fruits.push("Kiwi");
delete fruits[0]; // Changes the first element in fruits to undefined
fruits.splice(2, 0, "Lemon", "Kiwi");
// first parameter (2) defines the position where new elements should be added (spliced in).
// second parameter (0) defines how many elements should be removed.
// rest of the parameters ("Lemon" , "Kiwi") define the new elements to be added.
/* NOTE: splice method modifies the array after execution, and returns the removed elements*/
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(0, 1); // Removes the first element of fruits
var cars_fruits = cars.concat(fruits); // Concatenates (joins) two arrays
var arr1_arr2_arr3 = arr1.concat(arr2, arr3, "Peter"); // Concatenates arr1 with arr2 and arr3 and "Peter"
var fruits = ["Banana", "Orange", "Lemon", "Apple"];
var citrus = fruits.slice(1, 3); // ["Orange", "Lemon"]
fruits_str = fruits.toString(); // 'Banana,Orange,Lemon,Apple', doesn't change fruits array
const values = [2, 3, 4];
values.includes(1); // false
values.includes(2); // true
sort()
sort()
and reverse()
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort(); // Sorts array alphabetically
fruits.reverse(); // Then reverse the order of the elements
By default, the sort()
function sorts values as strings (JavaScript’s default sorting method is by string Unicode point value, which may return unexpected results). This works well for strings (“Apple” comes before “Banana”). However, if numbers are sorted as strings, “25” is bigger than “100”, because “2” is bigger than “1”. Because of this, the sort() method will produce incorrect result when sorting numbers.
We can fix this by providing a compare function:
var numArray = [140000, 104, 99];
numArray.sort(function(a, b) { return a - b; }); // ascending
// Or, with ES6, you can use arrow functions
numArray.sort((a, b) => a - b); // For ascending sort
numArray.sort((a, b) => b - a); // For descending sort
With a comparing function, we can also sort an array of strings from Z to A (unalphabetical) without using reverse()
// Sort an array from Z to A (unalphabetical) without using reverse()
arr = ['Zach', 'Adrian', 'John', 'A', 'B', 'C', 'D'];
arr.sort(function(a, b) {
return a === b ? 0 : a < b ? 1 : -1;
});
console.log(arr); // [ 'Zach', 'John', 'D', 'C', 'B', 'Adrian', 'A' ]
Sort a numeric array in random order:
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return 0.5 - Math.random()});
Find the max/min number in an Array using Math.max()
:
Math.max.apply(null, numArray);
// Math.max.apply(null, [1, 2, 3]) is equivalent to Math.max(1, 2, 3)
var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
];
function compare( a, b ) {
if ( a.last_nom < b.last_nom ){
return -1;
}
if ( a.last_nom > b.last_nom ){
return 1;
}
return 0;
}
objs.sort(compare);
Another example:
var items = [
{ name: 'Edward', value: 21 },
{ name: 'Sharpe', value: 37 },
{ name: 'The', value: -12 },
];
// sort by value
items.sort(function (a, b) {
return a.value - b.value;
});
// sort by name
items.sort(function(a, b) {
var nameA = a.name.toUpperCase(); // ignore upper and lowercase
var nameB = b.name.toUpperCase(); // ignore upper and lowercase
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
});
Or inline:
objs.sort((a,b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0));
Or you can use inline arrow functions and localCompare
(ES6/ES2015):
objs.sort((a, b) => a.last_nom.localeCompare(b.last_nom));
// prior to
objs.sort(function(a, b) {
return a.last_nom.localeCompare(b.last_nom)
});
Note on .sort()
method: sort()
method changes the order of the elements in the original array (it mutates the array in place).
function myFunctionName(p1, p2) {
return p1 * p2;
}
let result = myFunctionName(2, 5); // 10
function toCelsius(fahrenheit) {
return (5/9) * (fahrenheit-32);
}
document.getElementById("demo").innerHTML = toCelsius(80);
// Accessing a function without () will return the function object instead of the function result.
// function toCelsius(f) { return (5/9) * (f-32); }
function getValues() {
return [getFirstValue(), getSecondValue()];
}
var values = getValues(); var first = values[0]; var second = values[1];
// or Access them with (ECMAScript 6)
var [first, second] = getValues();
// OR you can return an object with "labels"
function getValues() {
return {
first: getFirstValue(),
second: getSecondValue(),
};
}
var values = getValues(); var first = values.first; var second = values.second;
// or Access them with (ECMAScript 6)
var {first, second} = getValues();
// Other way of looking at it:
var [x, y] = [1, 2];
x; // 1
y; // 2
// or
[x, y] = (function(){ return [3, 4]; })();
x; // 3
y; // 4
// or
let {x, y} = (function(){ return {y: 3, z: 500, x: 40} })();
x; // 40
y; // 3
Function Hoisting
= JavaScript’s default behavior of moving declarations to the top of the current scope. Because of this, JavaScript functions can be called before they are declared:// JavaScript Hoisting
myFunction(5);
function myFunction(y) {
return y * y;
}
Arrow functions
Arrow functions allows a short syntax for writing function expressions. You don’t need the function
keyword, the return
keyword or the curly brackets.
function hello() {
return "Hello World"
}
var hello = function() { // this is also called anonymous function
return "Hello World!"; // (function without a name that is asigned to var hello)
} // which can be written as an arrow function
// With arrow function
var hello = () => {
return "Hello World!";
}
// With arrow function that returns only a single value by default and without parameters
var hello = () => "Hello World!";
// Arrow function with parameters
var hello = (val, val2) => "Hello " + val + val2;
var hello = e => "Hello " + e; // usually people use 'e' instead of 'val'
// ES5
var x = function(x, y = 5) { // You can make y = 5 as default
return x * y;
}
// ES6
const x = (x, y) => x * y;
// call it
x(5, 5)
const
is safer than using var
, because a function expression is always constant value.const x = (x, y) => { return x * y };
this
operatorthis
. In regular functions, the this
keyword represents the object that called the function, which could be the window, the document or a button.this
keyword always represents the object that defined the arrow function./* Both examples call a method twice:
first when the page loads, and once again when user clicks a button */
/* EXAMPLE WITH REGULAR FUNCTION */
// With a regular function this represents THE OBJECT THAT CALLS the function:
hello = function() { document.getElementById("demo").innerHTML += this; }
window.addEventListener("load", hello); // The window object calls the function
document.getElementById("btn").addEventListener("click", hello); // A button object calls the function
// => on first page reload will show [object Window]
// => after pressing button will show [object HTMLButtonElement]
/* EXAMPLE WITH ARROW FUNCTION */
// With an arrow function this represents the owner of the function:
hello = () => { document.getElementById("demo").innerHTML += this; }
window.addEventListener("load", hello); // The window object calls the function
document.getElementById("btn").addEventListener("click", hello); // A button object calls the function
// => on first page reload will show [object Window]
// => after pressing button will show [object Window]
// The owner is the Global object, so this refers to the Global object
// That's because in a browser window the Global object is [object Window]
More on this
here
// this in a method within an object
var person = {
firstName: "John",
lastName : "Doe",
id : 5566,
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
console.log(person.fullName()) // John Doe
// Or, more specific:
var person = {
firstName : "John",
lastName : "Doe",
id : 5566,
myFunction : function() {
return this;
}
};
document.getElementById("demo").innerHTML = person.myFunction(); // [object Object]
console.log(person.myFunction()); // will show all the definiton with properties and methods of object person
<!-- In HTML event handlers, this refers to the HTML element that received the event: -->
<button onclick="this.style.display='none'">
Click to Remove Me!
</button>
<!DOCTYPE html>
<html>
<body>
<p>The counter is: <span id="demo"></span></p>
<button id="btnAdd">Count</button>
<script>
var counter = 0; // global variable, can be used (and changed) by all scripts in the page
function addCnt() {
counter += 1;
document.getElementById("demo").innerHTML = counter;
}
document.getElementById("btnAdd").addEventListener("click", addCnt);
</script>
</body>
</html>
<!-- However, there is a problem with the solution above: Any code on the page can change the counter, without calling add(). -->
Another example on function closures here or here.
<!DOCTYPE html>
<html>
<body>
<p id="demo">0</p>
<button type="button" onclick="myFunction()">Count</button>
<script>
var add = (function () {
var counter = 0;
return function () {counter += 1; return counter;}
})();
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>
The variable add
is assigned the return value of a self-invoking function.
The self-invoking function only runs once. It sets the counter to zero (0), and returns a function expression.
This way add becomes a function. The “wonderful” part is that it can access the counter in the parent scope.
This is called a JavaScript closure. It makes it possible for a function to have “private” variables.
The counter is protected by the scope of the anonymous function, and can only be changed using the add function.
<!-- Add parameter to functions closures -->
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="myFunctionInc()">Increment</button>
<button type="button" onclick="myFunctionDec()">Decrement</button>
<p id="demo">0</p>
<script>
var add = (function () {
var counter = 0;
return function (param) {
if (param === 'add') {
counter += 1;
} else {
counter -= 1;
}
return counter;
}
})();
function myFunctionInc(){
document.getElementById("demo").innerHTML = add('add');
}
function myFunctionDec(){
document.getElementById("demo").innerHTML = add('sub');
}
</script>
</body>
</html>
Rest
operator (...
) on Function Parameters and Spread
(...
) operator to Evaluate Arrays In-Place/* This function takes 3 parameters and returns their sum */
const sum = (function() {
return function sum(x, y, z) {
const args = [x, y, z];
return args.reduce((a, b) => a + b);
};
})();
console.log(sum(1, 2, 3)); // 6
/* This function takes any number of parameters using Rest operator and returns their sum */
const sum = (function() {
return function sum(...args) {
// The Rest operator (...) wil convert the argumets into an array called args
return args.reduce((a, b) => a + b);
};
})();
console.log(sum(1, 2, 3, 4)); // 10
By default, copying an array uses pass-by-reference values.
const arr1 = ['JAN', 'FEB', 'MAR', 'APR'];
let arr2 = arr1;
arr1[0] = 'potato';
console.log(arr2); // [ 'potato', 'FEB', 'MAR', 'APR' ]
console.log(arr1); // [ 'potato', 'FEB', 'MAR', 'APR' ]
Using the Spread operator, we will “copy” the array using pass-by-value:
const arr1 = ['JAN', 'FEB', 'MAR', 'APR'];
let arr2 = [...arr1];
arr1[0] = 'potato';
console.log(arr2); // [ 'JAN', 'FEB', 'MAR', 'APR' ]
console.log(arr1); // [ 'potato', 'FEB', 'MAR', 'APR' ]
In Python we would use the Unpack
*
operator:
# In Python we use the * operator
# Example 1 (pass-by-reference)
a = [1, 2, 3]
b = a
b[0] = 'changed'
print(a) # ['changed', 2, 3]
print(b) # ['changed', 2, 3]
# Example 2 (pass-by-value)
a = [1, 2, 3]
b = [*a]
b[0] = 'changed'
print(a) # [1, 2, 3]
print(b) # ['changed', 2, 3]
Spread
operator to remove first two (or more) items from an Array:const numbers = [1, 2, 3, 4, 5, 6, 7];
const [ , , ...arr] = numbers;
console.log(arr); // [3, 4, 5, 6, 7]
forEach
, map
, filter
, reduce
, every
, some
, indexOf
, find
, findIndex
Array.forEach()
method calls a function (a callback function) once for each elementvar txt = "";
var numbers = [45, 4, 9, 16, 25];
numbers.forEach(myFunction);
function myFunction(value, index, array) {
txt = txt + value + "<br>";
}
console.log(txt) // 45<br>4<br>9<br>16<br>25<br>
// or using js arrow function
numbers.forEach((value) => {txt += value + "<br>";});
// In Python we would use list comprehension and join
txt = "".join([str(_)+"<br>" for _ in x])
Note that the function takes 3 arguments, some can be optional but must respect the same name:
value
index
array
itselfArray.map()
method creates a new array by performing a function on each array elementvar numbers1 = [45, 4, 9, 16, 25];
var numbers2 = numbers1.map(myFunction);
function myFunction(value, index) {
return value * 2;
}
console.log(numbers2) // [ 90, 8, 18, 32, 50 ]
// or using js arrow function
var numbers2 = numbers1.map((value) => {return 2 * value});
# In Python we would use list comprehension:
numbers2 = [2 * _ for _ in numbers1]
# or map and lambda function
numbers2 = list(map(lambda _: 2 * _, numbers1))
Another example of using map
to convert strings numbers to numbers:
['1', '7', '11'].map(n => parseInt(n)) // [1, 7, 11]
// WRONG Method of doing it:
['1', '7', '11'].map(parseInt) // [1, NaN, 3]
// And also, we need to use Number() or parseFloat() for numbers that are not integers
console.log(['1', '7.2', '11.98', '3.1415'].map(n => parseInt(n))); // [ 1, 7, 11, 3 ]
console.log(['1', '7.2', '11.98', '3.1415'].map(n => Number(n))); // [ 1, 7.2, 11.98, 3.1415 ]
console.log(['1', '7.2', '11.98', '3.1415'].map(n => parseFloat(n))); // [ 1, 7.2, 11.98, 3.1415 ]
Note: See the difference between Number()
and parseFloat()
Note: The differences between forEach
and map
are:
Array.prototype.forEach()
— executes a provided function once for each array element and doesn’t actually return anything (undefined). forEach
does mutate/modifies each element of the array called upon.Array.prototype.map()
— creates a new array with the results of calling a provided function on every element in the calling array, without modifying the original array.let arr = [1, 2, 3, 4, 5];
let doubled = arr.forEach((num, index) => {
return arr[index] = num * 2;
});
console.log(arr); // [2, 4, 6, 8, 10]
console.log(doubled); // undefined
// NOTE: We can't use forEach() with an arrow function that receives the element directly
let arr = [1, 2, 3, 4, 5];
arr.forEach(value => value * 2);
console.log(arr); // returns [ 1, 2, 3, 4, 5 ] !!!
let arr = [1, 2, 3, 4, 5];
let doubled = arr.map(num => {
return num * 2;
});
console.log(arr); // [1, 2, 3, 4, 5]
console.log(doubled); // [2, 4, 6, 8, 10]
map()
could be up to 70% faster than forEach()
on massive arrays.Array.filter()
method creates a new array with array elements that passes a testvar numbers = [45, 4, 9, 16, 25];
var over18 = numbers.filter(myFunction);
function myFunction(value, index, array) {
return value > 18;
}
console.log(over18) // [ 45, 25 ]
// or using js arrow function
var over18 = numbers.filter((value) => {return value > 18;});
# In Python we could use list comprehension:
over18 = [_ for _ in numbers if _ > 18]
Another example:
// Compute the square root of integers only (not floats)
var numbers = [4, 5.6, -9.8, 3.14, 12, 6, 8.34, -2];
var squareNumbers = numbers.filter(val => Number.isInteger(val)).map(x => x ** 2);
console.log(squareNumbers); // [ 16, 144, 36, 4 ]
// Same example but in 2 methods:
arr.filter(val => Number.isInteger(val) && val >= 0)
.map(val => val**2);
// is the same as (here we use curly brackets and return)
arr.filter((val) => {return Number.isInteger(val) && val >= 0})
.map((val) => {return val ** 2});
Array.reduce()
method runs a function on each array element to produce (reduce it to) a single valuereduce()
method works from left-to-right in the array.reduceRight()
does exactly the same but works from right-to-left in the array.total
:
total
(the initial value / previously returned value)value
index
array
itselfvar numbers = [45, 4, 9, 16, 25];
var nrSum = numbers.reduce(myFunction);
function myFunction(total, value, index, array) {
return total + value;
}
console.log(nrSum); // 99
// or using js arrow function
var nrSum = numbers.reduce((total, value) => {return total + value});
# In Python, we can use sum(Array)
nrSum = sum(numbers)
Soo, if we want to add only the numbers that are >18?
var numbers = [45, 4, 9, 16, 25];
var sumOver18 = numbers.filter((value) => {return value > 18;})
.reduce((total, value) => {return total + value}); // 70
// or
var sumOver18 = numbers.filter(e => e > 18)
.reduce((total, value) => {return total + value});
# or in Python using list comprehension and sum()
sumOver18 = sum([_ for _ in numbers if _ > 18])
What if we want sum of even numbers?
var numbers = [45, 4, 9, 16, 25];
var sumEven = numbers.filter(e => !(e % 2))
.reduce((total, value) => {return total + value}); // 20
# and Python?
sumEven = sum([_ for _ in numbers if _ % 2 == 0])
Sum of all prices of an Array with objects that have a “price” property:
let arr = [
{ name: "Banana", price: 2 },
{ name: "Chia seeds", price: 5 },
{ name: "Milk" },
{ name: "Potatoes", price: 1.5 }
];
// Also check if object has a price property, if not, map as 0 (zero)
let totalPrice = arr.map(item => item.price || 0)
.reduce((total, price) => {return total + price}, 0);
console.log(totalPrice); // 8.5
# Python3
arr = [
{'name': "Banana", 'price': 2},
{'name': "Chia seeds", 'price': 5},
{'name': "Milk"},
{'name': "Potatoes", 'price': 1.5}
]
# Also check if item (dict) has a price attribute/key
totalPrice = sum([item['price'] for item in arr if 'price' in item])
print(totalPrice) # 8.5
Array.every()
method check if all array values pass a testvar numbers = [45, 4, 9, 16, 25];
var allOver18 = numbers.every((value, index, array) => {return value > 18});
console.log(allOver18) // false
# In Python we would use all() and list comprehension
allOver18 = all([_ > 18 for _ in numbers]) # False
# all() returns True if every element in the list is True
# [_ > 18 for _ in numbers] returns [True, False, False, False, True]
Array.some()
method check if some array values pass a testvar numbers = [45, 4, 9, 16, 25];
var someOver18 = numbers.some((value) => {return value > 18}); // true
# In Python we would use any() and list comprehension
someOver18 = any([_ > 18 for _ in numbers]) // True
Array.indexOf(item[, start])
method searches an array for an element value and returns its positionArray.lastIndexOf(item[, start])
returns the position of the last occurrence of the specified element.var fruits = ["Kiwi", "Apple", "Orange", "Apple", "Mango"];
var a = fruits.indexOf("Apple"); // 1
// in Python we would use index
fruits.index('Apple') // 1
fruits.index('Orange') // 2
fruits.indexOf('dates'); // returns -1 if element is not present in array
function quickCheck(arr, elem) {
return (arr.indexOf(elem) != -1) ? true : false
}
console.log(quickCheck(['squash', 'onions', 'shallots'], 'mushrooms')); // false
Array.find()
returns the value of the first array element that passes a test functionvar numbers = [4, 9, 16, 25, 29];
var first = numbers.find(myFunction); // 25
function myFunction(value, index, array) {
return value > 18;
}
// or with js arrow function
var first = numbers.find(e => e > 18); // 25
Array.findIndex()
method returns the index of the first array element that passes a test functionvar numbers = [4, 9, 16, 25, 29];
var first = numbers.findIndex(myFunction); // 3 (index)
function myFunction(value, index, array) {
return value > 18;
}
var voxel = {x: 3.6, y: 7.4, z:6.54};
// Method 1 [old way]:
var x = voxel.x; // x = 3.6
var y = voxel.y; // y = 7.4
var z = vozel.z; // x = 6.54
// Method 2 [new way]:
const {x: a, y: b, z: c} = voxel; // a = 3.6, b = 7.4, c = 6.54
const localForecast = {
today: {min: 17, max: 25},
tomorrow: {min: 15, max: 21}
};
const {tomorrow: { max: maxOfTomorrow}} = localForecast;
console.log(maxOfTomorrow) // 21
Why don’t we use object property access instead?: because when destructuring the object you can list several variables to assign whilst =
assignment is 1-to-1 where right part is being assigned to the left.
const maxOfTomorrow = localForecast.today.max;
console.log(maxOfTomorrow) // 21
var a = 3, b = 7;
[b, a] = [a, b]; // a = 7, b = 3
const source = [1,2,3,4,5];
const [, , ...arr] = source; // arr = [3,4,5]
const [a, b, ...arr] = source; // a = 1, b = 2, arr = [3,4,5]
/* Instead of passing the whole object like this: */
const stats = {
max: 56.78,
standard_deviation: 4.34,
median: 34.54,
mode: 23.87,
min: -0.75,
average: 35.85
};
// const half = (function() {
// return function half(stats) {
// return (stats.max + stats.min) / 2.0;
// };
// })();
const half = (stats) => (stats.max + stats.min) / 2.0; // 28.015
console.log(stats);
console.log(half(stats));
/* We can pass only the parameters we need */
const stats = {
max: 56.78,
standard_deviation: 4.34,
median: 34.54,
mode: 23.87,
min: -0.75,
average: 35.85
};
// const half = (function() {
// return function half( {min, max} ) {
// return (max + min) / 2.0;
// };
// })();
const half = ({max, min}) => (max + min) / 2.0; // 28.015
const createPerson = (name, age, gender) => {
return {
name: name,
age: age,
gender: gender
};
};
console.log(createPerson("Anna", "27", "female")); // { name: 'Anna', age: '27', gender: 'female' }
If we create objects where the keys are the exact same name as the variables (arrow function’s parameters), we can rewrite our function as:
const createPerson = (name, age, gender) => ( {name, age, gender} );
The long way of puting a function into an object:
const bicycle = {
gear: 2,
setGear: function(newGear) {
"use strict";
this.gear = newGear;
}
};
bicycle.setGear(6);
console.log(bicycle.gear); // 6
The simpler method:
const bicycle = {
gear: 2,
setGear(newGear) {
"use strict";
this.gear = newGear;
}
};
yield
)The yield keyword is used to pause and resume a generator function (function*
). Syntax: [retrievedValue] = yield [expression]
function* foo(index) {
while (index < 2) {
yield index;
index++;
}
}
const iterator = foo(0);
console.log(iterator.next().value); // expected output: 0
console.log(iterator.next().value); // expected output: 1
/* Another example */
function* countAppleSales () {
let saleList = [3, 7, 5];
for (let i = 0; i < saleList.length; i++) {
yield saleList[i];
}
};
let appleStore = countAppleSales() // Generator { }
console.log(appleStore.next()) // { value: 3, done: false }
console.log(appleStore.next()) // { value: 7, done: false }
console.log(appleStore.next()) // { value: 5, done: false }
console.log(appleStore.next()) // { value: undefined, done: true }
JavaScript is object-oriented, but is not a class-based object-oriented language like Java, C++, C#. Class-based OOP languages are a subset of the larger family of OOP languages which also include prototype-based languages like JavaScript. JavaScript is both an object-oriented as well as a functional programming language.
Class Syntax:
class ClassName {
constructor(parameters) { ... }
get getter() { ... }
set setter(parameter) { ... }
method_1() { ... }
method_2() { ... }
method_3() { ... }
}
It should be noted that the class
syntax is just syntax, and not a full-fledged class-based implementation of an object-oriented paradigm, unlike in languages such as Java, Python, Ruby, etc.
In ES5, we usually define a constructor function and use the new
keyword to instantiate an object:
var SpaceShuttle = function(targetPlanet){
this.targetPlanet = targetPlanet;
}
var zeus = new SpaceShuttle('Jupiter');
The class
syntax simply replaces the constructor function creation:
class SpaceShuttle {
constructor(targetPlanet) {
this.targetPlanet = targetPlanet;
}
}
const zeus = new SpaceShuttle('Jupiter');
console.log(zeus); // SpaceShuttle { targetPlanet: 'Jupiter' }
^^ The class
keyword declares a function, to which a constructor is added. This constructor is invoked when new
is called to create a new object.
One more example:
class Vegetable {
constructor(name) {
this.name = name;
}
}
const carrot = new Vegetable('carrot');
console.log(carrot.name); // will display 'carrot'
class Car {
constructor(name, year) {
this.name = name;
this.year = year;
}
age() {
let date = new Date();
return date.getFullYear() - this.year;
}
}
myCar = new Car("Ford", 2014);
document.getElementById("demo").innerHTML =
"My car is " + myCar.age() + " years old.";
You can obtain values from an object (get) and set the value of a property within an object.
/* Example 1 */
class Book {
constructor(author) {
this._author = author;
}
// getter
get writer() {
return this._author;
}
// setter
set writer(updatedAuthor) {
this._author = updatedAuthor;
}
}
const novel = new Book('anonymous');
console.log(novel.writer); // anonymous
novel.writer = 'newAuthor';
console.log(novel.writer); // newAuthor
Note: It is convention to write the name of a private variable with an underscore (_
). However, that doesn’t make a variable private.
/* Example 2 */
class Thermostat {
constructor(fahrenheit_temp) {
this._temp = fahrenheit_temp;
}
get temperature() {
return 5/9 * (this._temp - 32);
}
set temperature(new_temp) {
this._temp = new_temp;
}
}
const thermos = new Thermostat(76); // Setting in Fahrenheit scale
let temp = thermos.temperature; // 24.44 in Celsius
thermos.temperature = 26;
temp = thermos.temperature; // 26 in Celsius
To create a class inheritance, use the extends
keyword. A class created with a class inheritance inherits all the methods from another class:
class Car {
constructor(brand) {
this.carname = brand;
}
present() {
return 'I have a ' + this.carname;
}
}
class Model extends Car {
constructor(brand, mod) {
super(brand);
this.model = mod;
}
show() {
return this.present() + ', it is a ' + this.model;
}
}
mycar = new Model("Ford", "Mustang");
document.getElementById("demo").innerHTML = mycar.show(); // I have a Ford, it is a Mustang
^^ The super()
method refers to the parent class. By calling the super()
method in the constructor method, we call the parent’s constructor method and gets access to the parent’s properties and methods.
Inheritance is useful for code reusability: reuse properties and methods of an existing class when you create a new class.
Unlike functions, and other JavaScript declarations, class declarations are not hoisted. That means that you must declare a class before you can use it:
// !! You cannot use the class yet. !!
// mycar = new Car("Ford")
// This would raise an error.
class Car {
constructor(brand) {
this.carname = brand;
}
}
//Now you can use the class:
mycar = new Car("Ford")
My portfolio: radubulai.com