Chapter 12: Advanced JavaScript-অ্যাডভান্সড জাভাস্ক্রিপ্ট
12-1: Destructuring ভাংচুর চানাচুর

মাঝেমধ্যে আমাদের এমন পরিস্থিতি আসে, যেখানে কিছু জিনিসকে ভেঙে ছোট ছোট অংশে ভাগ করে নিতে হয়। এটাই মূলত destructuring বা কোনো জিনিসকে ছোট ছোট অংশে ভেঙে ফেলার প্রক্রিয়া। যেমন, আমরা পিজ্জা খাওয়ার সময় সেটাকে একসাথে না খেয়ে ছোট স্লাইসে ভাগ করে খাই। এমনকি শসা, আপেল, পেয়ারা ও তরমুজ খাওয়ার সময় ছোট ছোট টুকরা করে খাই। তেমনি প্রোগ্রামিংয়েও আমরা অবজেক্ট বা অ্যারেকে ছোট ছোট ভাগ করে কাজ করতে পারি।
Destructuring মূলত ES6-এর সাথে জনপ্রিয় হয়ে ওঠে এবং এর মাধ্যমে আমরা সহজে অবজেক্ট বা অ্যারে থেকে প্রয়োজনীয় ভ্যালুগুলো আলাদা করতে পারি। ধর, তোর কাছে একটি অবজেক্ট আছে।
const actor = {
name: "ananata",
age: 30,
phone: "0188232232",
money: 123132313,
};এখন যদি অবজেক্টের প্রোপার্টিগুলোকে অ্যাক্সেস করে সেগুলাকে আলাদা আলাদা নামের ভেরিয়েবলে রাখতে চাস, তখন ডট নোটেশন ব্যবহার করতে পারবি।
const name = actor.name;
const age = actor.age;
const phone = actor.phone;
const money = actor.money;
console.log(name, age, phone, money);
Output: ananata;
30;
0188232232;
123132313;প্রতিবার ডট নোটেশন ব্যবহার করতে হচ্ছে, যা কিছুটা ঝামেলার। এখানে destructuring তোর জন্য কাজটা শর্টকাট এবং সহজ করে দিবে। এর মাধ্যমে খুব সহজেই অবজেক্টের ভ্যালুগুলো আলাদা করতে পারবি।
Destructuring Syntax:
const { name, age, money, phone } = actor;এভাবে অবজেক্টের ভ্যালুগুলোকে সরাসরি পেয়ে যাবি।
console.log(name);
console.log(age);
console.log(money);
console.log(phone);
Output: ananata;
30;
123132313;
0188232232;তুই যদি কোনো প্রোপার্টির নাম চেঞ্জ করতে চাস, সেটা করতে পারবি। জাস্ট প্রোপার্টির নামের পর কোলন চিহ্ন(😃 দিয়ে তোর ইচ্ছামতো নতুন নাম দিতে পারবি। যেমন, নিচে age প্রোপার্টির নতুন নাম boyos দেয়া হইছে।
const { name, age: boyos, money, phone } = actor;
console.log(name);
console.log(boyos);
Output: ananata;
30;মাঝেমধ্যে অবজেক্ট থেকে যে প্রোপার্টি ডিস্ট্রাকচারিং করতে হবে, সেই নামে অলরেডি আরেকটা ভেরিয়েবল থাকতে পারে। তখন দুইটা নাম একই হলে একটু ভেজাল হয়ে যেতে পারে। এইসব ক্ষেত্রে ভেজাল বা কনফিউশন এড়ানোর জন্য প্রোপার্টির নাম চেঞ্জ করতে পারবি জাস্ট কোলন দিয়ে, তারপর নতুন একটা নাম লিখে।
const book = { title: "1984", author: "George Orwell" };
const { title: bookTitle, author: bookAuthor } = book;
console.log(bookTitle);
console.log(bookAuthor);
Output:
1984
George Orwellঅ্যারে Destructuring
যখন অবজেক্টকে destructuring করছিলি, তখন ডানপাশে ছিল অবজেক্ট আর বামপাশে নামগুলো ছিল { } ব্র্যাকেটের মধ্যে। কারণ, অবজেক্ট লিখতে এই { } লাগে, তাই ডিস্ট্রাকচারিং করতেও { } লাগবে। একইভাবে যখন অ্যারেকে ডিস্ট্রাকচারিং করবি, তখন ডানপাশে থাকবে অ্যারে, আর বামপাশে নামগুলা থাকবে [ ] ব্র্যাকেটের মধ্যে। কারণ, একটা সিম্পল অ্যারে ডিক্লেয়ার করার জন্য [ ] এইটা লাগে। তাই ডিস্ট্রাকচারিং করার জন্য [ ] লাগবে।
const numbers = [45, 99];
const [first, second] = numbers;
console.log(first);
console.log(second);
Output: 45;
99;এখানে numbers অ্যারের প্রথম এবং দ্বিতীয় উপাদানকে first এবং second নামে অ্যাসাইন করা হয়েছে।
ফাংশন রিটার্ন থেকে destructuring করা
ধর, আমরা একটি ফাংশন লিখছি, যেটা দুটি ভ্যালু নিবে এবং তাদের ডাবল করে একটি অ্যারে রিটার্ন করবে।
function doubleThem(a, b) {
return [a * 2, b * 2];
}এখন আমরা এই রিটার্ন করা অ্যারেকে destructure করতে পারি।
const [prothom, ditiyo] = doubleThem(6, 9);
console.log(prothom, ditiyo);
Output: 12;
18;এখানে আমরা doubleThem ফাংশন থেকে রিটার্ন করা অ্যারের প্রথম এবং দ্বিতীয় ভ্যালু আলাদা করেছি এবং সেগুলোকে আলাদা করে প্রিন্ট করেছি। যেহেতু ফাংশনটি একটি অ্যারে রিটার্ন করে, তাই আমরা [ ] ব্যবহার করে এটাকে destructure করেছি।
Destructuring প্রাথমিকভাবে একটু ভেজাইল্লা মনে হতে পারে, তবে এটি একটি খুবই শক্তিশালী এবং দরকারি টেকনিক। এটি আমাদের কোডকে সিম্পল এবং ইজি করে তোলে।
Default Value
ডিস্ট্রাকচারিং কী করে? কোনো অবজেক্ট বা অ্যারের মধ্যে কোনো প্রপার্টি বা উপাদান থাকলে সেটাকে সরাসরি একটা ভেরিয়েবলে বসিয়ে দেয়। কিন্তু যদি সেই প্রোপার্টি বা উপাদান অ্যারের মধ্যে না থাকে, তাহলে কী হবে? তাহলে সেটার মান undefined হয়ে যাবে। তবে তুই যদি undefined না করে কোনো একটা ডিফল্ট মান দিতে চাস, সেটা দিতে পারবি। তাহলে যদি মান থাকে, সেই মান পেয়ে যাবি। আর যদি মান না থাকে, তাহলে undefined না পেয়ে ডিফল্ট মান পাবি।
const person = { name: "Amit", age: 25 };
const { name, phone = "N/A" } = person;
console.log(name);
console.log(phone);
Output: Amit;
N / A;যেখানে কিছু ভ্যালু মিসিং থাকতে পারে, সেখানে ডিফল্ট মান খুব কাজে লাগবে।
Advanced: ফাংশনের প্যারামিটারে Destructuring
ফাংশনের প্যারোমিটারের মধ্যেও সরাসরি destructuring করা সম্ভব। সেজন্য সব প্যারামিটারকে অবজেক্টের মধ্যে রাখবি। আর আর্গুমেন্ট পাস করার সময় অবজেক্ট হিসেবে পাঠিয়ে দিবি। তাহলে সিরিয়াল মেইনটেইন না করলেও চলবে। জাস্ট অবজেক্টের ভিতরের প্রোপার্টির নামের সাথে প্যারামিটারের নাম মিলিয়ে নিবে।
function introduce({ name, age }) {
console.log(`Name: ${name}, Age: ${age}`);
}
const user = { name: "Arohi", age: 22, hobby: "Reading" };
introduce(user);
Output: Name: Arohi, Age: 22এইটা একটু ভেজাইল্লা। আপাতত না বুঝলেও চলবে। তারপরেও একটু দুই মিনিট খেয়াল করে দেখ। introduce ফাংশনকে ডিক্লেয়ার করার সময় প্যারামিটার হিসেবে একটা অবজেক্ট আছে। আর এই ফাংশনকে কল করার সময় আর্গুমেন্ট (প্যারামিটার হিসেবে) পাঠানো হয়েছে একটা অবজেক্টকে। তাই সেই অবজেক্টের প্রোপার্টির নাম এর সাথে ফাংশনের প্যারামিটারের অবজেক্টের প্রোপার্টি ডিস্ট্রাকচারিং হয়ে যাবে।
অ্যারে প্যারামিটারে
সিমিলারভাবে অ্যারে দিয়েও ফাংশনের প্যারামিটারকে ডিস্ট্রাকচারিং করা যায়। সিমিলার কনসেপ্ট। জাস্ট অবজেক্টের জায়গায় অ্যারে।
function sum([a, b]) {
return a + b;
}
console.log(sum([5, 10]));
Output: 15;Skipping Values in Array Destructuring
অ্যারের কিছু অংশ স্কিপ করতে চাইলে শুধু কমা দিয়ে সেগুলো এড়িয়ে যেতে পারিস।
const numbers = [1, 2, 3, 4, 5];
const [, second, , fourth] = numbers;
console.log(second);
console.log(fourth);
Output: 2;
4;Practice:
- অবজেক্ট থেকে brand প্রোপার্টি আলাদা কর। const product = { name: "Laptop", price: 50000, brand: "Dell" };
- Item অবজেক্ট থেকে phone এবং price প্রোপার্টি ডিস্ট্রাকচারিং কর। const item = { name: "Mobile", price: 20000, phone: "Samsung" }।
- অ্যারে থেকে প্রথম দুইটা উপাদান বের কর। const colors = ["red", "blue", "green", "yellow"];
- তিনটা সংখ্যার একটা অ্যারে থেকে
destructuringকরে সেকেন্ড সংখ্যাটা আলাদা করে second নামক ভেরিয়েবলে রাখ। - অ্যারের প্রথম এবং শেষ উপাদানকে destructuring করে two এবং eight নামের ভেরিয়েবলে রাখ। const digits = [2, 4, 6, 8]।
- ফাংশন রিটার্ন থেকে ডিস্ট্রাকচারিং করে প্রথম এবং দ্বিতীয় ভ্যালু আলাদা কর। function multiply(a, b) { return [a * 3, b * 3]; }।
- person অবজেক্ট থেকে name এবং city আলাদা কর। আর phone না থাকলে ডিফল্ট ভ্যালু N/A সেট কর। const person = { name: "Rahim", city: "Dhaka" }।
- teacher অবজেক্ট থেকে name এবং profession-এর ভ্যালু বের কর, যেখানে profession-এর নাম alias হিসেবে job রাখ। const teacher = { name: "Maria", profession: "Teacher" }।
12-2: বাকিরা Rest-এ আছে
ধর, তোরা কয়েকজন ফ্রেন্ড মিলে ভ্রমণে গেলি সুন্দরবনে। রাতে জঙ্গলেই তাঁবু গেড়ে থাকবি। ক্যাম্পেইন করবি। এমন সাহসী সিদ্ধান্ত। মাঝরাতে দুইটা রয়েল বেঙ্গল টাইগার এসে তোদের দুইজনকে বলল, বাইরে আসো, কোলাকুলি করব। এই কথা শুনে তোদের দুজন বাদে বাকিরা গেল লুকিয়ে। হুট করে আরেকটা বাঘের বাচ্চা এসে বলল, বাকিরা কই। তখন তুই বললি, বাকিরা rest-এ আছে।
Rest Operator
JavaScript-এ তিনটা ডট দিয়ে Rest Operator (...) ইউজ করা যায়। এইটা ফাংশন, অ্যারে এবং অবজেক্টে একাধিক মানকে একসাথে ধরে রাখার জন্য খুবই উপকারি একটা সিস্টেম। Rest Operator ইউজ করলে—
একসাথে ফাংশনের অনেকগুলা আর্গুমেন্ট বা প্যারামিটারকে রাখা যায়।
অবজেক্টের ডিস্ট্রাকচারিং করার সময় একসাথে অনেকগুলা প্রোপার্টিকে রাখা যায়।
Array থেকে উপাদান বের করার সময় অনেকগুলা উপাদান আলাদা করা যায় বা একসাথে রাখা যায়।
Rest Operator অনেক আর্গুমেন্ট বা প্রোপার্টিকে বা উপাদানকে একসাথে রাখতে খুব কাজে লাগে। এ ছাড়া কখনো যদি আমরা নিশ্চিত না হই যে, কতগুলো ডেটা আসবে, তখন Rest Operator ব্যবহার করে সহজে সমস্ত ডেটাকে ধরে রাখা যায়। এ ছাড়া rest অপারেটর দিয়ে সহজ, ছোট এবং সিম্পল হয়। জটিল কাজকে সহজে করা যায়।
কয়েকটা উদাহরণ দেখি—
নিচের array-এর প্রথম দুইটা উপাদান আমরা দুইটা ভেরিয়েবলে রাখলাম। তারপর যত উপাদান থাকুক না কেন, সবগুলাকে তিনটা ডট চিহ্নের পর যেকোনো নাম দিয়েই রাখতে পারবি। আমি দিলাম rest নাম।
const [first, second, ...rest] = [10, 20, 30, 40, 50];
console.log(first);
console.log(second);
console.log(rest);
Output: 10;
(20)[(30, 40, 50)];অবজেক্ট ডিস্ট্রাকচারিংয়ের ক্ষেত্রে Rest Parameter ব্যবহার করে Object-এর কিছু প্রোপার্টি আলাদা করে এবং বাকিগুলো অন্য একটি নাম দিয়ে অন্য একটি Object-এ রাখা যায়। যেমন, নিচে details নামে রেখেছি। সেখানে city আর name ছাড়া বাকিসব প্রোপার্টি details নামক অবজেক্টে আছে।
const person = { name: 'Alice', age: 25, city: 'Dhaka', country: 'Bangladesh' };
const { name, city, ...details } = person;
console.log(name);
console.log(city);
console.log(details);
Output:
Alice
Dhaka
{ age: 25, country: 'Bangladesh' }ফাংশনের প্যারামিটারের ক্ষেত্রেও রেস্ট প্যারামিটার ইউজ করা যায়। যেমন, আমরা প্রথম প্যারামিটার বাদে বাকিগুলাকে rest অপারেটর দিয়ে আমাদের ইচ্ছামতো একটা নাম দিছি। যেমন, নিচে নাম দিলাম numbers
function multiply(multiplier, ...numbers) {
console.log(numbers);
}
multiply(2, 1, 2, 3);
multiply(3, 4, 5, 6);
Output: [1, 2, 3][(4, 5, 6)];Practice:
- একটা product অবজেক্ট আছে const product = { name: "Laptop", price: 50000, brand: "Dell" }; এইটা থেকে name বাদে বাকি প্রোপার্টিগুলা আলাদা একটা অবজেক্টে রাখ।
- const project = { id: 101, title: "Web App", budget: 3000, client: "Tech Corp" }; এখানে title বাদে বাকি প্রোপার্টিগুলা আলাদা একটা অবজেক্টে রাখ।
- const programmer = { name: "Sophia", language: "JavaScript", experience: 5, specialty: "Frontend", tools: "React" }; এখানে language আর specialty আলাদা প্রোপার্টি হিসেবে রেখে বাকিগুলা details নামে একটা অবজেক্টে রাখ।
- একটা সংখ্যার array আছে। [10, 20, 3, 30, 300, 3000] এইটা থেকে প্রথম দুইটা উপাদান বাদে বাকিগুলা আলাদা আরেকটা array-এর মধ্যে রাখ।
- একটা function লেখ, যেটা দুইটা প্যারামিটার বাদে বাকিসব প্যারামিটারকে রেস্ট অপারেটর দিয়ে ধরে রাখবে। ফাংশনটি সেই বাকি প্যারামিটারগুলোর যোগফল রিটার্ন করবে।
- একটা ফাংশন লেখ, যে সব প্যারামিটারকে রেস্ট অপারেটর দিয়ে একটা array-তে রাখবে, তারপর আর্গুমেন্টগুলো যোগ করবে। ফাংশনটি array-এর উপাদানগুলোর গড় রিটার্ন করবে।
12-3: পাউরুটির ওপর মাখন এর Spread
ইংরেজি সেন্টেন্সের পরে একটা ডট দিলে সেন্টেন্স শেষ। ফুল স্টপ হয়ে যায়। কোনো জায়গায় দুইটা ডট দিলে মনে হয় থেমেও থামতে চাচ্ছে না; বরং তোতলাচ্ছে।
আর তিন ডটের কথা শুনে তোর মামা-খালু-চাচা থেকে কেউ বলে উঠতে পারে, সে ছোটবেলায় একটা সিনেমা দেখছিল, যেটার নাম ছিল 3 idiots। এই 3 idiots-এর কথা মনে করে তোকে আবার তোর সেই আঙ্কেল বলে বসতে পারে, তুই হচ্ছস i ওয়ালা 3 dots।
[ কারণ, dots-এর মধ্যে i বসালে idiot হয়ে যেতে পারে ]
তিন ডটের দুইটা ইউজ আছে
১. rest অপারেটর (অবজেক্ট, array-এর বাকি উপাদানগুলা বা ফাংশনের বাকি প্যারামিটারগুলা পাওয়ার জন্য ইউজ করা হয়)
২. Spread Operator মানে হলো 'বিছিয়ে দেওয়া' বা 'মাখিয়ে দেওয়া'।
তবে ডট শেখার আগে কিছু সংখ্যার মধ্যে সবচেয়ে বড় সংখ্যা বের করার সিস্টেমটা আরেকবার দেখে আসি।
const max = Math.max(5, 23, 45, 1, 89, 34);
console.log(max);
Output: 89;এখানে আমরা Math.max() ফাংশন ব্যবহার করে কিছু সংখ্যার মধ্যে সবচেয়ে বড় সংখ্যাটি বের করেছি। কিন্তু যদি আমাদের একটি অ্যারে থাকে এবং আমরা তার মধ্যে থেকে সবচেয়ে বড় সংখ্যাটি বের করতে চাই, তাহলে কী হবে?
const numbers = [3, 5, 2, 45, 5, 43, 90, 32, 15];
const arrayMax = Math.max(numbers);
console.log(arrayMax);
Output: NaN;এবার একটু খেয়াল কর, আমরা Math.max() ফাংশনের আগে যে কাজটি করেছি, তা সঠিকভাবে কাজ করছিল। কিন্তু যখন একটি অ্যারে ব্যবহার করলাম, তখন NaN আউটপুট পেলাম। কারণ, Math.max() সরাসরি একটি অ্যারের সাথে কাজ করে না, এটি একাধিক প্যারামিটার নেয়।
অ্যারের ক্ষেত্রে আমরা যদি তিনটি ডট ... ব্যবহার করি, যা spread operator নামে পরিচিত, তাহলে অ্যারের প্রতিটি উপাদানকে আলাদা আলাদা করে নেওয়া সম্ভব হবে।
const arrayMax = Math.max(...numbers);
console.log(arrayMax);
Output: 90;এখন আমরা Math.max() ব্যবহার করে অ্যারের মধ্য থেকে সবচেয়ে বড় সংখ্যাটি বের করতে পারছি। Spread operator-এর মাধ্যমে অ্যারের প্রতিটি উপাদানকে আলাদা করে পাঠিয়েছি, ঠিক যেমন আগের উদাহরণে একাধিক সংখ্যা দিয়েছিলাম।
Spread Operator দিয়ে কপি
Spread operator শুধু Math.max()-এর মতো ফাংশনগুলিতে কাজ করতেই ব্যবহার করা হয় না; বরং এটাকে কপি করার ক্ষেত্রেও ব্যবহার করা যায়। উদাহরণস্বরূপ, আমরা যদি দুটি অ্যারে নেই এবং একটি অ্যারের উপাদানগুলো অন্যটিতে কপি করতে চাই—
const friends = [4, 5, 87, 9];
const boundu = friends;
boundu.push(12);
console.log(boundu);
Output: [4, 5, 87, 9, 12];এখন আমরা যদি friends অ্যারেটা প্রিন্ট করি, দেখা যাবে friends অ্যারের মধ্যে 12 যুক্ত হয়ে গেছে, যদিও আমরা শুধু boundu-তে push করেছিলাম।
console.log(friends);
Output: [4, 5, 87, 9, 12];এটা ঘটছে, কারণ friends এবং boundu একই রেফারেন্স ধরে আছে। যখন তুই কোনো non-primitive টাইপ (যেমন অ্যারে বা অবজেক্ট) কপি করবি, তখন আসলে নতুন ভ্যালু কপি হয় না; বরং একই রেফারেন্স শেয়ার করে।
Spread Operator দিয়ে রেফারেন্স সমস্যা এড়ানো
তুই যদি Spread operator ইউজ করস, তাহলে রেফারেন্সের এই সমস্যা হবে না এবং friends-এ নতুন কোনো উপাদান যোগ করলেও সে কপি করা dosto নামক অ্যারেতে যোগ হবে না।
const friends = [4, 5, 87, 9];
const dosto = [...friends];
console.log(dosto);
friends.push(100);
console.log(dosto);
console.log(friends);
Output: [4, 5, 87, 9][(4, 5, 87, 9)][(4, 5, 87, 9, 100)];এখানে দেখা যাচ্ছে, friends-এ নতুন উপাদান যোগ করার পরেও dosto অ্যারের ভ্যালু পরিবর্তিত হয়নি। কারণ, আমরা spread operator ব্যবহার করে friends-এর একটি নতুন কপি তৈরি করেছি এবং তাদের রেফারেন্স থেকে আলাদা হয়েছে।
কপির সময় নতুন উপাদান যোগ করা
তুই চাইলে কপির সময় একইসাথে অ্যারের মধ্যে নতুন উপাদানও যোগ করতে পারবি spread operator-এর মাধ্যমে।
const friends = [4, 5, 87, 9];
const sonkha = [...friends, 9999];
console.log(sonkha);
Output: [4, 5, 87, 9, 100, 9999];এটা ছিল spread operator ব্যবহারের কিছু উদাহরণ, যা আমাদের অ্যারের বা অবজেক্টের মধ্যে উপাদানগুলো বা প্রোপার্টি নিয়ে কাজ করতে এবং রেফারেন্সের সমস্যা এড়াতে সাহায্য করে।
স্প্রেড অপারেটর দিয়ে অ্যারের মধ্যে যেকোনো জায়গায় অন্য অ্যারের সব উপাদান সহজেই যোগ করা যায়।
const fruits = ["Apple", "Banana"];
const moreFruits = ["Mango", ...fruits, "Orange"];
console.log(moreFruits);
Output: ["Mango", "Apple", "Banana", "Orange"];একসাথে একাধিক অ্যারেকে জোড়া লাগানো (Concatenate)
স্প্রেড অপারেটর দিয়ে সহজেই দুই বা তার বেশি অ্যারেকে একসাথে যোগ করা যায়।
const array1 = [1, 2];
const array2 = [3, 4];
const combinedArray = [...array1, ...array2];
console.log(combinedArray);
Output: [1, 2, 3, 4];এইভাবে অনেকগুলো অ্যারেকে একসাথে যোগ করতে পারবি।
অবজেক্ট কপি করা
অবজেক্ট ক্লোন বা কপি করার জন্যও স্প্রেড অপারেটর দারুণ কাজ করে।
const person = { name: "Amit", age: 30 };
const clonedPerson = { ...person };
console.log(clonedPerson);
Output: { name: "Amit", age: 30 }তবে খেয়াল রাখবি, এটি shallow copy তৈরি করে। যদি অবজেক্টের ভেতরে nested অবজেক্ট থাকে, সেটাকে ডিপ কপি করবে না।
অবজেক্টে নতুন প্রোপার্টি যোগ করা
অবজেক্ট কপি করার সময় চাইলে নতুন কিছু প্রোপার্টি যোগ করে দিতে পারবি।
const student = { name: "Rafi" };
const updatedStudent = { ...student, age: 22 };
console.log(updatedStudent);
Output: { name: "Rafi", age: 22 }অ্যারে বা অবজেক্টকে মিক্স, ক্লোন বা আপডেট করতে চাইলে স্প্রেড অপারেটর খুবই দরকারি।
মনে রাখবি, Spread Operator কিছু জিনিস 'বিছিয়ে দেয়', আর Rest Operator বাকি জিনিসগুলো 'জমা' করে।
Practice:
- নতুন একটা অ্যারে বানা, যেখানে প্রথম উপাদান হবে "variable", তারপরের উপাদানগুলো আসবে const technologies = ["Condition", "array", "loop"], অ্যারে Spread Operator দিয়ে কপি করে।
- myFruits নামে নতুন একটা অ্যারে তৈরি কর, যেখানে const fruits = ["Apple", "Banana", "Mango"], এই অ্যারেটার উপাদানগুলো থাকবে আর শেষে papaya, orange থাকবে।
- তিনটা অ্যারে আছে const frontEnd = ["JavaScript"], const backEnd = ["Node.js"], const database = ["MongoDB"], এগুলোকে Spread Operator দিয়ে একটাতে একত্রিত কর।
- const website = { name: "MySite", type: "e-commerce", status: "active" } এই অবজেক্টে নতুন প্রোপার্টি theme: "dark" যোগ করে নতুন অবজেক্ট তৈরি কর এবং প্রিন্ট কর।
- const young = { name: "Arif", age: 30, country: "B Baria" } এই অবজেক্টের একটি কপি তৈরি কর এবং country বাদে বাকিসব প্রোপার্টি নতুন অবজেক্টে রেখে প্রিন্ট কর।
- const car = { make: "Toyota", model: "Corolla", year: 2020 } এই অবজেক্টের একটি কপি তৈরি কর এবং year আপডেট করে 2032 করে নতুন অবজেক্ট তৈরি কর।
12-4: Export-import বিজনেস

বেশির ভাগ পোলাপান থাকে অগোছালোর চরম সীমানায়। তাদের বই, খাতা, বিছানা, বালিশ, জামা, কাপড়, ফোন, চার্জার— সব একসাথে দলা ফাকিয়ে থাকে। আর লাখে দুই-একটা লক্ষ্মী বাচ্চা আছে। যাদের সব গুছানো। বইয়ের জায়গায় বই, জামা-কাপড়ের জায়গায় জামা-কাপড়, বিছানা-বালিশের জায়গায় বিছানা-বালিশ। তাদের কোনো কিছু দরকার হলে একজাক্টলি সেই জায়গায় যাবে, আর নিয়ে আসবে। আর এইরকম একটা লক্ষ্মী বাচ্চার জন্য আশেপাশের ৫০ গ্রাম পর্যন্ত বাবা-মারা সন্তানদের বলতে থাকে তার পা ধুয়ে পানি খেতে।
কোডিং করার সময়ও তুই যদি সবকিছু এক জায়গায় জগাখিচুড়ি করে রাখিস, তাহলে কোথায় কী আছে, সেগুলা খুঁজে পাওয়া ভেজাইল্লা একটা অবস্থা হয়ে যাবে।
এইটার সমাধান হচ্ছে, ছোট ছোট করে গুছিয়ে আলাদা আলাদা ফাইলে কোড রাখা। আলাদা আলাদা ফাইলে কোড রাখাকে বলা হয় মডিউলে ভাগ করে কোড রাখা। মডিউল বলতে বড় কোনো একটা জিনিসের ছোট একটা অংশকে বুঝায় এবং জাভাস্ক্রিপ্টের ক্ষেত্রে সাধারণভাবে ধরতে পারস, মডিউল মানে আলাদা আলাদা ফাইল করে তাদের মধ্যে কোড আলাদা হলেও একটা ফাইল আরেকটা ফাইলের মধ্যে যে কোড আছে, সেগুলার কিছু ফাংশনালিটি ইউজ করতে পারবে, এমন একটাভাবে অনেক বড় বড় কোডগুলাকে গুছানো বা অর্গানাইজ করাকে বুঝায়।
যদিও আলাদা ফাইল মানেই আলাদা মডিউল না। তবে বুঝার সুবিধার জন্য প্রাথমিকভাবে ধরতে পারিস। তবে কেউ শক্ত করে ধরলে আবার আমার নাম বলিস না কিন্তু।
আলাদা আলাদা ফাইলে কোড ভাগ করার তিনটা সুবিধা আর তিনটা অসুবিধা আছে। তিনটা সুবিধা হচ্ছে—
১. ফাইলগুলো ছোট ছোট হয়। সিমিলার টাইপের জিনিস এক ফাইলে রাখা যায়। সহজে পড়া এবং বুঝা যায়।
২. কোনো কিছু খুঁজে বের করার দরকার হলে সেই ফাইলে গেলে সহজেই খুঁজে পাওয়া যায়। লম্বা-বিশাল-বড় একটা ফাইল হলে প্যাঁচাপেঁচি লেগে যায়।
৩. কোড ফাইলের মধ্যে আটকে রাখা যায়। বাহির থেকে চাইলেই ইউজ করতে পারবে, তবে চেইঞ্জ করতে পারবে না।
আর আলাদা আলাদা ফাইলে রাখার অসুবিধা হচ্ছে—
১. যেহেতু আলাদা আলাদা ফাইলে আছে, তাই এক ফাইল থেকে অন্য ফাইলে কোড ইউজ করতে হলে এক ফাইল থেকে কোড বাইরে ব্যবহার করার জন্য যে ফাইলে কোড আছে, সেখান থেকে এক্সপোর্ট করতে হবে।
২. যে ফাইল থেকে অন্য ফাইলের কোড ইউজ করবি, সেখানে কোড ইমপোর্ট করতে হবে।
৩. ছোট ছোট করে অনেক অনেক ফাইল হয়ে যায়, তখন ফোল্ডার বানিয়ে অর্গানাইজড করতে হয়।
এক্সপোর্ট-ইমপোর্ট
ধর, বাংলাদেশে কফি উৎপাদন হয় না। এখন যদি আমরা কফি খেতে চাই, তাহলে যেসব দেশে কফি উৎপাদন হয়, তাদেরকে কফি এক্সপোর্ট করতে হবে, আর আমাদের দেশে কফি ইমপোর্ট করতে হবে।
একইভাবে আমাদের দেশে অনেক ইলিশ মাছ আছে। অন্য দেশের দাদারা যদি ইলিশ মাছ খেতে কান্নাকাটি করে, তাহলে আমাদের দেশ থেকে ইলিশ মাছ এক্সপোর্ট করতে হবে এবং অন্যদেশ যারা ইলিশ খেতে চায়, তাদের ইলিশ ইমপোর্ট করতে হবে।
এইটুক বুঝলেই কাজ শেষ।
Export— কোনো ফাইল থেকে কোডের কিছু অংশ (যেমন ফাংশন, ভেরিয়েবল) "export" করতে পারবি। মানে, ওই ফাংশন বা ভেরিয়েবল বাইরে বের করে অন্য ফাইল চাইলে ব্যবহার করতে পারবি। তবে সাধারণত একটা ফাইলের সবকিছু এক্সপোর্ট করে না। কিছু জিনিস বাহির থেকে এক্সেস নেয়া দরকার, সেগুলাকে এক্সপোর্ট করে। আবার কিছু জিনিস ফাইলের ভিতরে সীমাবদ্ধ থাকে।
Import— একটা ফাইল থেকে "import" করে সেই export করা কোডের অংশ নিয়ে আসতে পারবি।
বিশেষ নোটস
মডিউল ইউজ করার জন্য দরকার হয় জাভাস্ক্রিপ্টের কিছু স্পেশাল টুলস, যেগুলাকে bundler বলে। ইউজ করতে হবে, অথবা ব্রাউজারকে module বলে দিতে হবে। যদি কোনো কারণে মডিউল প্র্যাকটিস করতে একটু সমস্যা হয়, তাহলেও কনসেপ্টটা এখন জেনে রাখ। পরে বড় ধরনের প্রজেক্ট সেটাপ করতে গেলে বেশির ভাগ সময় অটোমেটিকভাবেই মডিউল ইউজ করার সিস্টেম পেয়ে যাবি। বাড়তি কোনো কষ্ট করা ছাড়াই।
ধর, তুই একটা math.js ফাইল তৈরি করলি, যেখানে কিছু ম্যাথের সিম্পল যোগ-বিয়োগ আর গুণ করার ফাংশন লিখলি।
// math.js
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}এখন তুই এই add আর multiply ফাংশন ডিক্লেয়ার করার আগে export নামের একটা স্পেশাল কি-ওয়ার্ড লিখছিস। তারমানে এই জিনিসগুলো এক্সপোর্ট করা যাবে এবং দরকার হলে অন্য ফাইল থেকে এই ফাংশন দুইটাকে ইমপোর্ট করে ইউজ করতে পারবি।
ইমপোর্ট করার জন্য প্রথমে import লিখবি, তারপর হয় কোনো নাম লিখবি, না হয় অবজেক্ট ডিস্ট্রাকচারিংয়ের মতো করে এক বা একাধিক নাম লিখবি, তারপর from লিখবি, এরপর কোটেশনের মধ্যে স্ট্রিং আকারে লিখবি এবং কোনো ফাইল থেকে ইমপোর্ট করবি। যে ফাইল থেকে ইমপোর্ট করতেছস, আর যে ফাইলে ইমপোর্ট করতেছস, যদি দুইটা একই ফোল্ডারে থাকে, তাহলে ডট চিহ্নের পর ফরওয়ার্ড স্ল্যাশ দিয়ে তারপর ফাইলের নাম লিখে ফেলবি। নিচের মতো করে—
এখন ধর, তুই main.js ফাইল থেকে math.js-এর ফাংশনগুলো ব্যবহার করতে চাস।
// main.js
import { add, multiply } from "./math.js";
console.log(add(2, 3));
console.log(multiply(4, 5));
Output: 5;
20;তুই খেয়াল করলে বুঝবি, main.js ফাইলে কিন্তু add বা multiply ফাংশনগুলো ডিক্লেয়ার করা হয়নি। এইগুলা ইমপোর্ট করা হইছে math.js ফাইল থেকে। নরমালভাবে ইমপোর্ট করতে হলে যেটা যেটা ইমপোর্ট করবি, সেটাকে সেকেন্ড ব্র্যাকেটের { } মধ্যে রাখবি। অনেকটা destructuring-এর মতো। তোর যেটা যেটা দরকার, শুধু সেটার নাম সেকেন্ড ব্র্যাকেটের ভিতর রাখবি।
এইভাবে এক ফাইলের কোড অন্য ফাইল থেকে ইউজ করা যায়।
Named Export আর Default Export
কখনো ইচ্ছামতো নাম দিয়ে ইমপোর্ট করতে চাইলে যে ফাইল থেকে ইমপোর্ট করবি, সেখানে হয় export-এর পর default ইউজ করবি। তখন ইচ্ছামতো নাম দিতে পারবি, আবার সেকেন্ড ব্র্যাকেটের ভিতরেও রাখা লাগবে না। তবে মডিউল (বা একটা ফাইলে) একটার বেশি ডিফল্ট export রাখতে পারবি না।
দরকার হলে ইমপোর্ট করার পর যাকে ইমপোর্ট করা হয়েছে, সেটার নাম চেইঞ্জ করে দিবি। নিচে প্রথমে default এক্সপোর্টের বিষয়টা দেখ।
// greeting.js
export default function greet() {
return "Hello, World!";
}এইটা import করলে এমন হবে—
// main.js
import specialGreet from './greeting.js';
console.log(specialGreet ());
Output: Hello, World!এখন greet ফাংশনটাকে যেকোনো নামে import করতে পারবি, কারণ default একটাই।
ইলিয়াস alias
ইমপোর্ট করার সময় চাইলে যেকোনো ইমপোর্টের নাম চেইঞ্জ করতে পারবি as নামক একটা স্পেশাল কি-ওয়ার্ড ইউজ করে। নিচের মতো করে—
import { add as sum, mult as multiply } from "./math.js";
console.log(sum(5, 3));
console.log(mult(5, 3));File path
যে ফাইল থেকে ইমপোর্ট করবি, আর যে ফাইলে ইমপোর্ট করবি, দুইটা যদি সেইম ফোল্ডারে থাকে, তাহলে সোজা সোজা তাদের ইমপোর্ট করতে পারবি। আর যদি ডিফারেন্ট ফোল্ডারে থাকে, তখন রিলেটিভ পাথ ব্যবহার করতে হবে। যখন বড় প্রজেক্টে কাজ করতে যাবি, তখন এই জিনিসটা দেখে নিবি। তখন দেখবি, কিছু ফোল্ডারের নাম আবার কিছু ডট ডট স্ল্যাশ ( ../ ) ইউজ করতেছে।
এতকিছু ঝামেলা মনে হলে জাস্ট দুইটা জিনিস বুঝার চেষ্টা করবি। না বুঝলে ফিউচারে আবার এই জিনিস দেখতে আসবি।
export মানে কোনো কোডকে বাইরের জন্য ওপেন করে রাখা। import মানে অন্য একটা ফাইলের দরকারি অংশ নিয়ে আসা।
Practice:
- export এবং import-এর মধ্যে পার্থক্য কী? উভয় কীভাবে কাজ করে?
- default export কী? এর মাধ্যমে ইমপোর্ট করার সময় কী সুবিধা হয়?
- as কি-ওয়ার্ড কীভাবে নাম পরিবর্তন করতে সাহায্য করে?
- নাম দিয়ে export আর Default export-এর মধ্যে পার্থক্য কী?
- এক ফাইল থেকে একাধিক default export কি সম্ভব? কিভাবে সম্ভব?
