Important JavaScript Concepts
Tags: javascript, beginners, webdev
Published: 2022-07-10 20:10:16

## 1. Prototype
Prototypes are the mechanism by which JavaScript objects inherit features from one another. The prototype is an object that is associated with every functions and objects by default in JavaScript, where function's prototype property is accessible and modifiable and object's prototype property is not visible. 

### Usage of Prototype

```javascript
function Bike(model, color) {
 this.model = model;
 this.color = color;

 this.getDetails = function () {
  return this.model + ' bike is ' + this.color;
 };
}
var bikeObj1 = new Bike('BMW', 'BLACK');
var bikeObj2 = new Bike('BMW', 'WHITE');
```

```javascript
function Bike(model, color) {
 this.model = model;
 this.color = color;
}
Bike.prototype.getDetails = function () {
 return this.model + ' bike is ' + this.color;
};
var bikeObj1 = new Bike('BMW', 'BLACK');
var bikeObj2 = new Bike('BMW', 'WHITE');
```

### Advantages
If we define the method in the object constructor, the method will be defined in every instance of object. If we define the method to the prototype, it only defines once and every instance of object has access to it. It is only stored in the memory once.

---

## 2. Scope
Scope is the accessibility of variables, functions, and objects in some particular part of your code during runtime. In other words, scope determines the visibility of variables and other resources in areas of the code. The two types of scope are local and global:

- **Global** variables are declared outside of a block.

- **Local** variables are declared inside of a block.

### Usage of Scope
**Global Scope**
```javascript
function someFunction() {
  // Local Scope #1

  function someOtherFunction() {
    // Local Scope #2
  }
}
```

**Local Scope**

```javascript
function anotherFunction() {
  // Local Scope #3
}
```

### Lexical Scope

```javascript
function grandfather() {
  var name = 'Hammad';
  // likes is not accessible here

  function parent() {
    // name is accessible here
    // likes is not accessible here

    function child() {
      // name is also accessible here
      var likes = 'Coding';
    }
  }
}
```

### var, let and const
Block statements like **if** and **switch** conditions or **for** and **while** loops, unlike functions, don't create a new scope. Variables defined inside of a block statement will remain in the scope they were already in. ECMAScript 6 introduced the **let** and **const** keywords. Contrary to the **var** keyword, the **let** and **const** keywords support the declaration of local scope inside block statements.

```javascript
if (true) {
  // this 'if' conditional block doesn't create
a new scope

  var name = 'Hammad';
  // name is still in the global scope
}


var name = 'Hammad';
let likes = 'Coding';
const skills = 'Javascript and PHP';
```

```javascript
if (true) {
   // this if conditional block doesn't create a scope

   // name is in the global scope because of the var keyword
   var name = 'Hammad';

   // likes is in the local scope because of the let keyword
   let likes = 'Coding';

   // skills is in the local scope because of the const keyword
   const skills = 'JavaScript and PHP';
}

console.log(name); // 'Hammad'
console.log(likes); // Uncaught ReferenceError: likes is not defined
console.log(skills); // Uncaught ReferenceError: skills is not defined
```

### Questions

**What is the result of?**

```javascript
for (var i = 0; i < 5; i++) {
 setTimeout(function () {
  console.log(i);
 }, i * 1000);
}

//answer: 5 5 5 5 5
```

**What is the result of?**

```javascript
for (let i = 0; i < 5; i++) {
 setTimeout(function () {
  console.log(i);
 }, i * 1000);
}

//answer: 0 1 2 3 4
```

---

## 3. Closure

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.

### Lexical Scope

```javascript
function init() {
 var name = 'Mozilla';
 // name is a local variable created by init

 function displayName() {
  // displayName() is the inner function, a
closure
  console.log(name);
 }

 displayName();
}

init();
```

### Closure

```javascript
function makeFunc() {
 var name = 'Mozilla';

 function displayName() {
  console.log(name);
 }

 return displayName;
}

var myFunc = makeFunc();
myFunc();
```

### Creating closures in loops: A common mistake

```javascript
function showHelp(help) {
 document.getElementById('help').textContent = help;
}

function setupHelp() {
 var helpText = [
  {'id': 'email', 'help': 'Your e-mail address'},
  {'id': 'name', 'help': 'Your full name'}
 ];

 for (var i = 0; i < helpText.length; i++) {
  var item = helpText[i];
  document.getElementById(item.id).onfocus = function() {
   showHelp(item.help);
  }
 }
}

setupHelp();
```

```javascript
function showHelp(help) {
 document.getElementById('help').textContent = help;
}

function makeHelpCallback(help) {
 return function() {
  showHelp(help);
 };
}

function setupHelp() {
 var helpText = [
  {'id': 'email', 'help': 'Your e-mail address'},
  {'id': 'name', 'help': 'Your full name'},
 ];

 for (var i = 0; i < helpText.length; i++) {
  var item = helpText[i];
  document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
 }
}

setupHelp();
```

---

## 4. Hoisting
Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution. A strict definition of hoisting
suggests that variable and function declarations are physically moved to the top of your code, but this is not
in fact what happens. Instead, the variable and function declarations are put into memory during the compile phase, but stay exactly where you typed them in your code. 

```javascript
function catName(name) {
 console.log(name);
}
catName("Tiger");
// Tiger

catName("Chloe");
function catName(name) {
 console.log(name);
}
// Chloe
```

```javascript
// JavaScript only hoists declarations, not initializations.
console.log(num); // undefined:
var num = 6; // Declaration and Initialization

console.log(num); // ReferenceError exception
num = 6; // Initialization

a = 1; // Initialization
let a; // ReferenceError: Cannot access 'a' before initialization

a = 1; // Initialization
const a; // SyntaxError: Missing initializer in const declaration
```

---

## 5. Apply, Call, Bind

### Usage


![Apply, Call, Bind](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9iiffqbxjsvvf9x2sdmc.png)

```javascript
var obj = {
 num: 2;
};
var add = function (num2, num3, num4) {
 return this.num + num2 + num3 + num4;
};

// Call method
console.log(add.call(obj, 3, 4, 5)); // Output: 14

// Apply method
console.log(add.apply(obj, [3, 4, 5])); // Output: 14

// Bind Method
var bound = add.bind(obj);
console.log(bound(3, 4, 5)); // Output: 14
```

**Thanks for reading!**