نمایش خروجی در کنسول
برای بررسی مقدارها از log و برای پیامهای خطا از error استفاده کنید.
console.log("شروع برنامه");console.log(2 + 3);console.error("نمونهٔ پیام خطا");
راهنمایی فشرده و کاربردی برای نوشتن JavaScript مدرن؛ از تعریف داده و کنترل جریان تا طراحی توابع، کار با آرایهها و شیءها، ماژولها و مدیریت عملیات ناهمگام. مثالها مفاهیم کلیدی را در سناریوهای نزدیک به توسعهٔ واقعی مرور میکنند و برای مراجعهٔ سریع هنگام پیادهسازی و رفع اشکال آماده شدهاند. پایهٔ برنامهنویسی قابلاعتماد در JavaScript از شناخت نوع داده و انتخاب درست شیوهٔ نگهداری آن آغاز میشود. این بخش تعریف متغیرهای پایدار و قابلتغییر، تبدیل نوع، قالببندی رشته و خواندن خروجی و خطا در کنسول را پوشش میدهد. منطق تصمیمگیری برنامه را با عملگرهای حسابی، مقایسهٔ دقیق و ترکیب شرطها شفاف نگه دارید. مثالها تفاوت برابری سختگیرانه، مقادیر truthy/falsy و مقدار پیشفرض با nullish coalescing را نشان میدهند تا از نتایج ناخواستهٔ تبدیل نوع ضمنی جلوگیری کنید. از این صفحه بهعنوان مرجع سریع استفاده کنید و مثالها و نکتهها را با نسخهٔ ابزار، نیاز و شرایط واقعی پروژهٔ خود تطبیق دهید.
برای بررسی مقدارها از log و برای پیامهای خطا از error استفاده کنید.
console.log("شروع برنامه");console.log(2 + 3);console.error("نمونهٔ پیام خطا");const را پیشفرض بگیرید و فقط وقتی خود متغیر دوباره مقدار میگیرد از let استفاده کنید.
const courseName = "JavaScript";let lessonCount = 12;lessonCount += 1;عدد، رشته، بولین، undefined و null را از هم تشخیص دهید؛ typeof برای بیشتر نوعهای پایه کاربرد دارد.
const score = 18;const isReady = true;let selectedItem;const emptyValue = null;console.log(typeof score); // "number"console.log(selectedItem); // undefinedبرای ترکیب متن و مقدار از template literal استفاده کنید؛ ورودی کاربر را هنگام نمایش در HTML ایمن کنید.
const name = "Nina";const greeting = `Hello, ${name}!`;console.log(greeting);عملگرهای انتساب مقدار سمت چپ را تغییر میدهند؛ تبدیل نوع را هنگام دریافت ورودی صریح انجام دهید.
let total = 10;total += 5;const quantity = Number("3");console.log(total * quantity); // 45کامنت را برای دلیل یا تصمیم غیرآشکار نگه دارید و اطلاعات محرمانه را در آن ننویسید.
// توضیح کوتاه برای همین خط/* یادداشت چندخطی برای بخش محدود و مشخص*/برای جمع، تفریق، ضرب، تقسیم و باقیمانده از عملگرهای عددی استفاده کنید.
const sum = 8 + 3;const difference = 8 - 3;const product = 8 * 3;const quotient = 8 / 3;const remainder = 8 % 3;در بیشتر شرطها === و !== را بهکار ببرید تا مقدار و نوع هر دو مقایسه شوند.
console.log(5 === "5"); // falseconsole.log(5 !== 3); // trueconsole.log(10 >= 10); // true&& و || مقدار یکی از عملوندها را برمیگردانند؛ ! مقدار منطقی را معکوس میکند.
const canSubmit = isReady && score >= 10;const displayName = nickname || "مهمان";const isUnavailable = !isReady;از ?? برای جایگزینی فقط null یا undefined استفاده کنید؛ برخلاف || مقدار صفر و رشتهٔ خالی حفظ میشوند.
const retryLimit = configuredLimit ?? 3;const label = customLabel ?? "بدون عنوان";console.log(0 ?? 5); // 0شرطهای وابسته را با else if مرتب کنید و هر شاخه را تا حد امکان کوتاه نگه دارید.
if (score >= 18) { console.log("عالی");} else if (score >= 10) { console.log("قبول");} else { console.log("نیازمند تمرین");}عبارت سهتایی برای انتخاب یکی از دو مقدار ساده است؛ شرطهای چندمرحلهای را با if بنویسید.
const status = isReady ? "آماده" : "در انتظار";برای هر case از break استفاده کنید تا اجرای ناخواسته به حالت بعدی ادامه پیدا نکند.
switch (status) { case "ready": console.log("شروع"); break; case "waiting": console.log("کمی صبر کنید"); break; default: console.log("وضعیت نامشخص");}وقتی تعداد تکرار یا اندیس لازم است، مقدار آغاز، شرط توقف و گام را مشخص کنید.
for (let index = 0; index < 3; index += 1) { console.log(index);}در حلقهٔ while مطمئن شوید شرط در نهایت false میشود تا حلقه بیپایان نماند.
let remaining = 3;while (remaining > 0) { console.log(remaining); remaining -= 1;}for...of مقدارهای iterable مثل آرایه را میدهد و برای پیمایش کلکسیون معمولاً از for...in مناسبتر است.
const colors = ["آبی", "سبز"];for (const color of colors) { console.log(color);}for...in کلیدهای enumerable را میخواند؛ برای آرایهها بهجای آن for...of یا متدهای آرایه را ترجیح دهید.
const settings = { theme: "dark", compact: true };for (const key in settings) { console.log(key, settings[key]);}break حلقه را تمام میکند و continue فقط به تکرار بعدی میرود.
for (const value of [1, 2, 3, 4]) { if (value === 2) continue; if (value === 4) break; console.log(value);}return نتیجه را به فراخواننده میدهد؛ بدون return صریح، خروجی تابع undefined است.
function add(first, second) { return first + second;}console.log(add(4, 6)); // 10مقدار پیشفرض زمانی استفاده میشود که آرگومان حذف شده یا برابر undefined باشد.
function greet(name = "دوست") { return "سلام " + name;}console.log(greet());در بدنهٔ تکعبارتی میتوان آکولاد و return را حذف کرد؛ تابع پیکانی this مستقل ندارد.
const multiply = (first, second) => first * second;const double = value => value * 2;پارامتر rest آرگومانهای باقیمانده را در یک آرایه جمع میکند و باید آخرین پارامتر باشد.
function sumAll(...values) { return values.reduce((total, value) => total + value, 0);}console.log(sumAll(2, 3, 4)); // 9let و const به نزدیکترین بلوک محدودند؛ var دامنهٔ تابعی دارد و در کد جدید معمولاً لازم نیست.
if (true) { const message = "داخل بلوک"; console.log(message);}// message بیرون از بلوک در دسترس نیست.callback را برای واگذاری ادامهٔ کار به تابع دیگر استفاده کنید.
function runWith(value, callback) { return callback(value);}const result = runWith(5, number => number * 2);اندیس آرایه از صفر شروع میشود و length تعداد عضوها را برمیگرداند.
const scores = [12, 16, 19];console.log(scores[0]); // 12console.log(scores.length); // 3push و pop آرایهٔ اصلی را تغییر میدهند؛ push طول تازه و pop عضو برداشتهشده را برمیگرداند.
const queue = ["الف"];queue.push("ب");const lastItem = queue.pop();unshift و shift ابتدای آرایه را تغییر میدهند و برای مجموعههای بزرگ ممکن است پرهزینه باشند.
const items = ["میانی"];items.unshift("اول");const firstItem = items.shift();map برای هر عضو یک مقدار میسازد و آرایهٔ تازهای با همان تعداد عضو برمیگرداند.
const prices = [10, 20, 30];const discounted = prices.map(price => price * 0.9);filter همهٔ عضوهای مطابق شرط را برمیگرداند؛ find فقط نخستین عضو مطابق را پیدا میکند.
const scores = [8, 14, 19, 20];const passing = scores.filter(score => score >= 10);const firstHighScore = scores.find(score => score > 18);مقدار آغازین accumulator را مشخص کنید تا نتیجه برای آرایهٔ خالی هم قابل پیشبینی باشد.
const amounts = [3, 5, 7];const total = amounts.reduce( (sum, amount) => sum + amount, 0);concat یا spread آرایهٔ جدید میسازند و برای ترکیب دادهها نیازی به تغییر آرایهٔ اصلی نیست.
const first = [1, 2];const second = [3, 4];const combined = [...first, ...second];forEach برای اجرای عمل جانبی روی هر عضو مناسب است و برخلاف map آرایهٔ نتیجه نمیسازد.
["چای", "قهوه"].forEach((drink, index) => { console.log(index, drink);});ویژگی را با نقطه یا براکت بخوانید؛ براکت برای نام متغیر یا کلیدی که فاصله دارد لازم است.
const user = { name: "Mina", score: 18 };console.log(user.name);console.log(user["score"]);نام متغیر را میتوان بهعنوان کلید نوشت و کلید محاسبهشده را داخل براکت قرار داد.
const field = "email";const email = "mina@example.com";const profile = { email, [field + "Verified"]: true };ویژگیهای موردنیاز را از شیء جدا کنید و برای ویژگیهای احتمالی مقدار پیشفرض بدهید.
const user = { name: "Mina", role: "editor" };const { name, role, active = true } = user;spread ویژگیهای سطح اول را کپی یا ادغام میکند؛ شیءهای تودرتو همچنان مرجع مشترک دارند.
const defaults = { theme: "light", compact: false };const preferences = { ...defaults, theme: "dark" };در متدهای معمولی، this به نحوهٔ فراخوانی وابسته است؛ جداکردن متد از شیء میتواند پیوند this را از بین ببرد.
const counter = { value: 0, increment() { this.value += 1; },};counter.increment();constructor وضعیت آغازین نمونه را میسازد و متدهای کلاس روی prototype مشترک قرار میگیرند.
class Animal { constructor(name) { this.name = name; } speak() { return this.name + " makes a sound"; }}const pet = new Animal("Milo");extends رابطهٔ ارثبری میسازد؛ در سازندهٔ فرزند، super را پیش از استفاده از this فراخوانی کنید.
class Dog extends Animal { speak() { return super.speak() + "!"; }}چند مقدار را با نام صادر و فقط موارد موردنیاز را در فایل دیگر وارد کنید.
// math.jsexport const add = (a, b) => a + b;export const subtract = (a, b) => a - b;// app.jsimport { add, subtract } from "./math.js";هر ماژول حداکثر یک export پیشفرض دارد و نام واردشده را مصرفکننده انتخاب میکند.
// formatter.jsexport default function formatName(name) { return name.trim();}// app.jsimport formatName from "./formatter.js";ماژول واسط میتواند API عمومی چند فایل را یکجا در دسترس قرار دهد.
export { add, subtract } from "./math.js";export { default as formatName } from "./formatter.js";تابع اجرایی Promise همزمان اجرا میشود و با resolve یا reject نتیجه را تعیین میکند.
const task = new Promise((resolve, reject) => { const succeeded = true; if (succeeded) resolve("انجام شد"); else reject(new Error("عملیات ناموفق بود"));});then برای نتیجه و catch برای خطای زنجیره است؛ مقدار برگشتی هر مرحله به مرحلهٔ بعد میرود.
task .then(result => { console.log(result); return result.length; }) .then(length => console.log(length)) .catch(error => console.error(error));await داخل تابع async نتیجهٔ Promise را منتظر میماند و خطای ردشدن را میتوان با try/catch گرفت.
async function loadMessage() { try { const message = await task; console.log(message); } catch (error) { console.error(error); }}Promise.all وقتی همهٔ عملیات موفق شوند آرایهٔ نتیجهها را میدهد و با ردشدن یکی از آنها رد میشود.
const [profile, courses] = await Promise.all([ loadProfile(), loadCourses(),]);allSettled نتیجهٔ موفق یا ناموفق هر عملیات را نگه میدارد و با ردشدن یک مورد متوقف نمیشود.
const results = await Promise.allSettled([ loadProfile(), loadCourses(),]);برای عملیات وابسته await را پشت سر هم اجرا کنید؛ برای کارهای مستقل از Promise.all بهره بگیرید.
const account = await loadAccount();const settings = await loadSettings(account.id);JSON.stringify داده را به متن تبدیل میکند و JSON.parse ممکن است برای متن نامعتبر خطا بدهد.
const payload = { title: "درس", complete: false };const json = JSON.stringify(payload);const restored = JSON.parse(json);عنصر را با selector پیدا کنید و رفتار تعاملی را با addEventListener ثبت کنید، نه با ویژگیهای رویداد inline.
const button = document.querySelector("#save");button?.addEventListener("click", event => { console.log("ذخیره شد", event.currentTarget);});fetch برای پاسخ HTTP ناموفق Promise را رد نمیکند؛ response.ok را پیش از خواندن بدنه بررسی کنید.
async function loadItems() { const response = await fetch("/api/items"); if (!response.ok) { throw new Error("دریافت داده ناموفق بود"); } return response.json();}برای بدنهٔ JSON، روش و Content-Type را مشخص و خطای شبکه یا پاسخ ناموفق را مدیریت کنید.
const response = await fetch("/api/items", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ title: "درس تازه" }),});if (!response.ok) { throw new Error("ثبت داده ناموفق بود");}در کد جدید معمولاً fetch سادهتر است؛ XMLHttpRequest را برای نگهداری یا سازگاری با کدهای قدیمی بشناسید.
const request = new XMLHttpRequest();request.open("GET", "/api/items");request.responseType = "json";request.addEventListener("load", () => { if (request.status >= 200 && request.status < 300) { console.log(request.response); }});request.send();let و const در محدودهٔ بلوک تعریف میشوند؛ const بازانتساب را منع میکند اما بهتنهایی شیء یا آرایه را immutable نمیکند.
const settings = { theme: "dark" };settings.theme = "light"; // مجاز استlet count = 1;count += 1;if (count > 1) { const message = "در محدودهٔ بلوک";}عبارتهای داخل ${...} ارزیابی میشوند؛ برای متنهای چندخطی نیازی به چسباندن دستی رشتهها نیست.
const name = "Nina";const greeting = `سلام، ${name}!`;const message = `این رشتهچند خط دارد.`;موقعیت سمت چپ با موقعیت مقدار در آرایه متناظر است؛ میتوان بعضی موقعیتها را خالی گذاشت یا از rest برای باقیمانده استفاده کرد.
const coordinates = [12, 24, 36];const [x, y] = coordinates;const [first, , third] = coordinates;const [head, ...rest] = coordinates;نام ویژگیها بهطور پیشفرض نام متغیر میشود؛ با syntax نام مستعار و مقدار پیشفرض، دادهٔ اختیاری را روشن مدیریت کنید.
const user = { id: 7, profile: { name: "Nina" } };const { id: userId, role = "reader", profile: { name },} = user;پارامتر شیءای، قرارداد تابع را با نام ویژگیها مشخص میکند؛ مقدار پیشفرض کل شیء را نیز در صورت نبود ورودی پوشش دهید.
function greet({ name = "دوست", greeting = "سلام" } = {}) { return `${greeting}، ${name}!`;}greet({ name: "Nina" });پارامترهای پیشفرض هنگام حذف یا undefined اعمال میشوند؛ پارامتر rest باید آخرین پارامتر باشد و آرایهای از باقی ورودیها میسازد.
function sum(first = 0, ...values) { return values.reduce((total, value) => total + value, first);}sum(1, 2, 3); // 6Spread در literal آرایه، اعضای iterable را درج میکند؛ این روش آرایهٔ تازه میسازد و آرایهٔ اولیه را تغییر نمیدهد.
const admins = ["Ava"];const editors = ["Nima", "Sara"];const users = [...admins, ...editors];const copied = [...users];ویژگیهای بعدی میتوانند مقدارهای قبلی را override کنند؛ این کپی سطحی است و مقدارهای تودرتو کپی عمیق نمیشوند.
const defaults = { theme: "light", compact: false };const options = { ...defaults, ...userOptions, compact: true,};rest ورودیهای اضافی را جمع میکند و spread آنها را هنگام فراخوانی باز میکند؛ این دو عملگر نقشهای مکمل دارند.
function logAll(label, ...values) { console.log(label, ...values);}const scores = [18, 20];logAll("نمرهها:", ...scores);وقتی نام متغیر با نام ویژگی برابر است میتوان از shorthand استفاده کرد؛ براکت، نام کلید محاسبهشده را میپذیرد.
const field = "email";const email = "nina@example.com";const profile = { email, [`${field}Verified`]: true,};Getter و setter دسترسی به ویژگی را کنترل میکنند؛ نام متد کوتاه نحو مختصر تعریف متد در object literal است.
const account = { _closed: false, get closed() { return this._closed; }, set closed(value) { this._closed = Boolean(value); }, close() { this.closed = true; },};در تابع پیکانی تکعبارتی return ضمنی است؛ برای بازگرداندن object literal آن را داخل پرانتز قرار دهید.
const double = value => value * 2;const add = (first, second) => first + second;const makeUser = name => ({ name, active: true });constructor وضعیت آغازین نمونه را مقداردهی میکند؛ متدهای نمونه در prototype مشترک قرار میگیرند.
class Circle { constructor(radius) { this.radius = radius; } getArea() { return Math.PI * this.radius ** 2; }}کلاس فرزند با extends از کلاس پایه ارث میبرد؛ در constructor فرزند، super پیش از دسترسی به this لازم است.
class ColoredCircle extends Circle { constructor(radius, color) { super(radius); this.color = color; }}متد static روی خود کلاس فراخوانی میشود؛ نامهایی که با # آغاز میشوند فقط در بدنهٔ همان کلاس قابل دسترسیاند.
class Token { static #prefix = "id"; #value; constructor(value) { this.#value = value; } static create(value) { return new Token(`${Token.#prefix}-${value}`); }}Promise.resolve و Promise.reject مقدار را به Promise تبدیل میکنند؛ all با شکست یک مورد رد میشود و allSettled نتیجهٔ همه را نگه میدارد.
const tasks = [loadProfile(), loadCourses()];const results = await Promise.allSettled(tasks);const first = await Promise.race(tasks);const safeValue = await Promise.resolve("آماده");خروجی نامدار چند عضو را از یک ماژول در دسترس میگذارد؛ هر ماژول حداکثر یک خروجی پیشفرض دارد.
// math.jsexport const add = (a, b) => a + b;export default function multiply(a, b) { return a * b;}نام مستعار تعارض نام را حل میکند؛ import ایستا باید در سطح بالای ماژول قرار بگیرد.
import multiply, { add as sum } from "./math.js";console.log(sum(2, 3));console.log(multiply(2, 3));import() یک Promise برمیگرداند و برای بارگذاری شرطی مناسب است؛ import.meta.url نشانی ماژول جاری را فراهم میکند.
const { openDialog } = await import("./dialog.js");openDialog();console.log(import.meta.url);فراخوانی generator function یک iterator میسازد؛ هر next اجرای تابع را تا yield بعدی پیش میبرد.
function* sequence() { yield 1; yield 2; return 3;}const iterator = sequence();iterator.next(); // { value: 1, done: false }متد Symbol.iterator باید iterator برگرداند؛ در مثال ساده میتوان خود generator را بهعنوان iterator استفاده کرد.
const range = { *[Symbol.iterator]() { yield 1; yield 2; yield 3; },};for (const value of range) console.log(value);padStart و padEnd برای تکمیل رشتهاند؛ Number.isInteger و Number.isNaN بررسیهای دقیقتری از تبدیل ضمنی ارائه میدهند.
const code = "7".padStart(3, "0");const label = "ES6".padEnd(6, ".");Number.isInteger(4); // trueNumber.isNaN(Number("x")); // trueMath.hypot طول بردار را محاسبه میکند و Array.from از iterable یا array-like آرایهٔ واقعی میسازد؛ برخی متدها در نسخههای پس از ES2015 آمدهاند.
const distance = Math.hypot(3, 4);const nodes = Array.from( document.querySelectorAll("button"),);const hasTopic = ["css", "js"].includes("js");عملگر ** در ES2016 اضافه شد؛ Array.prototype.includes نیز وجود مقدار را با SameValueZero بررسی میکند.
const square = 5 ** 2;const hasNaN = [NaN].includes(NaN);console.log(square, hasNaN);متغیر قابلتغییر را با let و مقدار ثابت را با const تعریف کنید.
برابری دقیق: === و !==؛ تبدیل نوع ضمنی را آگاهانه مدیریت کنید.
تابع پیکانی: const add = (a, b) => a + b
آرایهها: map برای تبدیل، filter برای انتخاب و find برای یافتن یک مورد.
شیء را با destructuring بخوانید و spread را برای کپی سطحی بهکار ببرید.
رشته قالبی: ` Hello, ${name} `؛ داده کاربر را پیش از نمایش ایمن کنید.
ماژولها: export و import; مرز مسئولیت فایلها را روشن نگه دارید.
ناهمگام: async/await همراه try/catch و مدیریت خطاهای درخواست.
در DOM از addEventListener استفاده و listenerهای غیرضروری را پاکسازی کنید.
برای داده نامطمئن، نوع و مقدار را بررسی کنید؛ JSON.parse میتواند خطا بدهد.
پاسخ fetch را با response.ok بررسی کنید؛ پاسخ HTTP ناموفق الزاماً Promise را reject نمیکند.
برای مقدارهای احتمالی از ?. و ?? استفاده کنید؛ || مقادیر معتبر صفر، رشتهٔ خالی و false را هم جایگزین میکند.