Home » blog » JavaScript Comparison Operators: Type Coercion & Quirks

JavaScript Comparison Operators: Type Coercion & Quirks

JavaScript Comparison!
Programming-এ ডিসিশন মেকিং ব্যাপারটা অনেকটা আমাদের রিয়েল লাইফের রিলেশনশিপ বা ঝগড়ার মতো!

কে কার চেয়ে বড়, কে কার সমান, আর কে একদমই আলাদা এগুলো নিয়ে সারাদিন ক্যাচাল লেগেই থাকে।

JavaScript Comparison Operators
JavaScript Comparison Operators

JavaScript-ও এর ব্যতিক্রম নয়। তবে, মজার ব্যাপার হলো, JavaScript-এর comparison মাঝে মাঝে এমন সব ভেল্কি দেখায়, যা দেখে তোমার মনে হতে পারে, “ভাই, তুই আসলে চাস কী?”

ম্যাথে যেমন আমরা বিভিন্ন comparison operators ব্যবহার করি, কোডিংয়েও লজিক বিল্ড করার জন্য এগুলো ছাড়া একদিনও চলা সম্ভব না।

চলো, আজ JavaScript-এর বিভিন্ন ধরনের comparison, এগুলোর পেছনের লজিক এবং কিছু অদ্ভুত (quirky) আচরণ সম্পর্কে একদম সহজ ভাষায় বিস্তারিত জেনে নিই।

The Basic Comparison Operators

JavaScript-এ সাধারণত নিচের অপারেটরগুলো সবচেয়ে বেশি ব্যবহার করা হয়:

  • Greater/less than: a > b, a < b
  • Greater/less than or equals: a >= b, a <= b
  • Equals: a == b (এখানে একটা বিশাল ভুল আমরা প্রায়ই করি! খেয়াল রেখো, ডাবল ইকুয়াল == মানে হলো equality চেক করা, আর সিঙ্গেল = মানে হলো কোনো ভ্যালু assign করা)।
  • Not equals: ম্যাথের খাতায় আমরা লিখলেও, JavaScript-এ এটি লিখতে হয় a != b

The Result is Always a Boolean

যেকোনো comparison অপারেটর দিন শেষে তোমাকে মাত্র দুটি উত্তরের যেকোনো একটি দেবে হয় হ্যাঁ, নয় না। অর্থাৎ, এটি একটি Boolean ভ্যালু রিটার্ন করে:

  • true – মানে “হ্যাঁ”, “সঠিক” বা “একদম সত্যি কথা”।
  • false – মানে “না”, “ভুল” বা “ডাহা মিথ্যা”।

উদাহরণটা দেখো:

alert( 2 > 1 );  // true (সঠিক)
alert( 2 == 1 ); // false (ভুল)
alert( 2 != 1 ); // true (সঠিক)

তুমি চাইলে এই comparison-এর রেজাল্টকে যেকোনো ভ্যালুর মতোই সরাসরি একটি variable-এ স্টোর করে রাখতে পারো:

let result = 5 > 4; // comparison-এর রেজাল্ট assign করা হলো
alert( result ); // true

String Comparison (Lexicographical Order)

JavaScript যখন দুটি String-এর মধ্যে Comparison করে, তখন সে ডিকশনারির মতো “lexicographical” অর্ডার ফলো করে। সহজ কথায়, এটি letter-by-letter বা অক্ষর ধরে ধরে Comparison করে।

alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Bee' > 'Be' ); // true

অ্যালগরিদমটি কীভাবে কাজ করে?

  1. প্রথমে দুটি স্ট্রিংয়ের প্রথম ক্যারেক্টার চেক করে।
  2. যদি একটির প্রথম ক্যারেক্টার অন্যটির চেয়ে বড় হয়, তবে প্রথম স্ট্রিংটিই বড়। খেলা ওখানেই শেষ!
  3. যদি প্রথম ক্যারেক্টার সেম হয়, তবে দ্বিতীয় ক্যারেক্টার চেক করে। এভাবে চলতে থাকে।
  4. Glow এবং Glee এর ক্ষেত্রে: G এবং l সেম, কিন্তু o ক্যারেক্টারটি e এর চেয়ে বড়। তাই Glow জিতে যায়।

Unicode Order: তবে এটি পুরোপুরি ডিকশনারির মতো নয়, কারণ এখানে character case (বড় হাতের/ছোট হাতের অক্ষর) অনেক বড় একটা ফ্যাক্টর।

যেমন, "A" এর চেয়ে lowercase "a" বড়। কারণ JavaScript ইন্টারনালি Unicode এনকোডিং টেবিল ব্যবহার করে, আর সেখানে lowercase অক্ষরের ইনডেক্স ভ্যালু বেশি থাকে।

Comparison of Different Types (Type Coercion)

JavaScript খুব চালাক (মাঝে মাঝে একটু বেশিই)! যখন সে দেখে দুটি ভিন্ন ডেটা টাইপের (যেমন: String ও Number) মধ্যে Comparison হচ্ছে, তখন সে নিজে থেকেই স্ট্রিংগুলোকে Number-এ কনভার্ট করে নেয়।

একে বলা হয় Type Coercion

alert( '2' > 1 ); // true, স্ট্রিং '2' নাম্বার 2 হয়ে যায়
alert( '01' == 1 ); // true, স্ট্রিং '01' নাম্বার 1 হয়ে যায়

Boolean ভ্যালুর ক্ষেত্রে, true হয়ে যায় 1 এবং false হয়ে যায় 0

একটি মজার রেজাল্ট: মাঝে মাঝে এমন অদ্ভুত সিচুয়েশন তৈরি হয় যেখানে দুটি ভ্যালু == অপারেটরে সমান, কিন্তু তাদের Boolean ভ্যালু পুরোপুরি আলাদা!

let a = 0;
alert( Boolean(a) ); // false

let b = "0";
alert( Boolean(b) ); // true

alert(a == b); // true!

JavaScript-এর মাথা থেকে চিন্তা করলে এটি খুবই স্বাভাবিক। কারণ == চেক করার সময় "0" স্ট্রিংটি নাম্বার 0 তে কনভার্ট হয়ে যায়, তাই তারা সমান।

Strict Equality (===) vs Loose Equality (==)

সাধারণ equality চেক (==) এর একটি বড় সমস্যা হলো এটি 0 এবং false এর মধ্যে পার্থক্য করতে পারে না।

alert( 0 == false ); // true
alert( '' == false ); // true

কারণ == অপারেটর ভিন্ন টাইপের ডেটাকে Number-এ কনভার্ট করে নেয়। এম্পটি স্ট্রিং '' এবং false উভয়েই 0 হয়ে যায়।

তাহলে সমাধান কী? যদি তুমি চাও যে ডেটার ভ্যালুর পাশাপাশি তার ডেটা টাইপও চেক করা হোক (অর্থাৎ কোনো অটোমেটিক কনভার্সন ছাড়া), তাহলে Strict Equality Operator (===) ব্যবহার করতে হবে।

alert( 0 === false ); // false, কারণ তাদের টাইপ আলাদা

একইভাবে “strict non-equality” চেক করার জন্য !== ব্যবহার করা হয়। প্রো-লেভেলের কোডিংয়ে সবসময় === ব্যবহার করাটা বেস্ট প্র্যাকটিস, কারণ এটি অপ্রত্যাশিত বাগ (bugs) থেকে বাঁচায়।

The Quirky World of null and undefined

null এবং undefined এর আচরণ JavaScript-এর সবচেয়ে কনফিউজিং পার্টগুলোর মধ্যে একটি।

Strict Equality (===) এর ক্ষেত্রে: যেহেতু তাদের ডেটা টাইপ আলাদা, তাই তারা সমান নয়।

alert( null === undefined ); // false

Non-strict Equality (==) এর ক্ষেত্রে: JavaScript-এর একটি স্পেশাল রুল আছে null এবং undefined একে অপরের বেস্ট ফ্রেন্ড! তারা একে অপরের সমান, কিন্তু দুনিয়ার আর অন্য কোনো ভ্যালুর সমান নয়।

alert( null == undefined ); // true

Math Comparisons (<, >, <=, >=) এর ক্ষেত্রে: এখানে নিয়মটা পাল্টে যায়। null কনভার্ট হয়ে 0 হয়ে যায় এবং undefined কনভার্ট হয়ে NaN (Not a Number) হয়ে যায়।

অদ্ভুত রেজাল্ট (null vs 0):

alert( null > 0 );  // false (1)
alert( null == 0 ); // false (2)
alert( null >= 0 ); // true  (3)

ম্যাথের লজিক অনুযায়ী (3) নাম্বার যদি true হয়, তাহলে (1) বা (2) এর যেকোনো একটি true হওয়া উচিত।

কিন্তু এখানে == এবং >= সম্পূর্ণ আলাদা লজিকে কাজ করে। > বা >= চেক করার সময় null Number (0) এ কনভার্ট হয়। কিন্তু == চেক করার সময় কোনো কনভার্সন হয় না, আর null শুধুমাত্র undefined ছাড়া আর কারো সমান নয়।

The Incomparable undefined: undefined কে কারো সাথেই Comparison করা উচিত নয়।

alert( undefined > 0 ); // false
alert( undefined < 0 ); // false
alert( undefined == 0 ); // false

কারণ math comparison-এর সময় এটি NaN হয়ে যায় (যা সবার সাথেই false রিটার্ন করে) এবং equality-তে এটি শুধু null ছাড়া আর কারো সমান হয় না।

Bonus: Comparing Objects and Arrays

তুমি যদি স্ট্রিং বা নাম্বারের মতো করে Array বা Object কে Comparison করতে যাও, তাহলে বিশাল ধোঁকা খাবে!

alert( [1, 2] == [1, 2] ); // false!

কেন false? কারণ JavaScript যখন Non-primitive ডেটা টাইপ (Array, Object) Comparison করে, তখন সে ভেতরের ভ্যালু দেখে না।

সে দেখে তাদের Memory Reference বা ঠিকানা। যেহেতু দুটি আলাদা Array মেমোরির দুটি আলাদা জায়গায় তৈরি হয়েছে, তাই তারা কখনোই সমান নয়।

Advanced Tool: Object.is()

JavaScript-এ comparison করার জন্য আরেকটি পাওয়ারফুল মেথড আছে, সেটি হলো Object.is()। এটি প্রায় === এর মতোই কাজ করে, তবে দুটি বিশেষ ক্ষেত্রে এটি আলাদা:

  1. NaN এর Comparison: JavaScript-এ NaN === NaN সবসময় false রিটার্ন করে (যা বেশ অদ্ভুত)। কিন্তু Object.is(NaN, NaN) দিলে তুমি true পাবে।
  2. +0 এবং -0 এর Comparison : +0 === -0 রিটার্ন করে true, কিন্তু Object.is(+0, -0) রিটার্ন করে false

এতসব অদ্ভুত নিয়ম সবসময় মুখস্থ রাখার দরকার নেই! শুধু এই কয়েকটি গোল্ডেন রুল মনে রেখো:

  1. কোডিং করার সময় সবসময় Strict Equality (===) ব্যবহার করার চেষ্টা করবে। এটি অনেক ঝামেলা থেকে বাঁচাবে।
  2. null বা undefined এর সাথে যেকোনো comparison করার সময় অতিরিক্ত সতর্ক থাকবে।
  3. যদি কোনো ভ্যারিয়েবলের ভ্যালু null বা undefined হওয়ার সম্ভাবনা থাকে, তবে তার সাথে >=, >, <, <= অপারেটরগুলো সরাসরি ব্যবহার করবে না। আগে if কন্ডিশন দিয়ে ভ্যালু চেক করে নেবে।

Summary

To wrap things up, mastering JavaScript comparison operators comes down to understanding how the language handles different data types behind the scenes. Every comparison ultimately yields a boolean result, but the journey to get there can sometimes be a bit tricky. For instance, strings are evaluated lexicographically based on their Unicode values, meaning character casing matters. More importantly, when comparing different data types using loose equality (==) or mathematical operators, JavaScript triggers automatic type coercion, often converting values into numbers.

All Tech Update

Technology এর সকল আপডেট সবার আগে বিস্তারিত পড়ুন –

Scroll to Top