Here’s a clean, copy-friendly cheat sheet for .call() vs .
bind() in JavaScript with examples and
comparisons:
📘 .call() – Calls a function immediately with a specific this
Definition:
js
CopyEdit
func.call(thisArg, arg1, arg2, ...)
thisArg: the value of this inside the function.
Calls the function immediately.
Example:
js
CopyEdit
function greet(greeting) {
console.log(`${greeting}, my name is ${this.name}`);
const person = { name: "Alice" };
greet.call(person, "Hello"); // Output: Hello, my name is Alice
📗 .bind() – Returns a new function with bound this
Definition:
js
CopyEdit
func.bind(thisArg)
Returns a new function with this permanently bound to thisArg.
Does not call the function immediately.
Example:
function greet() {
console.log(`Hi, I'm ${this.name}`);
const person = { name: "Bob" };
const boundGreet = greet.bind(person);
boundGreet(); // Output: Hi, I'm Bob
📊 .call() vs .bind() – Key Differences
Feature .call() .bind()
Invokes function? Yes, immediately No, returns new function
Use case One-time function call Reusable function with bound this
Arguments Passed after thisArg directly Passed when calling the new func
🔧 Bonus: Real Use Case (setTimeout + this)
js
CopyEdit
const obj = {
name: "React",
logName: function () {
console.log(this.name);
};
setTimeout(obj.logName, 1000); // undefined (this lost)
setTimeout(obj.logName.bind(obj), 1000); // React (this preserved)
now give me a lexical scope and closure example as well with code
ChatGPT said:
Absolutely! Here's a clean explanation of Lexical Scope and Closure in JavaScript, with examples and
clear comments:
🔍 Lexical Scope
Lexical Scope means that a variable’s accessibility is determined by its physical location in the
source code.
Example:
js
CopyEdit
function outer() {
const name = "JavaScript";
function inner() {
console.log(name); // ✅ Can access 'name' from outer scope
inner();
outer(); // Output: JavaScript
inner() has access to name because it is defined inside outer() — this is lexical scope.
🔐 Closure
A closure is created when a function "remembers" the variables from its lexical scope, even after the
outer function has finished execution.
Example:
js
CopyEdit
function counter() {
let count = 0;
return function () {
count++;
console.log("Count:", count);
};
const increment = counter(); // closure is formed here
increment(); // Count: 1
increment(); // Count: 2
🔑 What's happening?
counter() returns an inner function.
The inner function remembers the count variable — even after counter() is done executing.
This is a closure — the returned function keeps a reference to its lexical environment.
✅ Closure Use Cases
Data encapsulation / privacy
Function factories
Event handlers
Maintaining state (e.g., counters)
💡 Mini Interview Question:
Q: What is a closure in JS?
A: A closure is when a function retains access to variables from its lexical scope even after the outer
function has finished executing.
You said:
getter and setter example and why we should use it over normal constructors
ChatGPT said:
Great! Let's break down getters and setters in JavaScript with examples and explain why they're
useful over normal constructor assignments.
📘 What are Getters and Setters?
Getters are functions that return the value of a property.
Setters are functions that set the value of a property.
They help control access, add validation, or compute values dynamically.
✅ Basic Example
js
CopyEdit
class Person {
constructor(name) {
this._name = name; // convention: use _ to show it's "private"
get name() {
return this._name.toUpperCase(); // control or format on access
set name(newName) {
if (newName.length < 3) {
console.log("Name too short!");
} else {
this._name = newName;
const p = new Person("Alice");
console.log(p.name); // ALICE (getter used)
p.name = "Jo"; // Name too short! (setter validation)
p.name = "John"; // OK
console.log(p.name); // JOHN
🔄 Compared to a Constructor-Only Approach:
js
CopyEdit
class Person {
constructor(name) {
this.name = name; // no control, validation, or formatting
const p = new Person("Jo");
console.log(p.name); // Jo — no validation, formatting, or logic
💡 Why Use Getters/Setters?
Benefit Explanation
✅ Encapsulation Hide internal variables and only expose safe interfaces
✅ Validation Add logic before setting or getting a value
Benefit Explanation
✅ Computed Return values based on other internal state (e.g. fullName from first +
properties last)
✅ Read-only access Use getter only (no setter) to make something read-only
🧠 Bonus: Object.defineProperty()
You can also define getter/setter outside of class:
js
CopyEdit
const user = {
firstName: "John",
lastName: "Doe"
};
Object.defineProperty(user, "fullName", {
get() {
return `${this.firstName} ${this.lastName}`;
},
set(value) {
const [first, last] = value.split(" ");
this.firstName = first;
this.lastName = last;
});
console.log(user.fullName); // John Doe
user.fullName = "Jane Smith";
console.log(user.firstName); // Jane
Would you like this included in the PDF with closures and .call()/.bind() as well?
You said:
class example with extends keyword like inheritence also give the super keyword usecase instead
of .call()
ChatGPT said:
Absolutely! Let's walk through a JavaScript class inheritance example using the extends keyword and
the super() function — which is the modern replacement for Constructor.call(this) in classical
prototypes.
👨👩👧 Class Inheritance with extends and super()
✅ Basic Example
js
CopyEdit
class Animal {
constructor(name) {
this.name = name;
speak() {
console.log(`${this.name} makes a sound.`);
class Dog extends Animal {
constructor(name, breed) {
super(name); // 🔥 call the parent constructor
this.breed = breed;
speak() {
console.log(`${this.name} the ${this.breed} barks.`);
}
const d = new Dog("Rex", "Labrador");
d.speak(); // Rex the Labrador barks.
🧠 What's happening here?
Concept Description
extends Makes Dog a subclass of Animal. It inherits all properties and methods.
Calls the parent class constructor and sets this.name. Without super(), this will be
super(name)
undefined in a subclass constructor.
Method
Dog overrides the speak() method of Animal.
override
🔁 Comparison with .call() in Function Constructors
js
CopyEdit
function Animal(name) {
this.name = name;
function Dog(name, breed) {
Animal.call(this, name); // old way to inherit constructor
this.breed = breed;
In ES6 classes, super() does this internally in a cleaner and more readable way.
🔄 Inheriting Methods without Overriding
js
CopyEdit
class Cat extends Animal {}
const c = new Cat("Whiskers");
c.speak(); // Whiskers makes a sound.
🚀 Bonus: Accessing Parent Method with super
js
CopyEdit
class Bird extends Animal {
speak() {
super.speak(); // calls Animal's speak
console.log(`${this.name} also chirps.`);
const b = new Bird("Tweety");
b.speak();
// Tweety makes a sound.
// Tweety also chirps.
✅ Interview Flash Card
Q: What's the purpose of extends and super() in JavaScript classes?
A: extends enables class inheritance, and super() is used to call the parent class constructor or
methods, replacing .call(this) from pre-ES6.