JavaScript Class: Advanced (ক্লাস)
Prototype chain, class vs function, getters/setters গভীরে, mixin/composition, abstract idea, getter/setter pitfalls, interview notes — বাংলায়।
class-এর ভেতরের গভীর যান্ত্রিক ব্যাপার — prototype, composition, know-how — যা interview-এ ও বড় project-এ আসল পার্থক্য গড়ে।
Prototype chain
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} শব্দ করছে`;
}
}
const dog = new Animal("টমি");
// class-এর method আসলে prototype-এ থাকে
console.log(Object.getPrototypeOf(dog) === Animal.prototype); // true
console.log(dog.hasOwnProperty("name")); // true (নিজের)
console.log(dog.hasOwnProperty("speak")); // false (prototype-এ)instance-এ property নিজে থাকে, কিন্তু method থাকে `Class.prototype`-এ। খুঁজে না পেলে prototype chain ধরে বাবা-দাদা class-এ যায় — এটিই extends-এর গোপন কৌশল।
typeof ও class
class Animal {}
console.log(typeof Animal); // "function" — class-ও function-ই!JS-এ class হলো syntactic sugar — আসলে একটি function-এর বিশেষ রূপ। class Animal {} প্রায় function Animal() {} + prototype setup-এর মতোই।
Class বনাম function constructor
// পুরানো ধারা: function constructor
function Person(name) {
this.name = name;
}
Person.prototype.greet = function () {
return `হ্যালো ${this.name}`;
};
// আধুনিক ধারা: class
class Person2 {
constructor(name) {
this.name = name;
}
greet() {
return `হ্যালো ${this.name}`;
}
}
const p = new Person("আনামুল");
console.log(p instanceof Person); // true
console.log(p.greet()); // হ্যালো আনামুলদুটি-ই কাজ করে, তবে class-এ syntax পরিষ্কার ও inherit সুবিধা। ভুল রান: function constructor ছাড়া new করলে ব্যর্থ, class-এ নিজে থেকে error দেয় (বাধ্যতামূলক new)।
Composition — extends-এর বদলে
class CanWalk {
walk() {
return "হাঁটছে";
}
}
class CanSpeak {
speak() {
return "কথা বলছে";
}
}
// একাধিক capability একত্রে
class Human {
constructor(name) {
this.name = name;
this.walkCap = new CanWalk();
this.speakCap = new CanSpeak();
}
walk() {
return this.walkCap.walk();
}
speak() {
return this.speakCap.speak();
}
}
const user = new Human("আনামুল");
console.log(user.walk()); // হাঁটছে
console.log(user.speak()); // কথা বলছেJS এক-মাত্র parent (single inheritance)। যেখানে অনেক capability দরকার — composition (has-a) extend (is-a)-এর চেয়ে নমনীয়। mixin-ও একটি পথ।
Getter/Setter সমস্যা
class User {
#age;
constructor(age) {
this.#age = age;
}
get age() {
return this.#age;
}
set age(value) {
if (value < 0 || value > 120) {
throw new Error("বৈধ বয়স নয়");
}
this.#age = value;
}
}
const user = new User(28);
console.log(user.age); // 28
user.age = 100;
console.log(user.age); // 100
// user.age = 300; // Error: বৈধ বয়স নয়setter দিয়ে বৈধতা (validation) — class-এর ভেতরের ডেটা control-এ রাখা যায়। #private+setter একসাথে strong encapsulation দেয়।
Common pitfalls
// ১. method-এ this হারিয়ে যায়
class Counter {
constructor() {
this.count = 0;
}
add() {
this.count++; // button-এ পাঠালে this হারাতে পারে
}
}
// 2. arrow method — this bind স্থির
class Counter2 {
count = 0;
add = () => {
this.count++;
};
}
const c2 = new Counter2();
c2.add();
console.log(c2.count); // 1callback/event-এ regular method পাঠালে this খোলে যায় — arrow method বা bind(this) দিয়ে ঠিক হয়। class field-এ arrow method-ও ব্যবহার করা যায়; তবে মনে রাখবেন এতে প্রতিটি instance-এ নিজস্ব function থাকে (prototype sharable হয় না)।
Interview notes
// Q: class-কে কী আলাদা করে?
class Animal {
constructor(name) { this.name = name; }
speak() { return "..."; }
}
// Q: child-এ parent-কে ডাকা?
class Dog extends Animal {
constructor(name, breed) {
super(name); // parent constructor
this.breed = breed;
}
speak() {
return super.speak(); // parent method
}
}
// Q: static method?
class Helper {
static format(n) { return n.toFixed(2); }
}
console.log(Helper.format(3.14159)); // "3.14"class-এ new বাধ্যতামূলক; super(...) constructor-এ আগেই ডাকা লাগে; class নিজে hoist হয় না (temporal dead zone) — ব্যবহারের আগে define করতে হবে।
শুধু grouping/logic-এর জন্য function-ই যথেষ্ট। একাধিক instance, state + behavior, inheritance দরকার হলে class। class-এর ভেতরে function-ভিত্তিক চিন্তা — function প্রথম, class পরে।