DEV Community

Sagar Dutta
Sagar Dutta

Posted on

Important JavaScript Concepts

Loops

  • for

    The for statement creates a loop that consists of three optional expressions, enclosed in parentheses and separated by semicolons, followed by a statement (usually a block statement) to be executed in the loop.

    for (let i = 0; i < 9; i++) {
        console.log(i);
        // more statements
    }
    
  • forEach

    The forEach() method executes a provided function once for each array element.

    const array1 = ['a', 'b', 'c'];
    
    array1.forEach(element => console.log(element));
    
    // Expected output: "a"
    // Expected output: "b"
    // Expected output: "c"
    
  • for .. in

    The for...in statement iterates over all enumerable string properties of an object (ignoring properties keyed by symbols), including inherited enumerable properties.

    const object = { a: 1, b: 2, c: 3 };
    
    for (const property in object) {
        console.log(`${property}: ${object[property]}`);
    }
    
    // Expected output:
    // "a: 1"
    // "b: 2"
    // "c: 3"
    
  • for .. of

    The for...of statement executes a loop that operates on a sequence of values sourced from an iterable object. Iterable objects include instances of built-ins such as Array, String, TypedArray, Map, Set, NodeList (and other DOM collections), as well as the arguments object, generators produced by generator functions, and user-defined iterables.

    const array1 = ['a', 'b', 'c'];
    
    for (const element of array1) {
        console.log(element);
    }
    
    // Expected output: "a"
    // Expected output: "b"
    // Expected output: "c"
    
  • while

    The while statement creates a loop that executes a specified statement as long as the test condition evaluates to true. The condition is evaluated before executing the statement.

    let n = 0;
    
    while (n < 3) {
        n++;
    }
    
    console.log(n);// Expected output: 3
    

Mutable and Immutable Methods (in strings and arrays)

Mutable methods are those that change the original array or string. Immutable methods are those that return a new array or string without modifying the original one.

Some examples of mutable methods for arrays are:

  • pop(): removes the last element from an array and returns it

  • push(): adds one or more elements to the end of an array and returns its new length

  • shift(): removes the first element from an array and returns it

  • unshift(): adds one or more elements to the beginning of an array and returns its new length

  • reverse(): reverses the order of the elements in an array

  • sort(): sorts the elements of an array according to a compare function or lexicographically by default

  • splice(): changes the contents of an array by removing or replacing existing elements and/or adding new elements

Some examples of immutable methods for arrays are:

  • slice(): returns a shallow copy of a portion of an array into a new array

  • concat(): returns a new array that is the result of joining two or more arrays or values

  • map(): returns a new array with the results of calling a provided function on every element in the calling array

  • filter(): returns a new array with all elements that pass a test implemented by a provided function

For strings, all methods are immutable, meaning that they do not change the original string but return a new one. Some examples are:

  • charAt(): returns the character at a specified index in a string

  • concat(): returns a new string that is the result of joining two or more strings

  • indexOf(): returns the index of the first occurrence of a specified value in a string, or -1 if not found

  • replace(): returns a new string with some or all matches of a pattern replaced by a replacement

  • slice(): returns a portion of a string into a new string

  • split(): splits a string into an array of substrings using a separator

  • toUpperCase(): returns a new string with all characters converted to uppercase

Here is some javascript code to illustrate how mutable and immutable methods work:

// Mutable methods for arrays
let fruits = ["apple", "banana", "cherry"];
let last = fruits.pop(); // removes "cherry" from fruits and returns it
console.log(last); // "cherry"
console.log(fruits); // ["apple", "banana"]

let len = fruits.push("durian"); // adds "durian" to fruits and returns its new length
console.log(len); // 3
console.log(fruits); // ["apple", "banana", "durian"]

let first = fruits.shift(); // removes "apple" from fruits and returns it
console.log(first); // "apple"
console.log(fruits); // ["banana", "durian"]

len = fruits.unshift("elderberry"); // adds "elderberry" to fruits and returns its new length
console.log(len); // 3
console.log(fruits); // ["elderberry", "banana", "durian"]

fruits.reverse(); // reverses the order of fruits
console.log(fruits); // ["durian", "banana", "elderberry"]

fruits.sort(); // sorts fruits lexicographically
console.log(fruits); // ["banana", "durian", "elderberry"]

fruits.splice(1, 1, "fig", "grape"); // removes 1 element at index 1 from fruits and inserts "fig" and "grape"
console.log(fruits); // ["banana", "fig", "grape", "elderberry"]

// Immutable methods for arrays
let numbers = [1, 2, 3, 4, 5];
let sliced = numbers.slice(1, 3); // returns a new array with elements from index 1 to 3 (not inclusive) from numbers
console.log(sliced); // [2, 3]
console.log(numbers); // [1, 2, 3, 4, 5]

let joined = numbers.concat([6, 7, 8]); // returns a new array that is the result of joining numbers and [6, 7, 8]
console.log(joined); // [1, 2, 3, 4, 5, 6, 7, 8]
console.log(numbers); // [1, 2, 3, 4, 5]

let doubled = numbers.map(number => number * 2); // returns a new array with the results of multiplying each element in numbers by 2
console.log(doubled); // [2, 4, 6, 8, 10]
console.log(numbers); // [1, 2, 3, 4, 5]

let even = numbers.filter(number => number % 2 === 0); // returns a new array with all even elements from numbers
console.log(even); // [2, 4]
console.log(numbers); // [1, 2, 3, 4, 5]

// Immutable methods for strings
let name = "Alice";
let char = name.charAt(0); // returns the character at index 0 in name
console.log(char); // "A"
console.log(name); // "Alice"

let greeting = name.concat(" ", "Smith"); // returns a new string that is the result of joining name and " Smith"
console.log(greeting); // "Alice Smith"
console.log(name); // "Alice"

let index = name.indexOf("c"); // returns the index of the first occurrence of "c" in name, or -1 if not found
console.log(index); // 2
console.log(name); // "Alice"

let replaced = name.replace("A", "E"); // returns a new string with the first match of "A" replaced by "E" in name
console.log(replaced); // "Elice"
console.log(name); // "Alice"

let sliced = name.slice(1, 3); // returns a portion of name from index 1 to 3 (not inclusive) into a new string
console.log(sliced); // "li"
console.log(name); // "Alice"

let split = name.split(""); // splits name into an array of substrings using "" as a separator
console.log(split); // ["A", "l", "i", "c", "e"]
console.log(name); // "Alice"

let upper = name.toUpperCase(); // returns a new string with all characters in name converted to uppercase
console.log(upper); // "ALICE"
console.log(name); // "Alice"
Enter fullscreen mode Exit fullscreen mode

Pass by Reference and Pass by Value

Pass by value means that when a variable is passed to a function as an argument, the function receives a copy of the variable's value, not the original one. So any changes made to the variable inside the function do not affect the original variable outside the function. This happens when the variable is a primitive data type, such as a number, a string, a boolean, null or undefined.

Pass by reference means that when a variable is passed to a function as an argument, the function receives a reference to the variable's memory location, not a copy of its value. So any changes made to the variable inside the function do affect the original variable outside the function. This happens when the variable is a non-primitive data type, such as an object, an array or a function.

Here are some code snippets to illustrate the difference:

// Pass by value example
let x = 10; // x is a primitive data type (number)

function addFive(y) {
  // y is a copy of x's value
  y = y + 5; // change y's value
  console.log(y); // 15
}

console.log(x); // 10
addFive(x); // pass x to addFive function
console.log(x); // 10 (x's value is not changed)

// Pass by reference example
let obj = { name: "Alice", age: 20 }; // obj is a non-primitive data type (object)

function changeName(person) {
  // person is a reference to obj's memory location
  person.name = "Bob"; // change person's name property
  console.log(person); // { name: "Bob", age: 20 }
}

console.log(obj); // { name: "Alice", age: 20 }
changeName(obj); // pass obj to changeName function
console.log(obj); // { name: "Bob", age: 20 } (obj's name property is changed)
Enter fullscreen mode Exit fullscreen mode

Array methods

  • Basics:

    • Array.pop

      The pop() method removes the last element from an array and returns that element. This method changes the length of the array.

      const myFish = ["angel", "clown", "mandarin", "sturgeon"];
      const popped = myFish.pop();
      console.log(myFish); // ['angel', 'clown', 'mandarin' ]
      console.log(popped); // 'sturgeon'
      
    • Array.push

      The push() method adds the specified elements to the end of an array and returns the new length of the array.

      const animals = ['pigs', 'goats', 'sheep'];
      const count = animals.push('cows');
      console.log(animals);// Expected output: Array ["pigs", "goats", "sheep", "cows"]
      animals.push('chickens', 'cats', 'dogs');
      console.log(animals);// Expected output: Array ["pigs", "goats", "sheep", "cows", "chickens", "cats", "dogs"]
      
    • Array.concat

      The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.

      const array1 = ['a', 'b', 'c'];
      const array2 = ['d', 'e', 'f'];
      const array3 = array1.concat(array2);
      
      console.log(array3);// Expected output: Array ["a", "b", "c", "d", "e", "f"]
      
    • Array.slice

      The slice() method returns a shallow copy of a portion of an array into a new array object selected from start to end (end not included) where start and end represent the index of items in that array. The original array will not be modified.

      const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
      
      console.log(animals.slice(2));// Expected output: Array ["camel", "duck", "elephant"]
      
      console.log(animals.slice(2, 4));// Expected output: Array ["camel", "duck"]
      
      console.log(animals.slice(2, -1));// Expected output: Array ["camel", "duck"]
      
    • Array.splice

      The splice() method changes the contents of an array by removing or replacing existing elements and/or adding new elements in place.

      const months = ['Jan', 'March', 'April', 'June'];
      months.splice(1, 0, 'Feb');// Inserts at index 1
      console.log(months);// Expected output: Array ["Jan", "Feb", "March", "April", "June"]
      
    • Array.join

      The join() method creates and returns a new string by concatenating all of the elements in an array (or an array-like object), separated by commas or a specified separator string. If the array has only one item, then that item will be returned without using the separator.

      const elements = ['Fire', 'Air', 'Water'];
      
      console.log(elements.join());// Expected output: "Fire,Air,Water"
      console.log(elements.join(''));// Expected output: "FireAirWater"
      
    • Array.flat

      The flat() method creates a new array with all sub-array elements concatenated into it recursively up to the specified depth.

      const arr1 = [0, 1, 2, [3, 4]];
      console.log(arr1.flat());// Expected output: Array [0, 1, 2, 3, 4]
      
      const arr2 = [0, 1, 2, [[[3, 4]]]];
      console.log(arr2.flat(2));// Expected output: Array [0, 1, 2, Array [3, 4]]
      
  • Finding:

    • Array.find

      The find() method returns the first element in the provided array that satisfies the provided testing function. If no values satisfy the testing function, undefined is returned.

      const array1 = [5, 12, 8, 130, 44];
      const found = array1.find(element => element > 10);
      
      console.log(found);// Expected output: 12
      
    • Array.indexOf

      The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.

      const beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];
      
      console.log(beasts.indexOf('bison'));// Expected output: 1
      console.log(beasts.indexOf('bison', 2));// Expected output: 4
      console.log(beasts.indexOf('giraffe'));// Expected output: -1
      
    • Array.includes

      The includes() method determines whether an array includes a certain value among its entries, returning true or false as appropriate.

      const array1 = [1, 2, 3];
      
      console.log(array1.includes(2));// Expected output: true
      
    • Array.findIndex

      The findIndex() method returns the index of the first element in an array that satisfies the provided testing function. If no elements satisfy the testing function, -1 is returned.

      const array1 = [5, 12, 8, 130, 44];
      const isLargeNumber = (element) => element > 13;
      
      console.log(array1.findIndex(isLargeNumber));// Expected output: 3
      
  • Higher Order Functions:

    • Array.forEach

      The forEach() method executes a provided function once for each array element.

      const array1 = ['a', 'b', 'c'];
      array1.forEach(element => console.log(element));
      
      // Expected output: "a"
      // Expected output: "b"
      // Expected output: "c"
      
    • Array.filter

      The filter() method creates a shallow copy of a portion of a given array, filtered down to just the elements from the given array that pass the test implemented by the provided function.

      const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
      
      const result = words.filter(word => word.length > 6);
      
      console.log(result);// Expected output: Array ["exuberant", "destruction", "present"]
      
    • Array.map

      The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.

      const array1 = [1, 4, 9, 16];
      
      const map1 = array1.map(x => x * 2);
      
      console.log(map1);// Expected output: Array [2, 8, 18, 32]
      
    • Array.reduce

      The reduce() method executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.

      const array1 = [1, 2, 3, 4];
      
      const initialValue = 0;
      
      const sumWithInitial = array1.reduce((accumulator, currentValue) => accumulator + currentValue, initialValue);
      
      console.log(sumWithInitial);// Expected output: 10
      
    • Array.sort

      The sort() method sorts the elements of an array in place and returns the reference to the same array, now sorted. The default sort order is ascending, built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.

      const months = ['March', 'Jan', 'Feb', 'Dec'];
      months.sort();
      console.log(months);// Expected output: Array ["Dec", "Feb", "Jan", "March"]
      
  • Advanced:

    • Array methods chaining

      It is a technique of applying multiple array methods one after another on the same array or the result of the previous method. This allows us to write more concise and readable code by avoiding intermediate variables and loops.

      To chain array methods, we use the dot (.) operator to call the next method on the return value of the previous method. However, not all array methods can be chained. Only those methods that return a new array can be chained, such as map(), filter(), slice(), concat(), sort(), etc. Methods that return a single value, such as reduce(), find(), indexOf(), etc. cannot be chained further².

      Here are some examples of array method chaining:

      • Suppose we have an array of numbers and we want to get a new array with only the even numbers multiplied by 10 and sorted in ascending order. We can chain filter(), map() and sort() methods to achieve this:

        let numbers = [5, 2, 7, 9, 4, 6, 3];
        let result = numbers
        .filter((num) => num % 2 === 0) // filter out odd numbers
        .map((num) => num * 10) // multiply each number by 10
        .sort((a, b) => a - b); // sort in ascending order
        console.log(result); // [20, 40, 60]
        

String methods

Common JavaScript string methods with example code snippets:

  • charAt (index)

    This method returns the character at the given index. For example:

    var str = "javascript";
    console.log(str.charAt(2)); // prints "v"
    
  • slice (start, end)

    This method extracts a part of a string and returns the extracted part in a new string. The start and end parameters specify the start and end positions of the slice (end not included). For example:

    var str = "Apple, Banana, Kiwi";
    console.log(str.slice(7, 13)); // prints "Banana"
    console.log(str.slice(-12)); // prints "Banana, Kiwi"
    
  • substring (start, end)

    This method is similar to slice (), but it treats negative values as 0. For example:

    var str = "Apple, Banana, Kiwi";
    console.log(str.substring(7, 13)); // prints "Banana"
    console.log(str.substring(-12)); // prints "Apple, Banana, Kiwi"
    
  • substr (start, length)

    This method is similar to slice (), but the second parameter specifies the length of the extracted part. For example:

    var str = "Apple, Banana, Kiwi";
    console.log(str.substr(7, 6)); // prints "Banana"
    console.log(str.substr(-4)); // prints "Kiwi"
    
  • replace (oldValue, newValue)

    This method replaces a specified value with another value in a string. By default, it replaces only the first match. To replace all matches, use a regular expression with the /g flag. For example:

    var str = "Please visit Microsoft!";
    console.log(str.replace("Microsoft", "Apple")); // prints "Please visit Apple!"
    console.log(str.replace(/o/g, "*")); // prints "Please visit Micr*s*ft!"
    
  • toUpperCase ()

    This method converts a string to upper case letters. For example:

    var str = "Hello World!";
    console.log(str.toUpperCase()); // prints "HELLO WORLD!"
    
  • toLowerCase ()

    This method converts a string to lower case letters. For example:

    var str = "Hello World!";
    console.log(str.toLowerCase()); // prints "hello world!"
    
  • concat (string1, string2,...)

    This method concatenates two or more strings and returns a new string. For example:

    var str1 = "Hello";
    var str2 = "World";
    console.log(str1.concat(" ", str2)); // prints "Hello World"
    
  • trim ()

    This method removes whitespace from both ends of a string. For example:

    var str = "   Hello World!   ";
    console.log(str.trim()); // prints "Hello World!"
    
  • split (separator)

    This method splits a string into an array of substrings, using a specified separator string. For example:

    var str = "Apple,Banana,Kiwi";
    console.log(str.split(",")); // prints ["Apple", "Banana", "Kiwi"]
    
  • indexOf (value)

    This method returns the index of the first occurrence of a specified value in a string, or -1 if the value is not found. For example:

    var str = "HelloWorld";
    console.log(str.indexOf("Hello")); // prints 0
    

Object methods and operations

  • Creating objects

    Objects can be created using an object initializer (also called an object literal) or a constructor function. For example:

    // Using an object initializer
    const obj = {
    name: "John",
    age: 25,
    greet: function() {
        console.log("Hello, " + this.name);
        }
    };
    
    // Using a constructor function
    function Person(name, age) {
    this.name = name;
    this.age = age;
    this.greet = function() {
        console.log("Hello, " + this.name);
    };
    }
    
    const obj = new Person("John", 25);
    
  • Accessing properties

    Properties can be accessed using dot notation or bracket notation. For example:

    // Using dot notation
    console.log(obj.name); // prints "John"
    console.log(obj.age); // prints 25
    
    // Using bracket notation
    console.log(obj["name"]); // prints "John"
    console.log(obj["age"]); // prints 25
    
  • Modifying properties

    Properties can be modified by assigning a new value to them using dot notation or bracket notation. For example:

    // Using dot notation
    obj.name = "Jane";
    console.log(obj.name); // prints "Jane"
    
    // Using bracket notation
    obj["age"] = 30;
    console.log(obj.age); // prints 30
    
  • Deleting properties

    Properties can be deleted using the delete operator. For example:

    delete obj.name;
    console.log(obj.name); // prints undefined
    
  • Iterating over properties

    Properties can be iterated over using a for...in loop or the Object.keys() method. For example:

    // Using a for...in loop
    for (let key in obj) {
    console.log(key + ": " + obj[key]);
    }
    
    // Using Object.keys()
    let keys = Object.keys(obj);
    for (let i = 0; i < keys.length; i++) {
        let key = keys[i];
        console.log(key + ": " + obj[key]);
    }
    
  • Calling methods

    Methods can be called using dot notation or bracket notation, followed by parentheses. For example:

    // Using dot notation
    obj.greet(); // prints "Hello, Jane"
    
    // Using bracket notation
    obj["greet"](); // prints "Hello, Jane"
    

Hoisting

It is special property of javscript where we can use the variables or functions without declaring first

console.log(b); //It will print undefined not error
var b 
Enter fullscreen mode Exit fullscreen mode

Hoisting is posible only with variables declared using var key word


Scopes

The current context of execution in which values and expressions are "visible" or can be referenced. If a variable or expression is not in the current scope, it will not be available for use. Scopes can also be layered in a hierarchy, so that child scopes have access to parent scopes, but not vice versa.

  • Types of scope

    • Global scope

      The default scope for all code running in script mode. Variables declared outside of any function become global variables. Global variables can be accessed and modified from any function³⁴.

    • Function scope

      The scope created with a function. Variables declared within a function become local to the function. Local variables can only be accessed from within the function or nested functions¹⁴.

    • Block scope

      The scope created with a pair of curly braces (a block). Variables declared with let or const can have block scope. They can only be accessed from within the block¹ .

Some examples of JavaScript scopes are:

  • Global scope

    In this example, x is a global variable that can be used anywhere in the code.

    var x = 10; // global variable
    
    function foo() {
        console.log(x); // prints 10
    }
    
    function bar() {
        var x = 20; // local variable
        console.log(x); // prints 20
    }
    
    foo(); // prints 10
    bar(); // prints 20
    console.log(x); // prints 10
    
  • Function scope

    In this example, y is a local variable that can only be used inside the baz function.

    function baz() {
        var y = 30; // local variable
        console.log(y); // prints 30
    }
    
    baz(); // prints 30
    console.log(y); // causes error: y is not defined
    
  • Block scope

    In this example, z is a block-scoped variable that can only be used inside the if block.

    if (true) {
        let z = 40; // block-scoped variable
        console.log(z); // prints 40
    }
    
    console.log(z); // causes error: z is not defined
    

Closures

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.


Higher Order Functions

A higher order function is a function that either takes one or more functions as arguments, or returns a function as its result. This is possible because in JavaScript, functions are treated as first-class citizens, meaning they can be assigned to variables, passed as arguments, or returned from other functions.

The benefits of using higher order functions are:

  • They allow us to write more concise and readable code by avoiding repetition and boilerplate.

  • They enable us to implement common patterns such as map, filter, reduce, etc. that can operate on any type of data.

Some examples of higher order functions are:

  • forEach(): This is a built-in array method that takes a function as an argument and applies it to each element of the array. For example:

    let arr = [1, 2, 3];
    arr.forEach((element) => console.log(element * 2)); // logs 2, 4, 6
    
  • map(): This is another built-in array method that takes a function as an argument and returns a new array with the results of applying the function to each element of the array. For example:

    let arr = [1, 2, 3];
    let newArr = arr.map((element) => element * 2); // returns [2, 4, 6]
    
  • filter(): This is also a built-in array method that takes a function as an argument and returns a new array with only the elements that pass the test implemented by the function. For example:

    let arr = [1, 2, 3, 4, 5];
    let newArr = arr.filter((element) => element % 2 === 0); // returns [2, 4]
    
  • reduce(): This is yet another built-in array method that takes a function and an initial value as arguments and returns a single value that is the result of applying the function to each element of the array and accumulating the result. For example:

    let arr = [1, 2, 3];
    let sum = arr.reduce((acc, element) => acc + element, 0); // returns 6
    
  • setTimeout(): This is a built-in function that takes a function and a delay (in milliseconds) as arguments and executes the function after the specified delay. For example:

    function greet() {
    console.log("Hello");
    }
    
    setTimeout(greet, 1000); // logs "Hello" after 1 second
    
  • setInterval(): This is another built-in function that takes a function and a delay (in milliseconds) as arguments and executes the function repeatedly with the specified delay between each call. For example:

    function greet() {
    console.log("Hello");
    }
    
    setInterval(greet, 1000); // logs "Hello" every 1 second
    
  • addEventListener(): This is a built-in method that takes an event type (such as "click") and a function (called a callback) as arguments and registers the function to be executed when the event occurs on the target element. For example:

    let button = document.getElementById("button");
    
    function greet() {
    console.log("Hello");
    }
    
    button.addEventListener("click", greet); // logs "Hello" when the button is clicked
    

Reference

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of

https://victoriacheng15.hashnode.dev/javascript-mutable-array-methods

https://www.linkedin.com/pulse/javascript-mutable-immutable-bharath-kumar-murugan

https://www.scaler.com/topics/javascript/pass-by-value-and-pass-by-reference/

https://www.freecodecamp.org/news/higher-order-functions-in-javascript-explained/

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects

https://www.tutorialsteacher.com/javascript/scope-in-javascript


Top comments (0)