JavaScript Interesting Parts: Comprehensive Guide
JavaScript Interesting Parts: Comprehensive Guide 1
1. Hoisting 2
Example: Variable Hoisting 2
Example: Function Hoisting 3
Exercise: 3
2. Coercion 3
Learn more HTML, CSS, JavaScript Web Development at https://basescripts.com/ Laurence Svekis
1
Example: Implicit Coercion 3
Exercise: 4
3. The this Keyword 4
Example: Global Scope 4
Example: Object Method 4
Example: Arrow Functions 4
Exercise: 5
4. Prototypal Inheritance 5
Example: Prototype Chain 5
Exercise: 6
5. Closures 6
Example: Basic Closure 6
Exercise: 6
6. Equality Comparisons 7
Example: Loose vs. Strict Equality 7
Exercise: 7
Multiple-Choice Questions 7
Question 1: 7
Question 2: 8
Question 3: 8
Exercises 8
Exercise 1: Fix this in a Callback 8
Exercise 2: Create a Counter Using Closures 9
Exercise 3: Check Prototypal Inheritance 9
Best Practices 9
JavaScript has unique features and behaviors that can be puzzling, especially for beginners.
These "weird parts" often result from its dynamic typing, prototypal inheritance, and loose
interpretation of data types. This guide will explore these quirks, explain them, and provide
exercises and quiz questions to help you master them.
1. Hoisting
In JavaScript, declarations are moved ("hoisted") to the top of their scope, but initialization
remains in place.
Example: Variable Hoisting
console.log(a); // Output: undefined
var a = 5;
Learn more HTML, CSS, JavaScript Web Development at https://basescripts.com/ Laurence Svekis
2
Explanation:
● The variable a is hoisted but not its assignment.
This is equivalent to:
var a;
console.log(a); // undefined
a = 5;
Example: Function Hoisting
greet(); // Output: Hello!
function greet() {
console.log("Hello!");
}
Explanation:
● Function declarations are hoisted with their definitions.
Exercise:
What will the following code output?
console.log(b);
let b = 10;
Answer:
● Error: ReferenceError: Cannot access 'b' before initialization.
● Variables declared with let or const are hoisted but remain in a "temporal dead zone"
until initialization.
2. Coercion
Coercion converts a value from one type to another, often implicitly.
Example: Implicit Coercion
console.log(1 + "2"); // Output: "12"
console.log(1 - "2"); // Output: -1
console.log("5" * 2); // Output: 10
Explanation:
Learn more HTML, CSS, JavaScript Web Development at https://basescripts.com/ Laurence Svekis
3
● 1 + "2": Number 1 is coerced into a string, resulting in concatenation.
● 1 - "2": String "2" is coerced into a number for subtraction.
Exercise:
Predict the output:
console.log(true + false); // ?
console.log([] + {}); // ?
console.log({} + []); // ?
Answer:
1. true + false: 1 (booleans are coerced to 1 and 0).
2. [] + {}: "[object Object]" (empty array coerced to an empty string; object
coerced to string).
3. {} + []: 0 (interpreted as an empty block {} and array coerced to 0).
3. The this Keyword
The value of this depends on how a function is called.
Example: Global Scope
console.log(this); // In browsers, Output: Window object
Example: Object Method
const obj = {
name: "Alice",
greet() {
console.log(this.name);
},
};
obj.greet(); // Output: "Alice"
Example: Arrow Functions
const obj = {
name: "Alice",
greet: () => {
console.log(this.name);
},
Learn more HTML, CSS, JavaScript Web Development at https://basescripts.com/ Laurence Svekis
4
};
obj.greet(); // Output: undefined
Explanation:
● Arrow functions do not have their own this and inherit it from the enclosing scope.
Exercise:
What will the following code output?
const obj = {
name: "Alice",
greet() {
const inner = () => {
console.log(this.name);
};
inner();
},
};
obj.greet();
Answer:
● Output: "Alice" (arrow function inherits this from greet).
4. Prototypal Inheritance
JavaScript uses prototypes for inheritance, where objects inherit properties and methods from
their prototype chain.
Example: Prototype Chain
const animal = {
eats: true,
};
const dog = Object.create(animal);
dog.barks = true;
console.log(dog.eats); // Output: true
Explanation:
● dog inherits from animal because of Object.create.
Learn more HTML, CSS, JavaScript Web Development at https://basescripts.com/ Laurence Svekis
5
Exercise:
What will the following code output?
function Animal() {}
Animal.prototype.walk = function () {
return "Walking";
};
const dog = new Animal();
console.log(dog.walk());
Answer:
● Output: "Walking" (dog inherits walk from Animal.prototype).
5. Closures
Closures are functions that retain access to their outer scope, even after the outer function has
executed.
Example: Basic Closure
function outer() {
const outerVar = "I'm outer";
return function inner() {
console.log(outerVar);
};
}
const closure = outer();
closure(); // Output: "I'm outer"
Exercise:
What will the following code output?
function counter() {
let count = 0;
return function () {
return ++count;
};
}
const increment = counter();
Learn more HTML, CSS, JavaScript Web Development at https://basescripts.com/ Laurence Svekis
6
console.log(increment());
console.log(increment());
Answer:
Output:
1
2
6. Equality Comparisons
Example: Loose vs. Strict Equality
console.log(0 == false); // true
console.log(0 === false); // false
Explanation:
● == performs type coercion.
● === checks both value and type.
Exercise:
What will the following code output?
console.log(null == undefined);
console.log(null === undefined);
Answer:
● null == undefined: true (loose equality treats them as equivalent).
● null === undefined: false (strict equality checks type).
Multiple-Choice Questions
Question 1:
What is the output of the following code?
function test() {
console.log(this);
}
test();
Learn more HTML, CSS, JavaScript Web Development at https://basescripts.com/ Laurence Svekis
7
1. undefined
2. null
3. Window object
4. {} (empty object)
Answer: 3. Window object (in browsers).
Question 2:
What will the following code output?
console.log(typeof null);
1. "null"
2. "object"
3. "undefined"
4. "function"
Answer: 2. "object"
Question 3:
Which of the following is true about var declarations?
1. Variables declared with var are block-scoped.
2. var declarations are not hoisted.
3. Variables declared with var are function-scoped.
4. var variables are constants.
Answer: 3. Variables declared with var are function-scoped.
Exercises
Exercise 1: Fix this in a Callback
Given the following code, fix the issue with this using an arrow function.
function User(name) {
this.name = name;
}
User.prototype.sayHi = function () {
setTimeout(function () {
Learn more HTML, CSS, JavaScript Web Development at https://basescripts.com/ Laurence Svekis
8
console.log(`Hi, I'm ${this.name}`);
}, 1000);
};
const user = new User("Alice");
user.sayHi();
Solution:
User.prototype.sayHi = function () {
setTimeout(() => {
console.log(`Hi, I'm ${this.name}`);
}, 1000);
};
Exercise 2: Create a Counter Using Closures
Write a function createCounter that returns a counter function. The counter should increment
by 1 each time it is called.
Exercise 3: Check Prototypal Inheritance
Given the following code, confirm if dog inherits from animal.
const animal = { eats: true };
const dog = Object.create(animal);
Solution:
console.log(animal.isPrototypeOf(dog)); // true
Best Practices
1. Avoid Implicit Coercion: Use strict equality (===) for predictable comparisons.
2. Use let and const: Avoid issues with var hoisting and scoping.
3. Understand Scope: Be cautious with closures and this.
4. Test Edge Cases: Check unexpected behaviors in type coercion and equality.
Learn more HTML, CSS, JavaScript Web Development at https://basescripts.com/ Laurence Svekis