Module ২ · type, operator আর coercion: '5' + 2 কেন 7 না
পুরো program: ইচ্ছে করে convert করা
এই lesson-এ যা শিখবে
- ছয়টা পুরো program লিখতে পারবে, যেগুলো text-কে number বানায়, number-কে text বানায়, আর যেকোনো value-কে true বা false বানায়, প্রতিটা convert তুমি নিজে বেছে নিয়ে।
- বুঝিয়ে বলতে পারবে
isNaN("abc")কেনtrueঅথচNumber.isNaN("abc")কেনfalse, আরparseInt("12px", 10)কেন 12 অথচNumber("12px")কেনNaN। toFixedআরIntl.NumberFormatদিয়ে মানুষের পড়ার মতো করে number সাজাতে পারবে, আর জানবে দুটোই ফেরত দেয় একটা string।
Phone-এর calculator app-টার কথা ভাবো। ওর button-গুলোর নিচে থাকে ছোট্ট একটা core: টাইপ করা text-কে number বানায়, হিসাবটা করে, তারপর উত্তরটাকে আবার text বানায়। ওই core-এর প্রতিটা লাইনই একটা convert, যেটা কেউ একজন ভেবেচিন্তে বেছেছে। Lesson 01 আর 02-এ engine নিজে থেকে convert করেছে, অনেক সময় চমকে দিয়ে। এই lesson-এ convert হবে ইচ্ছে করে, ছয়টা program-এ: calculator-এর ওই core থেকে শুরু করে এমন একটা পর্যন্ত, যেটা একজন কাজের programmer সত্যিই ship করে।
সাতটা converter, এক table-এ
Lesson 01-এ তিনটা converter দেখেছ, যারা যেকোনো value নেয়: Number(), String() আর Boolean()। আসল program-এ লাগে আরও চারটা। Radix মানে সংখ্যা লেখার ভিত্তি (base): রোজকার সংখ্যার জন্য 10, binary-র জন্য 2, hexadecimal-এর জন্য 16।
| Converter | কী নেয় | কী ফেরত দেয় | উদাহরণ | ফল |
|---|---|---|---|---|
Number(x) | যেকোনো value | একটা number; পুরো text-টা number না হলে NaN | Number("12px") | NaN |
String(x) | যেকোনো value | একটা string | String(255) | "255" |
Boolean(x) | যেকোনো value | falsy value-গুলোর জন্য false, বাকি সবকিছুর জন্য true | Boolean("0") | true |
parseInt(text, radix) | text (অন্য কিছু দিলে আগে text হয়ে যায়) | সামনের দিকের পূর্ণসংখ্যাটা; সামনে কোনো digit না থাকলে NaN | parseInt("12px", 10) | 12 |
parseFloat(text) | text | সামনের দিকের দশমিক সংখ্যাটা, সবসময় base 10-এ | parseFloat("3.5kg") | 3.5 |
n.toFixed(digits) | একটা number | ঠিক অতগুলো দশমিক ঘরসহ একটা string | (1.005).toFixed(2) | "1.00" |
n.toString(radix) | একটা number | ওই base-এ লেখা একটা string | (255).toString(16) | "ff" |
তিন নম্বর কলামটা আরেকবার পড়ো। toFixed আর toString ফেরত দেয় string, number না, আর নিচের তিনটা common mistake-এর দুটোই এটা ভুলে যাওয়া থেকে আসে। মানে converter-এর নাম বলে সে কী পড়ে, আর table বলে কোন type বের হয়।
পুরো string, নাকি শুধু সামনের অংশ
Number() আর parseInt() দুটোই text-কে number বানায়, তবু "12px" নিয়ে দুজনের মত মেলে না। কেন, ছবিটা দেখো।
তাই যে value-কে শুরু থেকে শেষ পর্যন্ত পুরোটাই number হতে হবে, যেমন form-এর একটা field, তার জন্য Number()। আর যে text একটা number দিয়ে শুরু হয়ে তারপর অন্য কিছু বলে, যেমন "12px" বা "3.5kg", তার জন্য parseInt() আর parseFloat()।
চারটা converter-এর গড়ন
parseInt(text, 10)
parseFloat(text)
value.toFixed(digits)
new Intl.NumberFormat(locale).format(value)
textহলো যে string পড়া হবে। অন্য কিছু দিলে আগে সেটা string হয়ে যায়।10হলো radix, মানে কোন base-এ পড়বে। এই track সবসময় এটা লিখে দেয়।digitsবলে দশমিকের পরে কয়টা digit থাকবে, 0 থেকে 100। ফলটা একটা string।localeএকটা ভাষা আর একটা অঞ্চলের নাম, যেমন"en-US"বা"bn-BD"।newএকটা formatter বানায়;newজিনিসটা বুঝিয়ে বলবে Module 9।
নতুন যা: প্রতিটা token-কে নিজে হাতে Number() দিয়ে convert করা। Starter-এর nextInt() আসলে হুবহু Number(next()); এখানে দুই অংশই আলাদা করে দেখবে। Program-টা দুইটা সংখ্যা আর একটা operator পড়ে, তিনটাই text হিসেবে।
const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];
const left = next();
const op = next();
const right = next();
const a = Number(left);
const b = Number(right);
const result = op === "+" ? a + b : a * b;
out.push("text joined: " + (left + right));
out.push("converted: " + a + " " + op + " " + b + " = " + result);
console.log(out.join("\n"));
text joined: 75
converted: 7 + 5 = 12
এই output-টা input 7 + 5-এর জন্য। প্রথম লাইনটা Bob-এর পুরনো bug, ইচ্ছে করেই রেখে দেওয়া: দুইটা string জোড়া লেগেছে। দ্বিতীয় লাইন আগে convert করে, তারপর number যোগ করে। Ternary শুধু + আর * সামলায়; - আর / যোগ হবে অনুশীলন 2-এ।
দুইটা isNaN function, আর যেটা মিথ্যা বলে
একটা validator-এর একটাই প্রশ্ন: এই text-টা কি ঠিকঠাক একটা number-এ convert হলো? সংকেতটা হলো NaN, আর ওটা খোঁজার জন্য JavaScript-এ function আছে দুইটা। দুজন কিন্তু আলাদা প্রশ্নের উত্তর দেয়।
console.log(isNaN("abc"), Number.isNaN("abc"));
console.log(isNaN(""), Number.isNaN(""));
console.log(isNaN(undefined), Number.isNaN(undefined));
console.log(isNaN(NaN), Number.isNaN(NaN));
console.log(Number.isNaN(Number("abc")));
true false
false false
true false
true true
true
Global isNaN(x) আগে Number(x) চালায়, তারপর দেখে। তাই isNaN("abc") এমন একটা value নিয়ে true বলে, যেটা আসলে string, NaN না। মিথ্যাটা এখানেই: নাম শুনে মনে হয় সে জিজ্ঞেস করছে "এটা কি NaN?", অথচ উত্তর দিচ্ছে "এটা কি NaN হয়ে যাবে?"। Number.isNaN(x) কিছুই convert করে না, শুধু আসল NaN value পেলেই true বলে।
দুই নম্বর লাইনে দুজনেই ধোঁকা খায়। Number("") হলো 0, তাই খালি একটা field দিব্যি convert হয়ে যায়। তাই validator নিজে Number() দিয়ে convert করে, Number.isNaN() দিয়ে যাচাই করে, আর খালি input আসতে পারলে ""-টা আলাদা করে check করে।
নতুন যা: নিজে convert করা value-র উপর Number.isNaN() দিয়ে যাচাই।
const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];
const n = nextInt();
for (let i = 0; i < n; i++) {
const text = next();
const value = Number(text);
out.push(text + ": " + (Number.isNaN(value) ? "not a number" : "the number " + value));
}
console.log(out.join("\n"));
12: the number 12
-4.5: the number -4.5
abc: not a number
1e3: the number 1000
0x1f: the number 31
12px: not a number
Infinity: the number Infinity
এই output-টা input 7, তারপর 12 -4.5 abc 1e3 0x1f 12px Infinity-এর জন্য। 1e3 মানে 1 গুণ 10-এর ঘাত 3, আর 0x1f হলো 31-এর hexadecimal রূপ; Number() দুটোই পড়তে পারে। শেষ লাইনে একটা ফাঁক আছে: Infinity number হিসেবে পার পেয়ে যায়। ফাঁকটা বন্ধ হবে অনুশীলন 1-এ।
parseInt-এর radix, আগে আর এখন
ES5-এর আগে, মানে standard-এর 2009 সংস্করণের আগে, শুরুতে 0 থাকলে engine চাইলে সেটাকে octal (base 8) ধরে পড়তে পারত। কিছু পুরনো browser তাই করত, ফলে parseInt("08") দিত 0, কারণ 8 কোনো octal digit না। ES5 নিয়মটা তুলে দিয়েছে, আর Node 22 দেয় 8। যে ফাঁদটা আজও বেঁচে আছে, সেটা 0x। Radix না দিলে parseInt "0x1f"-কে hexadecimal ধরে পড়ে; radix 10 দিলে পড়ে "0", তারপর x-এ থেমে যায়।
নতুন যা: radix-সহ আর radix ছাড়া parseInt, আর parseFloat, পাশাপাশি Number()-এর সাথে।
const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];
const n = nextInt();
for (let i = 0; i < n; i++) {
const text = next();
out.push(text + ": Number " + Number(text) + ", parseInt " + parseInt(text) + ", base 10 " + parseInt(text, 10) + ", parseFloat " + parseFloat(text));
}
console.log(out.join("\n"));
12px: Number NaN, parseInt 12, base 10 12, parseFloat 12
3.5kg: Number NaN, parseInt 3, base 10 3, parseFloat 3.5
08: Number 8, parseInt 8, base 10 8, parseFloat 8
0x1f: Number 31, parseInt 31, base 10 0, parseFloat 0
1e3: Number 1000, parseInt 1, base 10 1, parseFloat 1000
abc: Number NaN, parseInt NaN, base 10 NaN, parseFloat NaN
এই output-টা input 6, তারপর 12px 3.5kg 08 0x1f 1e3 abc-এর জন্য। এক সারি করে পড়ো। 3.5kg-এর দশমিক বিন্দুতে আর 1e3-এর e-তে parseInt থেমে যায়, কারণ কোনোটাই digit না। parseFloat দুটোই পড়ে, কিন্তু hexadecimal কখনো পড়ে না। সামনের অংশ পড়া converter আগেভাগে থেমে যায়, কোনো warning ছাড়াই।
toFixed ফেরত দেয় text
toFixed(2) একটা number-কে দুই দশমিক ঘরে গোল করে, মানুষের পড়ার জন্য। ফেরত দেয় একটা string, আর গোল করে computer যে value-টা store করেছে সেটাকে, যেটা সবসময় তোমার টাইপ করা value না। Module 1-এ 0.1 + 0.2 print হয়েছিল 0.30000000000000004, কারণ number store হয় binary ভগ্নাংশ হিসেবে, যেটা কাছাকাছি, হুবহু না। 1.005 store হয় 1.00499999999999989... হিসেবে, তাই নিচের দিকে গোল হয়।
নতুন যা: toFixed, তার ফেরত দেওয়া string, আর store করা value-কে গোল করার ব্যাপারটা।
const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];
const bill = Number(next());
const percent = Number(next());
const tip = bill * percent / 100;
const tipText = tip.toFixed(2);
out.push("tip: " + tipText);
out.push("total: " + (bill + tip).toFixed(2));
out.push("typeof tipText: " + typeof tipText);
out.push("(1.005).toFixed(2): " + (1.005).toFixed(2));
console.log(out.join("\n"));
tip: 6.00
total: 46.00
typeof tipText: string
(1.005).toFixed(2): 1.00
এই output-টা input 40 15-এর জন্য: 40-এর bill, 15 শতাংশ tip। Total-এ আগে দুইটা number যোগ হয়, bill + tip, তারপরেই কেবল toFixed call হয়। আগে হিসাব, শেষে text: নিয়ম এটাই। নিয়মটা ভাঙলে কোন bill-এ এক cent খোয়া যায়, সেটা দেখাবে lesson 04।
নতুন যা: filter(Boolean), যেটা starter Module 1 থেকেই ব্যবহার করছে। Falsy value-গুলোর নাম lesson 01 বলে দিয়েছে: false, 0, "", null, undefined আর NaN, সাথে শূন্যের আরও দুই রূপ -0 আর 0n। এই program প্রতিটা print করে, তারপর এমন পাঁচটা value, যেগুলো শুধু দেখতেই খালি। check এক লাইনের একটা arrow function, starter-এর next-এর মতোই গড়ন।
const out = [];
const check = (label, value) => out.push(label + ": " + (Boolean(value) ? "truthy" : "falsy"));
check("false", false);
check("0", 0);
check("-0", -0);
check("0n", 0n);
check("empty string", "");
check("null", null);
check("undefined", undefined);
check("NaN", NaN);
check("the text 0", "0");
check("the text false", "false");
check("one space", " ");
check("empty array", []);
check("empty object", {});
const mixed = [0, "0", "", " ", null, "12", NaN, []];
const kept = mixed.filter(Boolean);
out.push("kept " + kept.length + " of " + mixed.length);
console.log(out.join("\n"));
console.log(kept);
false: falsy
0: falsy
-0: falsy
0n: falsy
empty string: falsy
null: falsy
undefined: falsy
NaN: falsy
the text 0: truthy
the text false: truthy
one space: truthy
empty array: truthy
empty object: truthy
kept 4 of 8
[ '0', ' ', '12', [] ]
String falsy হয় শুধু খালি হলে, তাই "0" আর "false" দুটোই truthy। Array বা object খালি হলেও truthy। শেষ লাইনটা Node যেভাবে array দেখায় সেভাবে, string-গুলো single quote-এ। তাই starter-এর filter(Boolean) input-এর দুই কিনারার খালি string-গুলো ফেলে দেয়, কিন্তু "0" token-টা রেখে দেয়।
Intl.NumberFormat, তোমার প্রথম built-in API
API (application programming interface) মানে একটা system তোমার code-কে যে তৈরি করা যন্ত্রপাতিগুলো দেয়। Intl browser আর Node দুই জায়গাতেই built-in একটা API, যার নিজের আলাদা standard আছে, ECMA-402। Intl.NumberFormat জানে প্রতিটা অঞ্চলের digit, ভাগ করে লেখা (grouping) আর মুদ্রার নিয়ম। Playground-এর Node 22-এ সব অঞ্চলের পুরো data আছে, তাই "bn-BD" বাংলা digit print করে।
নতুন যা: Intl.NumberFormat দিয়ে একই number তিন ভাবে সাজানো। Zara-র delivery app trip-গুলো মিটারে লেখে। ওর report দেখায় ইংরেজিতে আর বাংলায় কিলোমিটার, মাইল, আর US dollar-এ তেলের খরচ।
const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];
const n = nextInt();
const en = new Intl.NumberFormat("en-US");
const bn = new Intl.NumberFormat("bn-BD");
const usd = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" });
let totalKm = 0;
for (let i = 0; i < n; i++) {
const metres = Number(next());
const km = metres / 1000;
totalKm += km;
out.push(en.format(km) + " km | " + bn.format(km) + " km | " + en.format(km * 0.621371) + " mi");
}
out.push("total: " + en.format(totalKm) + " km");
out.push("fuel at $0.12 a km: " + usd.format(totalKm * 0.12));
console.log(out.join("\n"));
2.5 km | ২.৫ km | 1.553 mi
42.195 km | ৪২.১৯৫ km | 26.219 mi
1,234,567.891 km | ১২,৩৪,৫৬৭.৮৯১ km | 767,124.685 mi
total: 1,234,612.586 km
fuel at $0.12 a km: $148,153.51
এই output-টা input 3, তারপর 2500 42195 1234567891-এর জন্য; শেষ trip-টা আসলে একটা truck-এর সারা জীবনের odometer। একই number en-US-এ পড়া যায় 1,234,567.891, আর bn-BD-তে ১২,৩৪,৫৬৭.৮৯১, লাখের হিসাবে ভাগ করা। Currency formatter dollar চিহ্ন বসায় আর cent পর্যন্ত গোল করে। প্রতিটা format call একটা string ফেরত দেয়, তাই সাজানোটা সবার শেষের কাজ।
এটা কোথায় কাজে লাগে
- React Hook Form। Form field-এর value সবসময় string। Library-টার
register-এর optionvalueAsNumber: trueতোমার code-এর হাতে একটা number তুলে দেয়, আর ওদের documentation বলে convert না হলে ফেরত আসেNaN। - Express। Node-এর এই web framework একটা URL-এর query string রাখে
req.query-তে, তাই?page=2এসে পৌঁছায় string"2"হিসেবে। ওদের documentation সাবধান করে দেয়: এই value-গুলো user-এর input, ব্যবহারের আগে যাচাই করে নিতে হবে। - Next.js Commerce। Vercel-এর open-source দোকান template প্রতিটা দাম পায় string হিসেবে। ওর
Pricecomponent সেটাকেparseFloatদিয়ে convert করে, তারপরcurrencystyle-এIntl.NumberFormatদিয়ে সাজায়।
যে ভুলগুলো সবাই করে
১. toFixed-এর text-এর সাথে number যোগ করা।
const tip = 6;
const bill = 40;
const total = tip.toFixed(2) + bill;
console.log(total);
6.0040
কোনো error নেই, শুধু উত্তরটা ভুল। tip.toFixed(2) হলো string "6.00", তাই + text জোড়া লাগায়। লেখো (tip + bill).toFixed(2): আগে number, একদম শেষে একবার text। ভুলটা তুমি করবে, কারণ "6.00" দেখতে হুবহু একটা number-এর মতো।
২. Token-এর উপর toFixed call করা।
const price = "3.14159";
console.log(price.toFixed(2));
TypeError: price.toFixed is not a function
Playground-এর রায় Runtime error। price একটা string, next() থেকে আসা প্রতিটা token-ই তাই, আর string-এর কোনো toFixed নেই। লেখো Number(price).toFixed(2)। ভুলে যাবে, কারণ টাইপ করার সময় input-টা number-ই মনে হয়েছিল।
৩. হাজারের comma-ওয়ালা দামের উপর parseInt।
const price = "1,299";
console.log(parseInt(price, 10));
1
কোনো error নেই, আর দাম এখন 1। parseInt comma-তে থেমে সামনের অংশটা ফেরত দেয়। Number("1,299") হলো NaN, অন্তত জোরে আওয়াজ করে ব্যর্থ হয়। আগে comma-গুলো সরাও (কীভাবে, দেখাবে Module 3), নয়তো comma ছাড়া input চাও। চুপচাপ ভুল 1-এর চেয়ে জোরালো একটা NaN ভালো।
Zara Example 2-কে token 1e400 খাওয়ায়, যেটা একটা number-এর জন্য অনেক বড়, আর program বলে "the number Infinity"। ও এমন একটা validator চায়, যে অসীম value-গুলোকে আলাদা করে চেনে।
Input. এক লাইনে n, তারপর n-টা token, কোনোটার ভিতরে space নেই।
Output. প্রতিটা token-এর জন্য এক লাইন: value-টা সসীম number হলে yes আর String(Number(t)), Infinity বা -Infinity হলে infinite, আর NaN হলে no।
Constraints. n অন্তত 1। Token মানে space ছাড়া যেকোনো text।
Sample. Input 5, তারপর 12 abc Infinity -0 1e400 দিলে পাঁচ লাইনে yes 12, no, infinite, yes 0 আর infinite।
const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];
// your code: read with next() and nextInt(), push every line of output to out
console.log(out.join("\n"));
আলাদা করে grade হয় না। মূল validator-টা grade করে clean-numbers। Number.isFinite(x) true হয় শুধু এমন number-এর জন্য, যেটা NaN-ও না, অসীমও না, আর Number.isNaN-এর মতো এটাও কিছু convert করে না।
Example 1-কে বড় করে Alice-এর পুরো calculator বানাও। এটা একসাথে অনেকগুলো হিসাব পড়ে, আর প্রতিটার উত্তর দেয় ঠিক JavaScript যেভাবে দিত।
Input. এক লাইনে n, তারপর n-টা লাইনে a op b: তিনটা token, যেখানে op হলো +, -, * বা /।
Output. প্রতিটা লাইনের জন্য Number(a) op Number(b)-এর ফল, JavaScript যেভাবে print করে সেভাবে। Infinity, -Infinity আর NaN-ও উত্তর।
Constraints. 1 <= n <= 10000। a আর b প্রতিটা 1 থেকে 20 অক্ষরের একটা দশমিক সংখ্যা, negative হতে পারে, দশমিক বিন্দুও থাকতে পারে।
Sample. Input 5, তারপর পাঁচ লাইনে 7 + 5, 7 - 10, 0.1 * 3, 1 / 0 আর 0 / 0 দিলে পাঁচ লাইনে 12, -3, 0.30000000000000004, Infinity আর NaN।
const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];
// your code: read with next() and nextInt(), push every line of output to out
console.log(out.join("\n"));
calculator নামে grade হয়। Hidden test-এ শূন্য দিয়ে ভাগ আছে, আর convert না করে দুইটা token যোগ করে ফেলা program-কে সেগুলো ধরে ফেলে।
Kenji বলে, একটা সংখ্যার পূর্ণ অংশ যেভাবেই নাও, একই আসবে। তিনটা উপায়ে ওকে যাচাই করো: Math.trunc(Number(t)), যেটা দশমিকের পরের অংশ কেটে ফেলে; parseInt(t, 10); আর Math.floor(Number(t)), যেটা নিচের দিকে গোল করে।
Input. এক লাইনে n, তারপর n-টা token, প্রতিটা text-এ লেখা একটা সংখ্যা।
Output. প্রতিটা token-এর জন্য এক লাইন: token, একটা colon, তারপর ওই ক্রমে তিনটা ফল। শেষে === দিয়ে তিনটাই সমান হলে same, নইলে differ।
Constraints. n অন্তত 1। প্রতিটা token Number() দিয়ে একটা সসীম number-এ convert হয়।
Sample. Input 3, তারপর 7.9 -7.9 1e21 দিলে তিন লাইনে 7.9: 7 7 7 same, -7.9: -7 -7 -8 differ আর 1e21: 1e+21 1 1e+21 differ।
const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];
// your code: read with next() and nextInt(), push every line of output to out
console.log(out.join("\n"));
আলাদা করে grade হয় না। Sample-এর বাইরে নিজে একটা token খুঁজে বের করো, যেটায় তিনটার উত্তর আলাদা আসে। দামের জন্য তিনটার কোনটাকে ভরসা করবে, আর page নম্বরের জন্য কোনটাকে?
Run in Compilerসচরাচর যে প্রশ্নগুলো আসে
+textআরNumber(text)কি একই জিনিস?হ্যাঁ। Unary plus একই convert চালায়, তাই
+"42"হলো 42। এই track লেখেNumber(text), কারণ নাম দেখেই বোঝা যায় কাজটা কী। একলা একটা+পড়ার সময় চোখ এড়িয়ে যেতে পারে।Number("")কেন 0,NaNনা?Standard বলে, খালি text বা শুধু space-ওয়ালা text convert হয় 0-তে। নিয়মটা পুরনো, এখন বদলালে অসংখ্য website ভেঙে যাবে। তাই validator convert-এর উপর ভরসা করার আগে
""আলাদা করে check করে।টাকা গোল করতে কি
toFixedচলবে?শুধু দেখানোর জন্য। এটা text ফেরত দেয়, আর store করা binary value-টাকে গোল করে, তাই
(1.005).toFixed(2)হয়"1.00"। Lesson 04 টাকা গোনে পুরো cent-এ।bn-BDকেন digit-গুলো 12,34,567 এভাবে ভাগ করে?এটা দক্ষিণ এশিয়ার লাখ-কোটির হিসাব: প্রথমে তিনটা digit, তারপর দুইটা দুইটা করে। প্রতিটা অঞ্চলের নিয়ম
Intlনেয় locale data-র একটা সবার-ব্যবহারের database থেকে, যার নাম CLDR, মানে Unicode Common Locale Data Repository।"en-IN"-ও একইভাবে ভাগ করে, শুধু digit-গুলো Latin।
মূল কথা
Number()চায় পুরো text-টাই number হোক;parseIntআরparseFloatসামনের অংশ পড়ে চুপচাপ থেমে যায়।parseInt-কে সবসময় radix দাও:parseInt(text, 10)। পুরনো"08"-এর ফাঁদ আর নেই, কিন্তু"0x1f"এখনো hexadecimal হিসেবে পড়া হয়।- যাচাই করো
Number.isNaNআরNumber.isFiniteদিয়ে, যারা কিছু convert করে না; globalisNaNআগে convert করে, তারপর অন্য একটা প্রশ্নের উত্তর দেয়। toFixed,toStringআরIntl.NumberFormatসবাই string ফেরত দেয়: আগে হিসাব, একদম শেষে একবার সাজাও।- Falsy value হলো
false,0,"",null,undefinedআরNaN, সাথে-0আর0n;"0"," ",[]আর{}truthy। - আরও গভীরে: Interview Pack, output puzzle, প্রশ্ন আর bug gallery (Pro)।
এরপর Kenji একটা review comment-এ লেখে "never use ==", ঠিক সেই লাইনে যেখানে ==-ই ঠিক ছিল, আর lesson 04 ব্যাপারটার মীমাংসা করে।
lesson ৩ শেষ
শেষ হলে চিহ্ন দিন, অগ্রগতি আপনার সাথে থাকবে।
পরেরটা: == কখন, কখন না, আর বাকি judgement call-গুলো