জাভাস্ক্রিপ্ট স্প্রেড অপারেটর

Image result for js spreading
JavaScript Spread operator

মঙ্গোডিবির ইঞ্জিনিয়ার ম্যাট জাভালি একবার বলেছিল —আমরা জাভাস্ক্রিপ্ট ডেভেলপাররা বিভিন্ন জিনিসকে ফ্যান্সি (fancy) নাম দিতে পছন্দ করি। ব্যাপারটার একটা দারুণ ঊদাহরণ হতে পারে জাভাস্ক্রিপ্টের স্প্রেড অপারেটর। জিনিসটা খালি তিনটা ডট(…)। কিন্তু, নাম নিয়ে রেখেছে একটা বলিহরি। জাফর ইকবালের ভাষায় গালভরা নাম।

যাই হোক! দেখতে তিনটা ডট হলে জাভাস্ক্রিপ্টের স্প্রেড অপারেটর কাজে সত্যিই বলিহরি। সেটার বিভিন্ন ইউজ কেস নিয়েই আজকের এই লেখা।

ফাংশন ডেফিনিশন

ধরা যাক, আমার একটা ফাংশন আছে add() নামে যেটার কাজ যোগ করা। আমরা চাইলে কল করতে পারি add(2, 3)। কিন্তু, ব্যাপারটা এমন না যে, প্রোগ্রামিংয়ে আমাদের শুধু দু’টো সংখ্যা যোগ করতে হয়। এবং এটা খুবই স্বাভাবিক যে, প্রোগ্রাম লেখার সময়ে আমরা জানবোও না যে, প্রোগ্রাম রান করার সময়ে কয়টা সংখ্যা যোগ করতে হবে। এই ধরণের ইউজ কেসের খুব সহজ একটা সল্যুশন হচ্ছে স্প্রেড অপারেটর। স্প্রেড অপারেটর ইউজ করে আমরা চাইলে একটা ফাংশনে যত খুশি প্যারামিটার পাস করতে পারি। নিচের এক্সামপলটা দেখি।

এখন আমরা চাইলে add() ফাংশনে যত খুশি তত প্যারামিটার পাস করতে পারি। সবগুলো প্যারামিটার একসাথে অ্যারে আকারেargs ভ্যারিয়েবলে থাকবে। তাই আমরা চাইলেই তার ওপর লুপ চালিয়ে সবগুলো সংখ্যা যোগ করে নিতে পারি।

আরও জোশ ব্যাপার হচ্ছে, আমরা চাইলে রেগুলার প্যারামিটার আর স্প্রেড অপারেটর একসাথে ইউজ করতে পারি। আমরা চাইলেই লিখতে পারি add(p1, p2, ...rest)। পরবর্তীতে add(1, 2, 3) কল করা হলে p1 এর ভ্যালু হবে 1, p2 এর ভ্যালু হবে 2 এবং rest এর ভ্যালু হবে [3]

ফাংশন কল

ভাল কথা। এখন আমরা চাইলেই অ্যাড ফাংশনে ইচ্ছে মত প্যারামিটার পাস করতে পারি। কিন্তু, ঘটনা হচ্ছে — আমরা যদি না’ই জানি add() ফাংশনে প্যারামিটার কয়টা হবে, তাহলে সেটা পাস করার প্রোগ্রামটাই লিখব কীভাবে?

আমরা সবাই জানি, যখন আমরা জানি না আমার মোট কয়টা ভ্যারিয়েবল লাগবে, তখন আমরা অ্যারে ব্যবহার করতে পারি। জাভাস্ক্রিপ্টের স্প্রেড অপারেটর ইউজ করে আমরা চাইলে একটা অ্যারের ইলিমেন্টগুলো আলাদা আলাদা ভাবে ফাংশনের প্যারামিটার আকারেও পাস করতে পারি। মানুষের ভাষাটা গোলমেলে লাগলেও প্রোগ্রামিংয়ের ভাষাটা আয়তাকার লাগা উচিৎ।

সিরিয়াসলি এতটাই সোজা। এখন গম্ভীর মুখ কোন হোমরা চোমরা প্রশ্ন করতেই পারে — হেহ! একটা অ্যারেকে এত ঘুরিয়ে পেচিয়ে পাস করার কী আছে। সরাসরি অ্যারে আকারে পাস করে দিলেই পারো।

তা বটে! তা বটে! কিন্তু, যখন ফাংশনের সিগনেচারটা হবে add(p1, p2, ...rest), তখন কী করবেন মশাই? তখনও চাইলেই add(…params) লিখে দিলেই প্রথম আর দ্বিতীয় ভ্যালু p1, p2 তে বসে যাবে আর বাকিটুকু যাবে rest এ।

এখন অনেকে ভাবতে পারে, ফাংশন ডিফাইন করার সময়ে স্প্রেড অপারেটর ব্যবহার না করলে বুঝি ফাংশন কল করার সময়ে স্প্রেড অপারেটর ব্যবহার করা যাবে না। ব্যাপারটা মোটেও তেমন কিছু না। নিচের এক্সামপলটা দেখি।

Math.sin() ফাংশনের ডেফিনিশনে স্প্রেড অপারেটর ব্যবহার করা হয়নি। কিন্তু, আমরা চাইলেই ফাংশন কল করতে স্প্রেড অপারেটর ব্যবহার করতে পারি। অ্যারের ইলিমেন্টগুলো সিরিয়ালি ফাংশনের প্যারামিটারগুলোতে পাস হয়ে যাবে।

অ্যারে স্প্রেড

একটু বিদঘুটে ভাবে চিন্তা করলে …[1, 2, 3, 4] কে চিন্তা করা যায় 1, 2, 3, 4 আকারে। কারণ, আমরা যদি এই ভ্যালু গুলোকে হাতে লিখে ফাংশনে পাস করতাম, তাহলে 1, 2, 3, 4 আকারেই লিখতাম। স্প্রেড অপারেটরকে যখনই আমরা এভাবে চিন্তা করতে শুরু করব, তখন আরেকটা দারুণ জিনিস আবিষ্কার করব — আমরা এটা দিয়ে অনেক জোশ ভাবে অ্যারে ডিক্লেয়ার করতে পারি।

যদি আমরা …[1, 2, 3, 4] কে সত্যি সত্যিই 1, 2, 3, 4 আকারে চিন্তা করতে শুরু করি, তাহলে ওপরের এক্সামপলটা বুঝতে কষ্ট হওয়ার কথা না।

এটা বুঝতে পারলেই আমরা আরেকটা দারুণ জিনিস বুঝতে পারব। আমরা চাইলে স্প্রেড অপারেটর ব্যবহার করে অ্যারে কনক্যাট করতে পারি।

এভাবে আমরা চাইলে যত খুশি তত অ্যারে কনক্যাট করে ফেলতে পারি।

কিন্তু একটা জিনিস মাথায় রাখতে হবে। এভাবে অ্যারে কিন্তু সিঙ্গেল ডাইমেনশনের বেশি কনক্যাট করা যায় না। […[[1]], …[[2]]] এর রেজাল্ট [1, 2] নয় বরং [[1], [2]]

অবজেক্ট স্প্রেড

এই জিনিসটা প্রথম জানার পরে আমি নিজেও একটু ধন্দে পড়ে গিয়েছিলাম। ফাংশন ডেফিনিশনে এর ব্যাবহার অনেক ল্যাঙ্গুয়েজেই আছে। অ্যারে স্প্রেড করা তাও মেনে নিলাম। তাই বলে অবজেক্ট স্প্রেড! জাভাস্ক্রিপ্ট সত্যিই সেটা করতে পারে। আমিও নিজের চোখে না দেখলে বিশ্বাস করতাম না রাসেল ভাই।

এখানে যেটা হচ্ছে সেটা হচ্ছে, b ভ্যারিয়েবল ডিক্লেয়ার করার সময়ে আমরা যখন …a লিখছি তখন a ভ্যারিয়েবলের প্রতিটা key: value কমা সেপারেটেড আকারে b ভ্যারিয়েবলে পাস হয়ে যাচ্ছে। ওপরের এক্সামপলে তাই …a এর মানে x: 1, y: 1

অবজেক্ট স্প্রেড বুঝতে পারলে, আমাদের এটাও বোঝার কথা যে স্প্রেড অপারেটর দিয়ে আমরা চাইলে কয়েকটা অবজেক্টকে কনক্যাটও করে ফেলতে পারি। সেটার আর এক্সামপলে গেলাম না।

যেটা মাথায় আসতে একটু টাইম লাগবে, সেটা হচ্ছে আমরা চাইলে স্প্রেড অপারেটর ব্যবহার করে অবজেক্ট ক্লোন করতে পারি। আমরা যখন const b = {…a} লিখি তখন আসলে a অবজেক্টের একটা ক্লোন তৈরি হয়ে b ভ্যারিয়েবলে স্টোর হয়।

এই ক্লোনিংয়ের ব্যাপারটা আবিষ্কার করার পরেই অনেকে যে ভুলটা করার জন্য উঠে পড়ে লাগে সেটা হচ্ছে, নেস্টেড ক্লোনিংয়ের জন্য স্প্রেড অপারেটর ব্যবহার করা। নিচের এক্সামপলটা দেখি।

এই এক্সামপল থেকেই বোঝা যাচ্ছে, নেস্টেড ক্লোনিংয়ের জন্য আমরা আসলে স্প্রেড অপারেটর ব্যবহার করতে পারব না।

অ্যাসাইনমেন্ট

স্প্রেড অ্যাসাইনমেন্ট বোঝার আগে আমাদের ডিস্ট্রাকচারিং অ্যাসাইনমেন্ট (আরেকটা গালভরা নাম) নামক একটা জিনিস বুঝতে হবে। ধরা যাক, a = {x: 1, y: 2, z: 3}। এখন আমি যদি লিখি const {x} = a, তাহলে x নামে একটা ভ্যারিয়েবল তৈরি হবে যার ভ্যালু হবে a.x অর্থাৎ 1। একইভাবে যদি আমরা লিখি const {x, y} = a, তাহলে x এবং y এর মান হবে যথাক্রমে a.xa.y এর মান অর্থাৎ 12। একইভাবে j = [1, 2, 3] হলে const [m, n] = j লিখলে mn এর মান হবে যথাক্রমে 12। বোঝা গেল ব্যাপারটা?

এখন আমরা যদি লিখি const {x, …b} = a তাহলেই একটা দারুণ ব্যাপার ঘটবে। a.x এর মান x এ অ্যাসাইন হয়ে যাবে, আর a এর বাকি অংশ b তে অ্যাসাইন হয়ে যাবে। অর্থাৎ, b এর মান হবে {y: 2, z: 3}। একইভাবে const {x, y, …b} = a লিখলে b এর মান হবে {z: 3}। একইভাবে const [m, …k] = j লিখলে k এর মান হবে [2, 3]

এটুকু পড়ে কারও কারও মাথায় প্রশ্ন আসতে পারে, কী কী ধরণের ভ্যারিয়েবলের সাথে স্প্রেড অপারেটর ব্যবহার করা যায়। উত্তরটা হচ্ছে, যেকোন iterable ভ্যারিয়েবলের সাথে। এখব iterable কী এবং কেন, সেটা নিয়ে বকবক করা আছে এখানে। দারুণ আরেকটা ফিচারের সাথে পরিচিত হতে চাইলে চোখ বুলিয়ে নিতে পারেন।

হ্যাপি জাভাস্ক্রিপ্টিং!

পুনশ্চ ১: যদি = চিহ্নের বাম পাশে বা ফাংশন ডেফিনিশনে ব্যবহার করা হয়, তাহলে তাকে বলে রেস্ট অপারেটর। কিন্তু, এখানে সিম্প্লিসিটির জন্য তাকে স্প্রেড অপারেটরই বলা হয়েছে।

পুনশ্চ ২: অবজেক্ট অ্যাসাইনমেন্টের জন্য এর ব্যবহার (const {x, …b} = a) জাভাস্ক্রিপ্ট স্পেসিফিকেশনের অংশ না। এটা এখনও প্রপোজাল স্টেটে আছে। আশা করা যায় এটা কিছুদিনের মধ্যেই স্পেসিফিকেশনের অংশ হয়ে যাবে। তবে যে কেউ চাইলে এখনই babel এর সাহায্যে এই ফিচার ব্যবহার করা শুরু করে দিতে পারে।

--

--