প্রোগ্রামিংয়ের জগতে ES6 (ECMAScript 2015) হচ্ছে একটা বড় ধরণের টার্নিং পয়েন্ট। যদি আপনি জাভাস্ক্রিপ্ট শিখতে থাকেন বা একটু আধটু কাজ করে থাকেন, তাহলে কিছু সময় পরই এই প্রশ্নটা মনে আসবে — "let, const, আর var এর মধ্যে আসলে পার্থক্যটা কী?" অথবা, "এই => সাইনটা দিয়ে সবাই কী করে?"
চিন্তার কিছু নেই, এই আর্টিকেলটা একদম হালকা ভাষায়, রিল্যাক্স মুডে আপনাকে ES6 এর সবচেয়ে দরকারি ফিচারগুলোর সাথে পরিচয় করিয়ে দিবে। আমরা একসাথে শিখবো let, const, arrow functions, destructuring, এবং আরও অনেক কিছু — ছোট ছোট উদাহরণ দিয়ে।
যারা একেবারে নতুন, তারাও ভয় না পেয়ে শুরু করতে পারেন। আর যারা পুরোনো জাভাস্ক্রিপ্ট জানেন, তাদের জন্য এটা একটা রিফ্রেশার বা ছোট্ট আপডেট গাইড। চলুন শুরু করা যাক।
১. Block Scope: let এবং const দিয়ে ভেরিয়েবল ডিফাইন করা
আগে JavaScript-এ ভেরিয়েবল ডিফাইন করতে আমরা শুধুমাত্র var
ব্যবহার করতাম। কিন্তু var
এর একটি বড় সমস্যা ছিল — এটি function scoped ছিল, অর্থাৎ এটি শুধু ফাংশনের ভেতরে সীমাবদ্ধ থাকত, ব্লকের (যেমন if
, for
, {}
ইত্যাদি) বাইরে চলে আসতেও পারত।
ES6 আমাদের দিয়েছে let
এবং const
, যা block scoped — অর্থাৎ যেখানে {}
ব্লক শুরু ও শেষ হয়, তার মধ্যেই থাকে।
- let: এমন ভেরিয়েবল যা আপনি ভবিষ্যতে পরিবর্তন করতে পারবেন
- const: এমন ভেরিয়েবল যার মান একবার সেট করার পর আর পরিবর্তন করা যাবে না
নিচের কোডটা দেখুন:
{
let x = 10;
const y = 20;
x = 15; // এটা ঠিক আছে
// y = 25; // এটা Error দিবে কারণ const পরিবর্তনযোগ্য না
}
console.log(x); // ReferenceError: x is not defined
উপরের কোডে, x
এবং y
ব্লকের বাইরে এক্সেস করতে গেলে এরর দিবে, কারণ let
এবং const
ব্লক স্কোপড।
এই ব্লক স্কোপিংয়ের সুবিধা হচ্ছে, আপনি নিরাপদে ভেরিয়েবল ব্যবহার করতে পারবেন — বাইরের কোনো কোড এক্সিডেন্টালি ভ্যালু পরিবর্তন করতে পারবে না।
{
let x = 10;
const y = 20;
// x = 15; // ঠিক আছে
// y = 25; // ERROR: বরাদ্দ পরিবর্তন করা যাবে না
}
// console.log(x, y); // ERROR: বাইরে অ্যাক্সেস নেই
২. Template Literals – ব্যাকটিক্স ব্যবহার
ES6 আসার আগে জাভাস্ক্রিপ্টে স্ট্রিং বানাতে হলে +
চিহ্ন দিয়ে কনক্যাট করতে হতো, যা দেখতে বিশৃঙ্খল ও রিডেবল ছিল না। ES6 আমাদের দিয়েছে Template Literals, যেটা backtick
(`) দিয়ে লেখা হয়।
এর দুইটি প্রধান সুবিধা:
- ইন্টারপোলেশন:
${}
এর মাধ্যমে সহজেই ভেরিয়েবল বা এক্সপ্রেশন স্ট্রিং-এর ভিতরে বসানো যায়। - মাল্টি-লাইন স্ট্রিং: একাধিক লাইনে স্ট্রিং লেখার জন্য আর
নিচের উদাহরণটি দেখুন:
const name = "Rafi";
const today = new Date().toLocaleDateString();
const msg = `স্বাগতম, ${name}!
আপনার আজকের তারিখ হলো ${today}`;
console.log(msg);
👆 এখানে আপনি দেখতে পাচ্ছেন, আমরা ${name}
এবং ${today}
ব্যবহার করে ভেরিয়েবল ইনসার্ট করেছি এবং নতুন লাইনে যেতে কোনো ঝামেলা হয়নি।
Template literals কোডকে করে তোলে আরো পরিচ্ছন্ন ও রিডেবল, বিশেষ করে যখন অনেক ভেরিয়েবল স্ট্রিং-এর মধ্যে বসাতে হয়।js
const name = "Rafi";
const msg = `স্বাগতম, ${name}!
আপনার আজকের তারিখ হলো
${new Date().toLocaleDateString()}`;
console.log(msg);
৩. Arrow Functions (=>) — ছোট ও পরিষ্কার ফাংশন লেখার নতুন উপায়
ES6 এ সবচেয়ে জনপ্রিয় এবং সুবিধাজনক ফিচারগুলোর একটি হলো Arrow Functions। এগুলো হল নতুন ধরনের ফাংশন ডিক্লারেশন যা দেখতে কমপ্যাক্ট এবং লেখতেও সহজ।
কেন Arrow Functions?
- ফাংশন লেখার সময় কম কোড লাগে
- লেক্সিক্যাল
this
ধরে রাখে (মানে, বাইরে যেই কন্টেক্সটে ফাংশন তৈরি হয়েছে, সেইthis
থাকে) - সাধারণ ফাংশনের চেয়ে অনেক ছোট ও পরিষ্কার কোড লেখা যায়
কেমন দেখায় Arrow Function?
// পুরনো ফাংশন
function sum(a, b) {
return a + b;
}
// Arrow function
const sum = (a, b) => a + b;
console.log(sum(3, 4)); // 7
এক প্যারামিটার হলে ব্র্যাকেট ছাড়াও লেখা যায়
const square = x => x * x;
console.log(square(5)); // 25
একাধিক স্টেটমেন্ট থাকলে ব্রেসের মধ্যে লিখতে হয়
const greet = name => {
const message = `হ্যালো, ${name}!`;
console.log(message);
};
greet('রফি');
Arrow function এ this
সমস্যা নেই
পুরনো ফাংশনে মাঝে মাঝে this
কে ধরে রাখতে bind
বা self=this
রাখতে হতো। কিন্তু Arrow Function বাইরে যেই this
থাকে, সেটাই ধরে রাখে।
const person = {
name: 'তারা',
hobbies: ['গান', 'ড্রইং'],
showHobbies() {
this.hobbies.forEach(hobby => {
console.log(`${this.name} পছন্দ করে ${hobby}`);
});
}
};
person.showHobbies();
Arrow functions কোডকে করে আরো স্বচ্ছ ও আধুনিক, তাই যেকোনো নতুন প্রজেক্টে এগুলো ব্যবহার করাই ভালো।
৪. Destructuring – অ্যারে ও অবজেক্ট থেকে মান সহজে বের করা
ES6 এর আরেক অসাধারণ ফিচার হলো Destructuring। এটি ব্যবহার করে আপনি সহজেই অ্যারে বা অবজেক্ট থেকে প্রয়োজনীয় মানগুলো আলাদা করে ভেরিয়েবলে নিতে পারেন — আর সেটা খুব পরিষ্কার ও ছোট কোডে।
অ্যারে Destructuring কী?
অ্যারের মানগুলোকে আলাদা করে ভেরিয়েবল হিসেবে ভাগ করে নেওয়া।
const fruits = ["আপেল", "কলা", "চেরি"];
const [first, second, third] = fruits;
console.log(first); // আপেল
console.log(second); // কলা
console.log(third); // চেরি
অবজেক্ট Destructuring কী?
অবজেক্টের প্রপার্টি থেকে সরাসরি নাম দিয়ে মান বের করা।
const person = {
name: "আলিফ",
age: 28,
country: "বাংলাদেশ"
};
const { name, age } = person;
console.log(name); // আলিফ
console.log(age); // 28
কিছু বিশেষ ব্যাপার
- আপনি নতুন নামও দিতে পারেন:
const { name: personName, country: nation } = person;
console.log(personName); // আলিফ
console.log(nation); // বাংলাদেশ
- ডিফল্ট মানও দিতে পারেন, যদি কোনো প্রপার্টি না থাকে:
const { city = "ঢাকা" } = person;
console.log(city); // ঢাকা (কারণ person-এ city নাই)
Destructuring ব্যবহার করলে আপনার কোড হবে অনেক বেশি পরিষ্কার এবং সহজে বোঝার মতো।
৫. Default Parameters & Rest Operator – ফাংশনকে আরও ফ্লেক্সিবল করা
Default Parameters কী?
পুরানো জাভাস্ক্রিপ্টে ফাংশনের প্যারামিটার না দিলে undefined
পাওয়া যেতো। ES6 এ আপনি প্যারামিটারের জন্য ডিফল্ট মান দিতে পারেন, যাতে যদি কেউ আর্গুমেন্ট না দেয়, তাহলে সেটি ওই ডিফল্ট ভ্যালু নেবে।
function greet(name = "বন্ধু") {
console.log(`হ্যালো, ${name}!`);
}
greet("রবি"); // হ্যালো, রবি!
greet(); // হ্যালো, বন্ধু!
Rest Operator কী?
...
দিয়ে ফাংশনে যতগুলো আর্গুমেন্ট আসুক সবগুলোকে একত্রে ধরে রাখতে পারেন, যাকে Rest Parameters বলে। এটা তখন কাজে লাগে যখন আপনি জানেন না কতগুলো আর্গুমেন্ট আসবে।
function sumAll(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sumAll(1, 2, 3)); // 6
console.log(sumAll(5, 10, 15, 20)); // 50
মিলিয়ে দেখুন
function greetEveryone(greeting = "হ্যালো", ...names) {
names.forEach(name => {
console.log(`${greeting}, ${name}!`);
});
}
greetEveryone("স্বাগতম", "রফি", "তারা", "আলিফ");
// আউটপুট:
// স্বাগতম, রফি!
// স্বাগতম, তারা!
// স্বাগতম, আলিফ!
greetEveryone(undefined, "রবি", "সারা");
// হ্যালো, রবি!
// হ্যালো, সারা!
Default Parameters আর Rest Operator একসাথে ব্যবহার করলে ফাংশন আরও শক্তিশালী ও নমনীয় হয়।
৬. Spread Operator (...
) – অ্যারে ও অবজেক্ট সহজে ম্যানিপুলেট করা
ES6 এ আসা এক জনপ্রিয় ফিচার হলো Spread Operator। এটি ...
চিহ্ন দিয়ে বোঝানো হয় এবং এটি মূলত একটি অ্যারে বা অবজেক্টের সব আইটেমকে আলাদা করে ছড়িয়ে দেয়।
Spread Operator কেন দরকার?
- অ্যারে বা অবজেক্টের কপি তৈরি করতে
- একাধিক অ্যারে বা অবজেক্ট একত্রিত করতে
- ফাংশনে অনেক আর্গুমেন্ট পাস করতে
Spread দিয়ে অ্যারে কপি বা মিক্স করা
const arr1 = [1, 2, 3];
const arr2 = [4, 5];
// arr1 কে পুরোপুরি কপি করে তারপর arr2 এর আইটেমগুলো যোগ করলাম
const combined = [...arr1, ...arr2, 6];
console.log(combined); // [1, 2, 3, 4, 5, 6]
Spread দিয়ে অবজেক্ট কপি ও মিক্স করা
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
// obj1 কপি করলাম, তারপর obj2 এর প্রপার্টি যোগ বা ওভাররাইড করলাম
const merged = { ...obj1, ...obj2 };
console.log(merged); // { a: 1, b: 3, c: 4 }
Spread দিয়ে ফাংশনে আর্গুমেন্ট পাঠানো
function add(a, b, c) {
return a + b + c;
}
const nums = [1, 2, 3];
console.log(add(...nums)); // 6
Spread Operator ব্যবহার করলে কোড লেখাটা হয় অনেক বেশি সহজ ও রিডেবল, বিশেষ করে যখন ডাটা ম্যানিপুলেট করতে হয়।
৭. Classes & Subclassing – জাভাস্ক্রিপ্টে অবজেক্ট-অরিয়েন্টেড প্রোগ্রামিং
ES6 এ Class হলো একটি নতুন সিনট্যাক্স যা JavaScript এর পুরনো প্রোটোটাইপ ভিত্তিক ওবজেক্ট ক্রিয়েশনকে সহজ ও পরিষ্কার করে। এটি ক্লাস-ভিত্তিক প্রোগ্রামিং (OOP) করার সুযোগ দেয়।
Class কী?
একটা Class
হচ্ছে একটি টেমপ্লেট যা থেকে আপনি অনেকগুলো অবজেক্ট তৈরি করতে পারেন, যার নিজস্ব প্রপার্টি ও মেথড থাকে।
Class ডিফাইন ও ব্যবহার
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} আওয়াজ করছে`);
}
}
const dog = new Animal('কুকুর');
dog.speak(); // আউটপুট: কুকুর আওয়াজ করছে
constructor
হলো বিশেষ মেথড যা নতুন অবজেক্ট তৈরির সময় কল হয়this
দিয়ে ক্লাসের প্রপার্টি অ্যাক্সেস করা হয়
Subclassing (ইনহেরিট্যান্স) কী?
ক্লাস থেকে আরেকটি ক্লাস তৈরি করে পুরানো ক্লাসের বৈশিষ্ট্যগুলো নেওয়া এবং নতুন ফাংশনালিটি যোগ করা হয়।
class Dog extends Animal {
speak() {
console.log(`${this.name} ভুঁকছে`);
}
}
const rex = new Dog('রেক্স');
rex.speak(); // আউটপুট: রেক্স ভুঁকছে
extends
দিয়ে ইনহেরিট করা হয়- সাবক্লাসে একই নামের মেথড লেখা হলে পুরানো মেথড ওভাররাইড হয়
Super কী?
সাবক্লাস থেকে প্যারেন্ট ক্লাসের মেথড বা কনস্ট্রাক্টর কল করতে super
ব্যবহার হয়।
class Cat extends Animal {
constructor(name, color) {
super(name); // প্যারেন্ট ক্লাসের কনস্ট্রাক্টর কল
this.color = color;
}
speak() {
super.speak(); // প্যারেন্টের speak() কল
console.log(`${this.name} একটি ${this.color} বিড়াল`);
}
}
const kitty = new Cat('কিটি', 'সাদা');
kitty.speak();
// আউটপুট:
// কিটি আওয়াজ করছে
// কিটি একটি সাদা বিড়াল
সংক্ষেপে
- Class দিয়ে সহজে অবজেক্ট তৈরির টেমপ্লেট তৈরি হয়
- Subclassing দিয়ে কোড পুনরায় ব্যবহার ও সম্প্রসারণ সহজ হয়
- super দিয়ে প্যারেন্ট ক্লাসের ফাংশন কল করা যায়
৮. Modules (import
/ export
)
কোড ভাঙ্গতে ও পুনঃব্যবহারযোগ্যভাবে সাজাতে সুবিধা হয় ()
// math.js
export function add(a, b) { return a + b; }
// main.js
import { add } from './math.js';
console.log(add(4, 5)); // 9
৯. Promises ও Async/Await – অ্যাসিঙ্ক্রোনাস কোড সহজ করার আধুনিক উপায়
JavaScript-এ অনেক সময় এমন কোড থাকে যা অ্যাসিঙ্ক্রোনাস অর্থাৎ কোনো কাজ এক্সিকিউট হতে কিছুক্ষণ সময় লাগে — যেমন: ডেটা ফেচ করা, ফাইল পড়া, API কল ইত্যাদি। ES6+ আসার আগে এগুলো হ্যান্ডেল করতে Callback ব্যবহার করা হত, কিন্তু সেটা অনেক জটিল ও পড়তে কষ্টকর হত।
Promises কী?
Promise হলো একটা অবজেক্ট যা ভবিষ্যতে কোনো অ্যাসিঙ্ক্রোনাস কাজ সম্পন্ন হলে সফল বা ব্যর্থ হওয়ার অবস্থা ধারণ করে। এটি আমাদের অ্যাসিঙ্ক্রোনাস কোডকে আরও ক্লিন ও ম্যানেজেবল করতে সাহায্য করে।
Promise তৈরি ও ব্যবহার
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve("ডেটা পাওয়া গেছে!");
} else {
reject("কিছু সমস্যা হয়েছে");
}
}, 1000);
});
};
fetchData()
.then(data => console.log(data))
.catch(error => console.error(error));
resolve
হল কাজ সফল হলে কল হয়reject
হল কাজ ব্যর্থ হলে কল হয়.then()
ও.catch()
দিয়ে সফলতা বা ব্যর্থতা হ্যান্ডেল করা হয়
Async/Await কী?
ES8 (ES2017) এ এসেছে Async/Await, যা Promises-এর উপর ভিত্তি করে লেখা হয়, কিন্তু দেখতে অনেক সহজ ও সিঙ্ক্রোনাস কোডের মত। এর মাধ্যমে আমরা অ্যাসিঙ্ক্রোনাস কাজগুলোকে সহজে লিখতে ও বুঝতে পারি।
Async/Await ব্যবহার
const fetchData = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve("ডেটা পাওয়া গেছে!");
}, 1000);
});
};
async function getData() {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.error(error);
}
}
getData();
async
ফাংশন সবসময় Promise রিটার্ন করেawait
দিয়ে Promise রেজল্ভ হওয়ার অপেক্ষা করা হয়try/catch
দিয়ে এরর হ্যান্ডেল করা যায়
সংক্ষেপে
Promise | Async/Await |
---|---|
.then() দিয়ে হ্যান্ডেল | কোড দেখায় সিঙ্ক্রোনাস মত |
কম্প্লেক্স হলে জটিল হয় | কোড ক্লিন ও পড়তে সহজ |
কলব্যাক হেল কমায় | এরর হ্যান্ডলিং সহজ হয় |
১০. নতুন Collection & Symbol – ES6 এর শক্তিশালী ডাটা স্ট্রাকচার ও ইউনিক আইডেন্টিফায়ার
ES6 এ কিছু নতুন ডাটা স্ট্রাকচার এবং বিশেষ ধরনের ডাটা টাইপ এসেছে, যা জাভাস্ক্রিপ্টের কাজ আরও সহজ ও শক্তিশালী করে।
নতুন Collection গুলো:
ES6 এ তিনটি নতুন কালেকশন এসেছে:
- Map
- Set
- WeakMap এবং WeakSet (অল্প পরিচিত, কিন্তু গুরুত্বপূর্ণ)
১. Map
- Key-value জোড়া সংরক্ষণ করে, যেখানে কী যেকোনো টাইপ হতে পারে (string, object, ইত্যাদি)।
- সাধারণ অবজেক্টের মতো, কিন্তু অনেক বেশি ফাংশনালিটি নিয়ে।
const map = new Map();
map.set('name', 'রহিম');
map.set(1, 'এক');
map.set(true, 'সত্য');
console.log(map.get('name')); // রহিম
console.log(map.has(1)); // true
console.log(map.size); // 3
২. Set
- ইউনিক মানগুলো সংগ্রহ করে। অর্থাৎ ডুপ্লিকেট রাখা হয় না।
- সাধারণত ইউনিক আইটেম রাখার জন্য ব্যবহার করা হয়।
const set = new Set();
set.add(10);
set.add(20);
set.add(10); // এটা যোগ হবে না কারণ আগেই আছে
console.log(set.has(10)); // true
console.log(set.size); // 2
৩. Symbol
- Symbol হলো একটি ইউনিক, ইমিউটেবল (পরিবর্তনশীল নয়) ডাটা টাইপ।
- প্রপার্টি বা আইডেন্টিফায়ার হিসেবে ব্যবহার হয়, যাতে অন্য কোনও প্রপার্টির সাথে কনফ্লিক্ট না হয়।
- প্রতিবার
Symbol()
কল করলে একটি নতুন ইউনিক সিম্বল তৈরি হয়।
const sym1 = Symbol('id');
const sym2 = Symbol('id');
console.log(sym1 === sym2); // false
const user = {
[sym1]: 123,
name: 'আলম',
};
console.log(user[sym1]); // 123
সংক্ষেপে
- Map: কী-ভ্যালু সংরক্ষণে ফ্লেক্সিবল এবং পারফেক্ট
- Set: ইউনিক আইটেমের জন্য
- Symbol: ইউনিক প্রপার্টি আইডেন্টিফায়ার