জাভাস্ক্রিপ্ট টিউটোরিয়াল-শিখুন গল্পে গল্পে সাথে 1100+ Exercise

  • জাভাস্ক্রিপ্ট পরিচিতি-Introduction to JavaScript
  • প্রোগ্রামিং শুরু করতে কতটুকু গণিত লাগে?
  • প্রোগ্রামিং শুরু করতে কতটুকু ইংরেজি জানা লাগে?
  • ভালো প্রোগ্রামার কিভাবে হবো? [+৭টি গুরুত্বপূর্ণ টিপস]
  • Dynamic ডায়নামাইট
  • প্রাইমারি স্কুলের Primitive
  • ডিফাইনহীন Undefined
  • পল্টিবাজ নট (!), ডাবল দিলে কট
  • == এর বেইজ্জুতি Type coercion
  • কল মি callback
  • ছোট scope-এ বড় কথা !

== এর বেইজ্জুতি Type coercion


যেহেতু সমান সমান তুলনা করতে দুইটা সমান চিহ্ন আবার তিনটা সমান চিহ্ন ইউজ করা যায়, তাই এই দুইটার মধ্যে কিছু ডিফারেন্স আছে। আবার কিছু কমন জিনিসও আছে। আর এইগুলার কারণে কিছু প্যাঁচাপেঁচি হয়ে যায়। তবে ভিতরের কারণ জানলে বিষয়টা অনেক ফকফকা হয়ে যাবে। 


ট্রিপল ইকুয়াল ঠিক কথা বলবে। সে বলবে— 



2 আর '2' সেইম না। 

1 আর true সেইম না। 

null আর undefined সেইম না। 

এম্পটি স্ট্রিং ('') আর 0) সেইম না।

false আর '0' সেইম না। 

[ ] আর false সেইম না। 


এইগুলা সব আলাদা আলাদা টাইপের জিনিস এবং আলাদা আলাদা মান। তাই নিচের সবগুলা false আসবে। 


  console.log(2 === '2');
  console.log(1 === true);
  console.log(null === undefined);
  console.log('' === 0);
  console.log(false === '0');
  console.log([ ] === false);

Output: false false false false false false 


মজার বিষয় হচ্ছে, ওপরের সবগুলা কোম্পারিজন (তুলনা) যদি তুই ডাবল ইকুয়াল দিয়ে করতে যাস, সবগুলা true আসবে। 


  console.log(2 == '2');
  console.log(1 == true);
  console.log(null == undefined);
  console.log('' == 0);
  console.log(false == '0');
  console.log([ ] == false);


ডাবল ইকুয়াল এমন আকাম করে। সে কোন আক্কেলে বলে, খালি স্ট্রিং আর 0 সেইম কিংবা খালি array আর false সেইম। অথচ একটু আগে দেখছস [ ]-এর মান truthy, আর এখন বলতেছে, এইটা false-এর সমান। কী একটা বেইজ্জুতি অবস্থা। 


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


ডাবল ইকুয়ালের নেপথ্যে কলকাঠি কে নাড়ে?

ডাবল ইকুয়াল == ব্যবহারের সময় জাভাস্ক্রিপ্ট একটি ধাপে ধাপে প্রসেসের ভিতর দিয়ে যায়, যেটা টাইপ কনভার্সন (type coercion) নামে পরিচিত। এর মানে হচ্ছে, যদি দুইটা ভিন্ন টাইপের মান তুলনা করতে বলা হয়, জাভাস্ক্রিপ্ট ভিতরে ভিতরে দুইটাকে এক টাইপে কনভার্ট করে তারপর তুলনা করে। 


টাইপ কনভার্সন প্রক্রিয়া। নিচে এক ধাপ এক ধাপ দেখানো হলো, কীভাবে কাজটা হয়—


প্রথমে জাভাস্ক্রিপ্ট চেক করে, ডাবল ইকুয়ালের দুই সাইডে দুইটা ভ্যালুর টাইপ কি এক? যদি এক হয়, তাহলে মান চেক করে মান সেইম হলে true বলে দেয়। আর মান সেইম না হলে false বলে দেয়।


আর যদি ডাবল ইকুয়ালের দুইপাশে মান দুই টাইপের হয়, তাহলে জাভাস্ক্রিপ্ট ভিতরে ভিতরে আগে টাইপ কনভার্সন করবে। তারপর দুই সাইডের মান একই টাইপের করে তারপর তুলনা করবে।


যদি একপাশে নাম্বার আর অন্যপাশে স্ট্রিং থাকে, তাহলে স্ট্রিংটাকে নাম্বারে কনভার্ট করে তারপর তুলনা করে। যেমন, 2 == '2' তুলনা করার সময় '2'-কে আগে সংখ্যায় রূপান্তর করে সংখ্যায় বানায়। সেখানে 2 পায়, তারপর 2 আর 2 তুলনা করে। আর এখন যেহেতু দুই সাইডে মান সেইম হয়ে গেছে, তাই true বলবে। 


একইভাবে 2 == '20' তুলনা করতে গিয়ে প্রথমে '20'-কে সংখ্যায় রূপান্তর করবে। তারপর 2 আর 20 তুলনা করে দেখবে মান আলাদা। তাই বলবে, এই দুইটা সেইম না, অর্থাৎ false বলবে। 


প্রসেসটা তো বুঝতে পারছস?


ডাবল ইকুয়ালের একপাশে বুলিয়ান, আর আরেকপাশে সংখ্যা থাকলে বুলিয়ানকে সংখ্যায় রূপান্তর করে। আর বুলিয়ানকে সংখ্যায় রূপান্তর করতে গেলে true থাকলে সেটা সংখ্যায় 1 হয়, আর false থাকলে সেটা সংখ্যায় 0 হয়। তারপর বাকি সংখ্যার সাথে তুলনা করে। 


এই কারণে false == '0'-এর মান সত্য হয়। কারণ, false কনভার্ট হয়ে 0 হয়, তারপর বামপাশে 0 সংখ্যা আর ডানপাশে '0' স্ট্রিং। তখন ওপরের তিন নম্বর রুল অনুসারে স্ট্রিংকে সংখ্যায় রূপান্তর করে 0-এর সাথে 0 তুলনা করে। আল্টিমেটলি সত্য (true) হয়। 


সিমিলার স্টাইলেই জাভাস্ক্রিপ্ট বের করার চেষ্টা করে। false == '1', বা true == '1', বা true == '10' কোনোটার তুলনার মান সত্য হবে, আর কোনোটার তুলনার মান মিথ্যা হবে। 


যদি ডাবল ইকুয়ালের একপাশে object, আর অন্য পাশে কোনো প্রিমিটিভ ডাটা টাইপ (string, number, boolean), তাহলে প্রথমে object-কে তার প্রিমিটিভ ভ্যালুতে কনভার্ট করবে। তখন স্ট্রিংয়ে কনভার্ট করার জন্য toString ফাংশন ব্যবহার করতে পারে। 


যেমন ধর, [ ] == 0 এই তুলনা করার জন্য একপাশে [ ] (খালি অ্যারে, যা একটি object) এবং অন্যপাশে 0 (একটি number)। যেহেতু টাইপ দুইটার ভিন্ন (object এবং number), জাভাস্ক্রিপ্ট টাইপ কনভার্সন করবে। যখন object (যেমন [ ])-কে প্রিমিটিভ ভ্যালুতে কনভার্ট করার চেষ্টা করে, এটি কনভার্সন করার জন্য toString() কল করে এবং [ ].toString() খালি স্ট্রিং ("") রিটার্ন করে। এখন তুলনাটি দাঁড়ায়: "" == 0 এ। অর্থাৎ একপাশে খালি স্ট্রিং ("") এবং অন্যপাশে সংখ্যা (0)। এইখানেও টাইপ দুইটা ভিন্ন, তাই আবার টাইপ কনভার্সন করবে। খালি স্ট্রিং ("")-কে নাম্বারে কনভার্ট করলে 0 হয়। তারপর তুলনাটি দাঁড়ায়: 0 == 0 তে। তখন যেহেতু দুইটা ভ্যালুই এখন সংখ্যা (0) এবং একই মান হওয়ায় জাভাস্ক্রিপ্ট true রিটার্ন করে।


একই সিস্টেমে [ 1 ] == 1 তুলনা করার জন্য একপাশে [ 1 ] (অ্যারে, যা একটি object) এবং অন্যপাশে 1 (একটি number)। যেহেতু টাইপ দুইটার ভিন্ন (object এবং number), জাভাস্ক্রিপ্ট টাইপ কনভার্সন করবে। যখন object (যেমন [ 1 ] )-কে প্রিমিটিভ ভ্যালুতে কনভার্ট করার চেষ্টা করে।


এটি কনভার্সন করার জন্য toString() কল করে এবং [1 ].toString() স্ট্রিং ("1") রিটার্ন করে। এখন তুলনাটি দাঁড়ায়: "1" == 1 এ। অর্থাৎ একপাশে খালি স্ট্রিং ("1") এবং অন্যপাশে সংখ্যা (1)। তখন ওপরের কনভার্সন অনুসারে স্ট্রিং সংখ্যায় রূপান্তর হয়ে 1 == 1 হবে এবং true রিটার্ন করবে। 


এইবার বুঝছস, কীভাব জাভাস্ক্রিপ্ট মনে করে, একটা [ ] (খালি অ্যারে) কীভাবে 0-এর সমান হয়।


অর্থাৎ জাভাস্ক্রিপ্টে যত অদ্ভুত জিনিস আছে, তার সব কিছুরই লজিক্যাল ব্যাখ্যা আছে। 


null == undefined তুলনা করার সময় জাভাস্ক্রিপ্ট কোনো টাইপ কনভার্সন হয় না। শুধু এই দুটি ভ্যালুকে জাভাস্ক্রিপ্ট নিজে থেকেই সমান ধরে নেয়। তবে যখন null === undefined দিয়ে চেক করে, তখন === (স্ট্রিক্ট ইকুয়ালিটি) ব্যবহার করা হয়, তখন টাইপ এবং মান দুটোই চেক করা হয়। তাই null এবং undefined-এর টাইপ ভিন্ন হওয়ায় null === undefined-এর জন্য false রিটার্ন করে।


NaN == NaN কেন false হয়, সেটা বুঝতে গেলে প্রথমেই চিন্তা করতে হবে, জাভাস্ক্রিপ্ট অদ্ভুত হলেও লজিক্যাল নিয়মে চলে এবং NaN মানে "Not a Number" হলেও মজার বিষয় হচ্ছে, এটি নিজেই একটি number টাইপ। এ ছাড়া Not a Number-এর মানে হলো, এইটা কোনো স্পেসিফিক বা নির্দিষ্ট মান না। অর্থাৎ এইটার মান নির্দিষ্ট না। তাই একটা অনির্দিষ্ট মান আরেকটা অনির্দিষ্ট মানের সমান বা সেইম, সেটা বলা যাবে না। কারণ, একটা অনির্দিষ্ট মান যেকোনো কিছু হতে পারে। আবার অন্য আরেকটা অনির্দিষ্ট মান অন্য যেকোনো কিছুই হতে পারে। তাই এই দুইটা সেইম না। তবে কখনো NaN চেক করতে চাইলে isNaN(NaN) ফাংশনকে কল করবি। তাহলে সে বলে দিবে NaN কি না। 


ডাবল ইকুয়াল দরকার হলে টাইপ কনভার্সন করে, যা নতুন প্রোগ্রামারদের জন্য কনফিউজিং হতে পারে। এজন্যই === ব্যবহার করা ভালো। কারণ, এটি টাইপ এবং মান দুটোই চেক করে এবং কোনো কনভার্সন করে না।


Non-Primitive Comparison

আরেকটা বিষয়, যদি দুইটা object কম্পেয়ার করতে যাস—


  console.log( { } == { })

Output: false


তুই ভাবছিস, কেন এমন হলো? দুইটা দেখতে একই, কিন্তু আউটপুট false কেন? এটা শুধু object না, array-এর ক্ষেত্রেও একই হবে। কারণ, যখন তুই non-primitive (object/array) কম্পেয়ার করিস, তখন তারা ভ্যালু না; বরং reference চেক করে।


  const first = { };
  const second = first;

  console.log(first === second) 

Output: true


এখানে দেখ, second ভেরিয়েবল first-এর reference ধরে রেখেছে, তাই আউটপুট true এসেছে। Non-primitive টাইপের ক্ষেত্রে reference চেক হয়, মান চেক হয় না।


Practice Problems


  1. তুই একটা প্রোগ্রাম লিখে চেক কর, যদি true আর 1 ডাবল ইকুয়াল হয়, তবে “same” দেখাবে, আর না হলে “different” দেখাবে।  
  2. তুই দুইটা আলাদা object তৈরি কর, তারপর ট্রিপল ইকুয়াল দিয়ে চেক কর, তারা সমান কি না। যদি সমান না হয়, তাহলে কেন, তা চিন্তা কর।  
  3. একটা array তৈরি কর, তারপর আরেকটা ভেরিয়েবলে ওই array টাকে reference হিসেবে রাখ। এবার ট্রিপল ইকুয়াল দিয়ে চেক কর, এই দুইটা সমান কি না।  
  4. একটা ফাংশন লিখ, যেখানে প্রথম প্যারামিটার হলো, কোনো সংখ্যা আর দ্বিতীয় প্যারামিটার হলো boolean। ফাংশনটা চেক করবে, এই দুইটা মান ডাবল ইকুয়াল কি না, আর আউটপুট দেখাবে।
  5. খালি string এবং false সমান কি না, সেটা ডাবল ইকুয়াল দিয়ে চেক করে দেখ।
  6. null এবং undefined-কে ট্রিপল ইকুয়াল দিয়ে তুলনা কর এবং এর আউটপুট কী হয়, তা দেখ।
  7. 1 == '1' চেক কর এবং জাভাস্ক্রিপ্ট কীভাবে টাইপ কনভার্সন করে, তা ব্যাখ্যা কর।


Previous PageNext Page