منابع آموزشی و پژوهشی، برای دانشگاه و مدرسه
پشتیبانیانتشار محتوا
مسیر یادگیری

جاوااسکریپت ۲؛ دورهٔ متوسط و پروژه‌های کاربردی

دورهٔ دوم و رایگان جاوااسکریپت، تألیف تحریریه درس‌آوند؛ ادامهٔ دورهٔ «جاوااسکریپت از صفر تا پروژه». ۲۴ درس سطح متوسط با مثال عملی، تمرین و پاسخ و سه پروژهٔ مدیریت هزینه، فروشگاه و API محلی تیکت. پیش‌نیاز: تسلط بر مبانی دورهٔ اول و HTML مقدماتی. زمان هر درس برآورد مطالعه و تمرین است؛ این نسخه ویدیو ندارد.

۲۴ درس۱٬۱۰۰ دقیقه۰ درس کامل‌شده
پرسش دربارهٔ این دوره
رابط کاربر و دفتر هزینه · درس ۱۲

۱۲. ذخیره و بازیابی؛ نسخهٔ داده، پشتیبان و شکست قابل مشاهده

دورهٔ رایگانثبت‌نام و پیشرفت یادگیری در حساب شما نگهداری می‌شود.ورود / ساخت حساب

در برنامهٔ واقعی، موفقیت امروز کافی نیست؛ داده باید فردا هم قابل خواندن باشد. localStorage برای تمرین ذخیرهٔ محلی ساده است، اما پایگاه دادهٔ سرور، فضای نامحدود یا محل امن اطلاعات محرمانه نیست. داده به origin وابسته است و در مرورگر کاربر نگه داشته می‌شود. این درس روی قرارداد فایل، اعتبارسنجی هنگام خواندن و رفتار در شکست تمرکز دارد.

JSON معتبر، الزاماً هزینهٔ معتبر نیست

فایل {"version":1,"items":[]} از نظر JSON درست است؛ ولی اگر amount یک رشته یا تاریخ نامعتبر باشد، برای برنامه قابل قبول نیست. JSON.parse فقط دستور زبان JSON را می‌خواند. پروژهٔ دفتر هزینه تابع restore را برای بررسی نسخه، تعداد ردیف، اعتبار هر هزینه، شناسهٔ تکراری و مجموع امن دارد. این کنترل‌ها هنگام خواندن از مرورگر و فایل پشتیبان یکسان اجرا می‌شوند.

مثال اول؛ بازیابی را پیش از تغییر انجام دهید

این کد را در فایل .mjs ریشهٔ پروژهٔ دانلودی با Node اجرا کنید. مدل به DOM وابسته نیست. نمونهٔ خراب باید پیش از جایگزینی دادهٔ فعلی رد شود؛ روی شکست، نباید items را خالی کنیم و به کاربر موفقیت نشان دهیم.

javascript
import { restore } from './projects/expenses/model.mjs';
const backup = JSON.stringify({ version: 1, items: [{
  id: '11111111-1111-4111-8111-111111111111',
  title: 'کتاب', amount: 180000, category: 'آموزش', date: '2026-10-28'
}] });
let current = [];
const candidate = restore(JSON.parse(backup));
current = candidate;
console.log(current.length); // 1
try {
  restore({ version: 1, items: [current[0], current[0]] });
} catch (error) {
  console.log(error.message); // شناسهٔ تکراری در پشتیبان وجود دارد.
}
console.log(current.length); // هنوز 1

متغیر candidate مرز مهمی دارد: همهٔ بررسی‌ها روی دادهٔ پیشنهادی انجام می‌شود. پس از تأیید و در رابط، پس از اطلاع کاربر از جایگزینی کامل، آن را اعمال می‌کنیم. ادغام پشتیبان با دادهٔ فعلی قرارداد دیگری است؛ بدون طراحی تشخیص تکرار، آن را «بازیابی» ننامید. پروژهٔ همراه جایگزینی کامل را اجرا می‌کند و قبل از آن تأیید می‌گیرد.

مثال دوم؛ ذخیره‌سازی را قابل تزریق کنید

در shared/ui.mjs توابع loadJSON و saveJSON وجود دارند. پارامتر اختیاری storage باعث می‌شود خطای ذخیره را بدون پر کردن حافظهٔ واقعی مرورگر بازتولید کنیم. نمونهٔ زیر هم در Node قابل اجراست؛ چون storage را صریح پاس می‌دهیم و به window نیاز ندارد.

javascript
import { loadJSON, saveJSON } from './projects/shared/ui.mjs';
const memory = new Map();
const storage = {
  getItem: key => memory.has(key) ? memory.get(key) : null,
  setItem: (key, value) => memory.set(key, value)
};
console.log(saveJSON('demo', { version: 1, items: [] }, storage)); // true
const result = loadJSON('demo', restore, [], storage);
console.log(result.value.length, result.error); // 0 و رشتهٔ خالی
const blocked = {
  getItem() { throw Error('read blocked'); },
  setItem() { throw Error('quota exceeded'); }
};
console.log(saveJSON('demo', {}, blocked)); // false
console.log(loadJSON('demo', restore, [], blocked).error.length > 0); // true

خطای دسترسی به خود window.localStorage هم ممکن است رخ دهد؛ دسترسی و خواندن باید داخل مسیر try باشند. تابع آماده همین نکته را رعایت می‌کند. شکست را پنهان نکنید: نمایش فهرست خالی پس از خطای خواندن ممکن است کاربر را به ذخیرهٔ نسخهٔ خالی و از دست دادن شانس بازیابی سوق بدهد. پیام باید فرق «هنوز داده‌ای نداریم» و «داده خوانده نشد» را مشخص کند.

نسخه‌بندی و مهاجرت سنجیده

اگر فردا currency اضافه شود، صرف افزودن version:2 مشکل را حل نمی‌کند. باید مشخص باشد نسخهٔ یک چگونه به دو تبدیل می‌شود، فیلد تازه چه مقدار پیش‌فرض معناداری دارد و خروجی مهاجرت دوباره چگونه اعتبارسنجی می‌شود. پروژهٔ فعلی فقط نسخهٔ یک را پشتیبانی می‌کند؛ مهاجرت، تمرین توسعهٔ شماست. نسخهٔ ناشناخته را حدس نزنید و رشته‌ها را بی‌صدا به عدد تبدیل نکنید.

ذخیرهٔ localStorage هم‌زمان و مبتنی بر رشته است. برای دادهٔ بزرگ، نوشتن مکرر می‌تواند رابط را متوقف کند و محدودیت فضا دارد. در فایل همراه سقف اندازهٔ فایل ورودی قبل از text بررسی می‌شود و سپس مدل سقف ردیف‌ها را بررسی می‌کند. این کار همهٔ خطرهای فایل دلخواه را حل نمی‌کند، ولی برای یک آزمایشگاه محلی مرزهای روشن می‌سازد. خروجی JSON رمزگذاری نیست و در پوشهٔ دانلود ممکن است قابل دسترسی دیگران باشد.

تمرین مستقل و پاسخ تشریحی

یک مهاجرت مستقل بسازید که فقط دادهٔ نسخهٔ یک را به نسخهٔ دو با currency:"TOMAN" تبدیل کند. تابع را روی ورودی نسخهٔ ناشناخته، ردیف خراب و ورودی درست امتحان کنید. پاسخ مناسب ابتدا restore نسخهٔ یک را صدا می‌زند، سپس رکورد تازه می‌سازد؛ نسخهٔ ناشناخته خطاست. نسخهٔ دو را مستقیماً به restore فعلی ندهید و ادعا نکنید مدل آماده آن را می‌پذیرد؛ validator نسخهٔ دو را جدا تعریف کنید.

معیار تحویل: فایل خراب دادهٔ فعلی را تغییر ندهد، ذخیرهٔ ناموفق پیام واضح داشته باشد، نسخهٔ ناشناخته رد شود و export سپس import همان تعداد ردیف و مجموع را بازگرداند. دادهٔ آزمایشی بسازید؛ تمرین را روی تنها نسخهٔ اطلاعات شخصی انجام ندهید.

منابع انگلیسی برای مطالعهٔ تکمیلی

https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse

تألیف و مثال‌های مستقل: تحریریه درس‌آوند.

یکجا انتخاب کن، راحت‌تر دریافت کن

انتخاب‌های من ۰ منبع

مجموعهٔ مطالعه‌ات را بساز.

کنار مقاله‌ها «انتخاب» را بزنید تا چند فایل را با هم دریافت کنید.

انتخاب مقاله‌های رایگان