| کانال توسعهدهندگان جاوااسکریپت |
Kanalga Telegram’da o‘tish
⭕️ کانال توسعهدهندگان جاوااسکریپت دولوپیکس 💠 دولوپیکس | جامعه توسعهدهندگان ایرانی 💎 @Developix 🚀 Developix.ir 📌 پشتیبانی و تبلیغات: @DevelopixSupport
Ko'proq ko'rsatish3 835
Obunachilar
+224 soatlar
-137 kun
-2930 kun
Postlar arxiv
\n\nو فایل جاوااسکریپت:\n\n// app.js\nconst form = document.querySelector(\"#todo-form\");\nconst input = document.querySelector(\"#todo-input\");\nconst list = document.querySelector(\"#todo-list\");\n\nconst STORAGE_KEY = \"jsdev_todos\";\nlet todos = loadTodos();\nrender();\n\nform.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n const text = input.value.trim();\n if (!text) return;\n\n todos.push({ id: Date.now(), text });\n input.value = \"\";\n saveTodos();\n render();\n});\n\nlist.addEventListener(\"click\", (e) => {\n if (!e.target.matches(\"button[data-id]\")) return;\n const id = Number(e.target.dataset.id);\n todos = todos.filter((t) => t.id !== id);\n saveTodos();\n render();\n});\n\nfunction loadTodos() {\n const raw = localStorage.getItem(STORAGE_KEY);\n try {\n return raw ? JSON.parse(raw) : [];\n } catch {\n return [];\n }\n}\n\nfunction saveTodos() {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(todos));\n}\n\nfunction render() {\n list.innerHTML = \"\";\n todos.forEach((todo) => {\n const li = document.createElement(\"li\");\n li.textContent = todo.text + \" \";\n\n const btn = document.createElement(\"button\");\n btn.textContent = \"حذف\";\n btn.dataset.id = todo.id;\n\n li.appendChild(btn);\n list.appendChild(li);\n });\n}\n\nچند نکته ریز ولی مهم 🧠\n• همیشه روی داده localStorage یک try...catch بگذار که اگر خراب شد (مثلاً دستی ویرایش شده بود) اپ کرش نکند.\n• از یک key ثابت مثل jsdev_todos استفاده کن تا اگر بعداً چند بخش دیگر هم اضافه شد، تداخل نداشته باشند.\n• برای id ها اینجا از Date.now() استفاده شده، که برای پروژههای کوچک کافی است.\n\nبا همین ساختار پایه میشود بعدها checkbox برای completed، فیلتر، و حتی sync ساده با backend هم اضافه کرد. یک بار این نمونه را تا انتها بساز، بعد هر جای اپهای واقعی که state و UI sync میشوند خیلی قابل فهمتر به نظر میرسد ⚡️\n\nاگر ساختی و کمی شخصیسازیاش کردی، نسخهات را برای بقیه بچههای جاوااسکریپت هم بفرست؛ همین مثالهای کوچک کمکم تبدیل به component و pattern های جدیتر میشوند.\n\n🔖 #Javascript #JS #جاوااسکریپت #JavaScript #LocalStorage #DOM #VanillaJS #Frontend\n\n👤 Developix\n\n💎 Channel: @DevelopixJavascript","datePublished":"2026-07-14T17:00:27Z","dateModified":"2026-07-14T17:00:27Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":0,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1512},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":8},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":22}]}},{"@type":"ListItem","position":2,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/80","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/80","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/80","headline":"💠 نسخه جدید رانتایم نود جیاس (NodeJS) منتشر شده است 🔸 ارتقا از نسخه 26.4.0 به 26.5.0 🔹 لیست تغییرات این نسخ…","articleBody":"💠 نسخه جدید رانتایم نود جیاس (NodeJS) منتشر شده است\n\n🔸 ارتقا از نسخه 26.4.0 به 26.5.0\n\n🔹 لیست تغییرات این نسخه:\n- افزودن متد جدید blob.textStream() در ماژول buffer\n- افزودن فلگ جدید --experimental-import-text برای ESM\n- افزودن نمونهبرداری تأخیر هر چرخه رویداد در perf_hooks\n- افزودن و اکسپوز کردن ReadableStreamTee در ماژول stream\n- گزارش گروههای مذاکرهشده TLS در ماژول tls\n- سایر بهبودها و بهروزرسانیهای داخلی و مستندات، و غیره\n\n🔖 #nodejs, #web, #js, #release\n\n💎 @DevelopixJavascript","datePublished":"2026-07-08T19:45:11Z","dateModified":"2026-07-08T19:45:11Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":0,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1452},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":7},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":4}]}},{"@type":"ListItem","position":3,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/79","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/79","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/79","headline":"خروجی این کد JavaScript چیست؟ در این مثال از prototype chain و shadowing روی یک property استفاده شده است. با…","articleBody":"خروجی این کد JavaScript چیست؟\n\nدر این مثال از prototype chain و shadowing روی یک property استفاده شده است. با دقت به ترتیب اجرا و اینکه هر بار چه مقداری log میشود توجه کنید و خروجی نهایی را به ترتیب سطرها بنویسید.\n\nconst base = {\n value: 1,\n inc() {\n this.value++;\n console.log(\"base:\", this.value);\n }\n};\n\nconst obj = Object.create(base);\nobj.value = 10;\n\nobj.inc();\nbase.inc();\n\ndelete obj.value;\nobj.inc();\n\nbase.value = 100;\nobj.inc();\n\n\nخروجی دقیق این کد در console چه خواهد بود؟ (همه سطرهای خروجی را به ترتیب بنویسید)\n\n🔖 #Javascript #JS #جاوااسکریپت\n\n👤 Developix\n\n💎 Channel: @DevelopixJavascript","datePublished":"2026-06-29T17:00:52Z","dateModified":"2026-06-29T17:00:52Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":11,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1719},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":3},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":4},{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":11}]}},{"@type":"ListItem","position":4,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/78","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/78","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/78","headline":"💠 نسخه جدید رانتایم دینو (Deno) منتشر شده است 🔸 ارتقا از نسخه 2.8.3 به 2.9.0 🔹 لیست تغییرات این نسخه: - افزو…","articleBody":"💠 نسخه جدید رانتایم دینو (Deno) منتشر شده است\n\n🔸 ارتقا از نسخه 2.8.3 به 2.9.0\n\n🔹 لیست تغییرات این نسخه:\n- افزوده شدن زیرکامند جدید deno desktop برای ساخت اپ دسکتاپ\n- اضافه شدن زیرکامندهای جدید deno watch / deno link / deno list در CLI\n- پشتیبانی نصب و قفلسازی از bun، pnpm، yarn، npm و بهبود node_modules\n- افزوده شدن قابلیتهای پیشرفته تست مثل Deno.test.each، snapshot، shard و retry\n- پشتیبانی کاملتر از Node-API v10 و node:test mocks برای سازگاری بیشتر با Node.js\n- بهبودهای فرمتدهی، پوشش کد و شبکه، بهروزرسانی WebCrypto و غیره\n\n🔖 #deno, #js, #release\n\n💎 @DevelopixJavascript","datePublished":"2026-06-26T09:30:16Z","dateModified":"2026-06-26T09:30:16Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":0,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1651},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":3},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":4}]}},{"@type":"ListItem","position":5,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/77","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/77","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/77","headline":"💠 نسخه جدید رانتایم نود جیاس (NodeJS) منتشر شده است 🔸 ارتقا از نسخه 26.3.1 به 26.4.0 🔹 لیست تغییرات این نسخ…","articleBody":"💠 نسخه جدید رانتایم نود جیاس (NodeJS) منتشر شده است\n\n🔸 ارتقا از نسخه 26.3.1 به 26.4.0\n\n🔹 لیست تغییرات این نسخه:\n- بهروزرسانی وضعیت پایداری blockList به «کاندید انتشار»\n- پشتیبانی از بافر سفارشی در fs.readFile()\n- افزودن بستهمپها در لودر ماژولها (package maps)\n- افزودن گزینه فشردهسازی گواهی در TLS\n- افزودن گزینههای جدید TCP keepalive در net.setKeepAlive()\n- افزودن زیرسیستم جدید node:vfs و تغییرات مرتبط، و غیره\n\n🔖 #nodejs, #web, #js, #release\n\n💎 @DevelopixJavascript","datePublished":"2026-06-25T17:30:25Z","dateModified":"2026-06-25T17:30:25Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":0,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1406},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":4},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":3}]}},{"@type":"ListItem","position":6,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/76","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/76","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/76","headline":"🏆آفرهای جام جهانی ۲۰۲۶ هاستایران فعال شد! با کمپین «ترکیب برنده سایتت»، زیرساخت سایتت رو برای روزهای پرترافی…","articleBody":"🏆آفرهای جام جهانی ۲۰۲۶ هاستایران فعال شد!\n\nبا کمپین «ترکیب برنده سایتت»، زیرساخت سایتت رو برای روزهای پرترافیک آماده کن:\n\n🔥 ۲۵٪ تخفیف روی پلنهای ۳ ماهه هاست اشتراکی ایران \n⚡ ۵۰٪ تخفیف روی پلنهای یکماهه سرویس ابری در دیتاسنترهای تهران، مشهد و اهواز \n\n🧠 مشاوره رایگان زیرساخت توسط کارشناسان هاستایران\nفرصت استفاده از تخفیفها و ثبت فرم مشاوره محدود است.\n\n📌 برای کپی کدهای تخفیف و ثبتنام در فرم مشاوره، روی لینک زیر کلیک کنید:\n\n📌صفحه فرم مشاوره\n📌تلگرام هاستایران\n📌بله هاستایران \n\n\n#هاست_ایران #سرور_ابری_هاست_ایران #هاست_اشتراکی #دیتاسنتر #مشاوره_زیرساخت #جام_جهانی2026","datePublished":"2026-06-16T15:30:08Z","dateModified":"2026-06-16T15:30:08Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":0,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1383},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":1}],"sharedContent":{"@type":"SocialMediaPosting","headline":"Developix Support","datePublished":"2026-06-15T11:32:24Z"}}},{"@type":"ListItem","position":7,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/75","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/75","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/75","headline":"⏱ جلوگیری از اجرای اضافی event با debounce ساده تو پروژههای فرانت، eventهایی مثل scroll و input میتونن تو ه…","articleBody":"⏱ جلوگیری از اجرای اضافی event با debounce ساده\n\nتو پروژههای فرانت، eventهایی مثل scroll و input میتونن تو هر ثانیه دهها بار فایر بشن و باعث لگ، مصرف CPU و رندر اضافه بشن. یک تکنیک ساده برای کنترل این ماجرا، استفاده از debounce هست. 😉\n\nایده: تا وقتی کاربر داره پشتسرهم تایپ یا اسکرول میکنه، تابع اصلی اجرا نشه؛ فقط وقتی یک مدت کوتاه هیچ eventی نیومد، تابع رو صدا بزن.\n\nfunction debounce(fn, delay) {\n let timeoutId;\n return function (...args) {\n if (timeoutId) clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n fn.apply(this, args);\n }, delay);\n };\n}\n\nconst handleSearch = debounce((event) => {\n console.log(\"Search:\", event.target.value);\n}, 400);\n\nconst input = document.querySelector(\"#search\");\ninput.addEventListener(\"input\", handleSearch);\n\n\n💡 این کار تعداد requestهای سرچ، رندر مجدد و لاگها رو بهشدت کم میکنه و UX نرمتری میسازه.\n\nمرجع بیشتر در مورد timing ها و eventها:\nMDN - setTimeout\n\nامتحانش روی inputهای سرچ یا resize و scroll نتیجه خیلی ملموسی میدهد. 🚀\n\n🔖 #Javascript #JS #جاوااسکریپت #JavaScript #debounce #performance #events #frontend\n\n👤 Developix\n\n💎 Channel: @DevelopixJavascript","datePublished":"2026-06-14T17:00:26Z","dateModified":"2026-06-14T17:00:26Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":0,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1372},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":6},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":5}]}},{"@type":"ListItem","position":8,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/73","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/73","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/73","headline":"در نمونهکد بالا برای فیلتر کردن یک آرایه بزرگ، در هر بار تکرار حلقه دوباره sort و filter روی کل دادهها اجرا…","articleBody":"در نمونهکد بالا برای فیلتر کردن یک آرایه بزرگ، در هر بار تکرار حلقه دوباره sort و filter روی کل دادهها اجرا شده که هم باعث پیچیدگی زمانی بسیار بالا (حدود O(n² log n)) و هم مصرف اضافی مموری میشود. در نسخهٔ بهبودیافته، ابتدا دادهها یکبار نرمالسازی و مرتب میشوند و سپس فقط یکبار روی آنها فیلتر و جستوجو انجام میگیرد.\n\nبه نظر شما چرا استفاده از متغیرهای میانی و جلوگیری از ایجاد آرایههای موقت متعدد میتواند در این سناریو باعث کاهش مصرف مموری و افزایش سرعت برنامه، مخصوصاً روی لیستهای بزرگ (مثلاً > ۱۰۰هزار آیتم)، شود؟\n\n🔖 #Javascript #JS #جاوااسکریپت\n\n👤 Developix\n\n💎 Channel: @DevelopixJavascript","datePublished":"2026-05-30T17:00:26Z","dateModified":"2026-05-30T17:00:26Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":1,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1804},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":3},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":7},{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":1}]}},{"@type":"ListItem","position":9,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/72","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/72","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/72","headline":"کتابخونه 🐻 Zustand یه state manager مینیمال برای React هست که بدون ceremony اضافی، state سراسری رو برات حل می…","articleBody":"کتابخونه 🐻 Zustand یه state manager مینیمال برای React هست که بدون ceremony اضافی، state سراسری رو برات حل میکنه.\n\nمزیتش نسبت به Redux و بقیه چیه؟\n• API خیلی ساده و مستقیم\n• بدون providerهای تو در تو؛ فقط یک store\n• performance عالی با رندر کمتر کامپوننتها\n• پشتیبانی از TypeScript بدون دردسر\n\nیه مثال ساده:\nnpm install zustand\n\n\nimport { create } from 'zustand'\n\nconst useBearStore = create((set) => ({\n bears: 0,\n increase: () => set((state) => ({ bears: state.bears + 1 })),\n}))\n\nfunction Counter() {\n const bears = useBearStore((state) => state.bears)\n const increase = useBearStore((state) => state.increase)\n\n return \n}\n\n\nبرای پروژههایی که Redux براشون زیادی سنگینه، Zustand گزینهایه که هم کد رو تمیز نگه میداره هم مقیاسپذیره. مخصوصاً برای dashboardها، panelهای ادمین و appهای data-heavy خیلی جواب میده.\n\nمستندات و سورس:\nGitHub\nDocs\n\nیک بار تو یه پروژه واقعی تستش کن، معمولاً بعدش برگردوندنش به عقب سخته 😄\n\n🔖 #Javascript #JS #جاوااسکریپت #JavaScript #React #Zustand #State_Management #Frontend\n\n👤 Developix\n\n💎 Channel: @DevelopixJavascript","datePublished":"2026-05-15T17:00:11Z","dateModified":"2026-05-15T17:00:11Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":8,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1777},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":4},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":6},{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":8}]}},{"@type":"ListItem","position":10,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/71","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/71","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/71","headline":"در کد زیر سازندهی کلاس تلاش میکند با استفاده از async/await و forEach دادهها را بهصورت غیرهمزمان لود کند…","articleBody":"در کد زیر سازندهی کلاس تلاش میکند با استفاده از async/await و forEach دادهها را بهصورت غیرهمزمان لود کند، اما رفتار نهایی با انتظار نویسندهی کد فرق دارد و this.data در زمان استفاده هنوز کامل مقداردهی نشده است.\n\nسؤال: در این کد چه چیزی باید تغییر کند تا اجرای غیرهمزمان بهدرستی منتظر اتمام تمام درخواستها بماند و سپس this.data کامل آماده باشد؟\n\nclass DataLoader {\n constructor(apiUrls) {\n this.data = [];\n this.load(apiUrls);\n }\n\n async load(urls) {\n urls.forEach(async (url) => {\n const res = await fetch(url);\n const json = await res.json();\n this.data.push(json);\n });\n }\n}\n\nconst loader = new DataLoader([\n \"https://example.com/api/users\",\n \"https://example.com/api/posts\"\n]);\n\n// بعداً در جایی دیگر:\nconsole.log(\"Loaded:\", loader.data.length); // مقدار اینجا غیرقابل اعتماد است\n\n🔖 #Javascript #JS #جاوااسکریپت\n\n👤 Developix\n\n💎 Channel: @DevelopixJavascript","datePublished":"2026-04-30T17:00:15Z","dateModified":"2026-04-30T17:00:15Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":4,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1563},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":4},{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":4}]}},{"@type":"ListItem","position":11,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/70","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/70","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/70","headline":"خروجی این کد JavaScript چیست؟ به ترتیب و با دقت به event loop و صف microtask و macrotask فکر کنید و رشتهای ر…","articleBody":"خروجی این کد JavaScript چیست؟\n\nبه ترتیب و با دقت به event loop و صف microtask و macrotask فکر کنید و رشتهای را که در کنسول چاپ میشود، دقیقا به همان ترتیب بنویسید.\n\nconst p = Promise.resolve(1);\n\np.then(v => {\n console.log(\"A\", v);\n return v + 1;\n}).then(v => {\n console.log(\"B\", v);\n return Promise.resolve(v + 1);\n}).then(v => {\n console.log(\"C\", v);\n});\n\nsetTimeout(() => {\n console.log(\"D\");\n Promise.resolve().then(() => {\n console.log(\"E\");\n });\n}, 0);\n\nconsole.log(\"F\");\n\nخروجی نهایی کنسول را دقیقا و به ترتیب، در یک خط یا چند خط، بنویسید.\n\n🔖 #Javascript #JS #جاوااسکریپت\n\n👤 Developix\n\n💎 Channel: @DevelopixJavascript","datePublished":"2026-04-15T17:00:13Z","dateModified":"2026-04-15T17:00:13Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":4,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1497},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":5},{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":4}]}},{"@type":"ListItem","position":12,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/68","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/68","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/68","headline":"در این نمونهکد، برای هر درخواست ورودی چندین بار JSON.parse روی req.body انجام میشود که میتواند در درخواست…","articleBody":"در این نمونهکد، برای هر درخواست ورودی چندین بار JSON.parse روی req.body انجام میشود که میتواند در درخواستهای سنگین باعث کاهش کارایی، افزایش مصرف CPU و حتی بروز خطا در صورت خراب شدن ساختار بدنه شود. در مقابل، در نسخه اصلاحشده با استفاده از یک middleware اختصاصی، فقط یک بار پارس انجام شده و نتیجه در یک فیلد امن روی req ذخیره میشود.\n\nبهنظر شما در پروژههای واقعی، استفاده از این الگو چه مزیتهایی از نظر performance، قابلیت تست و کاهش ریسک Side Effect نسبت به پارس مستقیم JSON در هر هندلر دارد؟\n\n🔖 #Javascript #JS #جاوااسکریپت\n\n👤 Developix\n\n💎 Channel: @DevelopixJavascript","datePublished":"2026-03-31T17:00:36Z","dateModified":"2026-03-31T17:00:36Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":0,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1583},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":2},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":2}]}},{"@type":"ListItem","position":13,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/67","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/67","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/67","headline":"🎯 هندلکردن کلیکها با Event Delegation وقتی تعداد زیادی دکمه یا آیتم در DOM داریم، اضافهکردن یک event liste…","articleBody":"🎯 هندلکردن کلیکها با Event Delegation\n\nوقتی تعداد زیادی دکمه یا آیتم در DOM داریم، اضافهکردن یک event listener روی هر عنصر هم کند است، هم کد را شلوغ میکند. با Event Delegation فقط روی والد گوش میدهیم و رویداد را از مسیر event.target مدیریت میکنیم. 🔥\n\n✅ این کار:\n• تعداد listenerها را کم میکند ✂️\n• مدیریت عناصر اضافه/حذفشونده را ساده میکند\n\nمثال ساده روی یک لیست:\n\nconst list = document.querySelector('#user-list');\n\nlist.addEventListener('click', (event) => {\n const item = event.target.closest('li');\n if (!item || !list.contains(item)) return;\n\n const userId = item.dataset.userId;\n console.log('Clicked user:', userId);\n});\n\n\nحالا هر که بعداً با JavaScript به #user-list اضافه شود، بدون نیاز به listener جدید، کلیک را هندل میکند. 🚀\n\nبرای جزئیات بیشتر: MDN - Event delegation\n\nتوی پروژههای سنگین DOM، این الگو هم خوانایی کد را بهتر میکند هم عملکرد را. 😉\n\n🔖 #Javascript #JS #جاوااسکریپت #JavaScript #Event_Delegation #DOM #Performance #ES6\n\n👤 Developix\n\n💎 Channel: @DevelopixJavascript","datePublished":"2026-03-16T17:00:09Z","dateModified":"2026-03-16T17:00:09Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":0,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1367},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":6},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":4}]}},{"@type":"ListItem","position":14,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/66","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/66","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/66","headline":"ویراک کلود | تجربهی ابری بدون محدودیت ☁️🚀 🎁 ۲۰٪ شارژ هدیه روی اولین واریزی مزیتهایی که واقعاً فرق میسازن:…","articleBody":"ویراک کلود | تجربهی ابری بدون محدودیت ☁️🚀\n\n🎁 ۲۰٪ شارژ هدیه روی اولین واریزی\n\nمزیتهایی که واقعاً فرق میسازن:\n⚡️ پهنای باند 980 مگ\n🌐با IP مازاد\n⏱️ راهاندازی فوری\n💳 پرداخت ساعتی\n🛡 پشتیبانی ۲۴/۷\n\n💬 هر سوالی داشتی، تیم ما کنارتـه\n✅ مناسب استارتاپها، تیمهای فنی، تا سازمانهای بزرگ\n\n همین الان شروع کن و با حداکثر منابع، سریعتر رشد کن 👇🏻\n\n📞 تماس سریع: 02191555530\n🔗 https://virakcloud.com","datePublished":"2026-02-24T17:00:02Z","dateModified":"2026-02-24T17:00:02Z","author":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"publisher":{"@type":"Organization","name":"| کانال توسعهدهندگان جاوااسکریپت |","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript","image":"https://img.telemetr.io/c/27u6CW/5823301833593045169?ty=x"},"commentCount":0,"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":1053}],"sharedContent":{"@type":"SocialMediaPosting","datePublished":"2026-02-22T12:01:03Z"}}},{"@type":"ListItem","position":15,"item":{"@type":"SocialMediaPosting","@id":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/65","url":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/65","mainEntityOfPage":"https://telemetr.io/uz/channels/1942875334-developixjavascript/posts/65","headline":"✨ ساخت یک Todo List ساده با JavaScript خالص (بدون Framework) خیلی وقتها برای تمرین JavaScript و DOM، یک پروژ…","articleBody":"✨ ساخت یک Todo List ساده با JavaScript خالص (بدون Framework)\n\nخیلی وقتها برای تمرین JavaScript و DOM، یک پروژه کوچیک و واقعی مثل Todo List بهترین گزینهست. هم رویدادها رو لمس میکنی، هم کار با DOM و هم مدیریت state ساده رو.\n\nیکی از بهترین رفرنسها برای کار با DOM و رویدادها، مستندات MDN هست:\nMDN DOM Introduction\n\nدر این تمرین، با چند مفهوم مهم سر و کار داریم:\n\n✅ گرفتن elementها با querySelector\n✅ گوش دادن به eventها مثل submit و click\n✅ جلوگیری از refresh فرم با event.preventDefault()\n✅ دستکاری DOM با createElement و appendChild\n\nمثال زیر یک Todo List خیلی ساده ولی عملی است. کافیست یک فایل index.html بسازی و این کد را داخلش قرار بدهی و در مرورگر باز کنی:\n\n\n\n\n \n Simple Todo \n \n\n\n 












Todo List
\n \nساخت TODO List یکی از بهترین تمرینهای واقعی برای جا افتادن مفاهیم DOM، event ها و ذخیره دادهها در مرورگر است. این بار بدون React و فریمورک، فقط با Vanilla JS و LocalStorage 💪
منبع اصلی ایده و توضیحات: آموزش MDN درباره Web Storage API و مستندات DOM Manipulation.
ایده کلی 👇
یک فرم ساده داریم برای اضافهکردن task ها، لیست را با JS توی DOM رندر میکنیم و هر تغییری که کاربر میدهد را در localStorage ذخیره میکنیم تا بعد از refresh هم از بین نرود.
نکته خوبش این است که با همین مثال ساده، چند تا چیز مهم جا میافتد:
• کار با querySelector و ساخت element های جدید
• مدیریت event ها مثل
submit و click
• تبدیل array به string و برعکس با JSON.stringify و JSON.parse
• sync نگهداشتن UI با state ذخیرهشده در localStorage
یک اسکلت ساده از کد 👇
<!-- index.html -->
<form id="todo-form">
<input id="todo-input" placeholder="کار جدید..." />
<button type="submit">اضافه کن</button>
</form>
<ul id="todo-list"></ul>
<script src="app.js"></script>
و فایل جاوااسکریپت:
// app.js
const form = document.querySelector("#todo-form");
const input = document.querySelector("#todo-input");
const list = document.querySelector("#todo-list");
const STORAGE_KEY = "jsdev_todos";
let todos = loadTodos();
render();
form.addEventListener("submit", (e) => {
e.preventDefault();
const text = input.value.trim();
if (!text) return;
todos.push({ id: Date.now(), text });
input.value = "";
saveTodos();
render();
});
list.addEventListener("click", (e) => {
if (!e.target.matches("button[data-id]")) return;
const id = Number(e.target.dataset.id);
todos = todos.filter((t) => t.id !== id);
saveTodos();
render();
});
function loadTodos() {
const raw = localStorage.getItem(STORAGE_KEY);
try {
return raw ? JSON.parse(raw) : [];
} catch {
return [];
}
}
function saveTodos() {
localStorage.setItem(STORAGE_KEY, JSON.stringify(todos));
}
function render() {
list.innerHTML = "";
todos.forEach((todo) => {
const li = document.createElement("li");
li.textContent = todo.text + " ";
const btn = document.createElement("button");
btn.textContent = "حذف";
btn.dataset.id = todo.id;
li.appendChild(btn);
list.appendChild(li);
});
}
چند نکته ریز ولی مهم 🧠
• همیشه روی داده localStorage یک try...catch بگذار که اگر خراب شد (مثلاً دستی ویرایش شده بود) اپ کرش نکند.
• از یک key ثابت مثل jsdev_todos استفاده کن تا اگر بعداً چند بخش دیگر هم اضافه شد، تداخل نداشته باشند.
• برای id ها اینجا از Date.now() استفاده شده، که برای پروژههای کوچک کافی است.
با همین ساختار پایه میشود بعدها checkbox برای completed، فیلتر، و حتی sync ساده با backend هم اضافه کرد. یک بار این نمونه را تا انتها بساز، بعد هر جای اپهای واقعی که state و UI sync میشوند خیلی قابل فهمتر به نظر میرسد ⚡️
اگر ساختی و کمی شخصیسازیاش کردی، نسخهات را برای بقیه بچههای جاوااسکریپت هم بفرست؛ همین مثالهای کوچک کمکم تبدیل به component و pattern های جدیتر میشوند.
🔖 #Javascript #JS #جاوااسکریپت #JavaScript #LocalStorage #DOM #VanillaJS #Frontend
👤 Developix
💎 Channel: @DevelopixJavascript💠 نسخه جدید رانتایم نود جیاس (NodeJS) منتشر شده است
🔸 ارتقا از نسخه 26.4.0 به 26.5.0
🔹 لیست تغییرات این نسخه:
- افزودن متد جدید blob.textStream() در ماژول buffer
- افزودن فلگ جدید --experimental-import-text برای ESM
- افزودن نمونهبرداری تأخیر هر چرخه رویداد در perf_hooks
- افزودن و اکسپوز کردن ReadableStreamTee در ماژول stream
- گزارش گروههای مذاکرهشده TLS در ماژول tls
- سایر بهبودها و بهروزرسانیهای داخلی و مستندات، و غیره
🔖 #nodejs, #web, #js, #release
💎 @DevelopixJavascript
خروجی این کد JavaScript چیست؟
در این مثال از prototype chain و shadowing روی یک property استفاده شده است. با دقت به ترتیب اجرا و اینکه هر بار چه مقداری log میشود توجه کنید و خروجی نهایی را به ترتیب سطرها بنویسید.
const base = {
value: 1,
inc() {
this.value++;
console.log("base:", this.value);
}
};
const obj = Object.create(base);
obj.value = 10;
obj.inc();
base.inc();
delete obj.value;
obj.inc();
base.value = 100;
obj.inc();
خروجی دقیق این کد در console چه خواهد بود؟ (همه سطرهای خروجی را به ترتیب بنویسید)
🔖 #Javascript #JS #جاوااسکریپت
👤 Developix
💎 Channel: @DevelopixJavascript💠 نسخه جدید رانتایم دینو (Deno) منتشر شده است
🔸 ارتقا از نسخه 2.8.3 به 2.9.0
🔹 لیست تغییرات این نسخه:
- افزوده شدن زیرکامند جدید deno desktop برای ساخت اپ دسکتاپ
- اضافه شدن زیرکامندهای جدید deno watch / deno link / deno list در CLI
- پشتیبانی نصب و قفلسازی از bun، pnpm، yarn، npm و بهبود node_modules
- افزوده شدن قابلیتهای پیشرفته تست مثل Deno.test.each، snapshot، shard و retry
- پشتیبانی کاملتر از Node-API v10 و node:test mocks برای سازگاری بیشتر با Node.js
- بهبودهای فرمتدهی، پوشش کد و شبکه، بهروزرسانی WebCrypto و غیره
🔖 #deno, #js, #release
💎 @DevelopixJavascript
💠 نسخه جدید رانتایم نود جیاس (NodeJS) منتشر شده است
🔸 ارتقا از نسخه 26.3.1 به 26.4.0
🔹 لیست تغییرات این نسخه:
- بهروزرسانی وضعیت پایداری blockList به «کاندید انتشار»
- پشتیبانی از بافر سفارشی در
fs.readFile()
- افزودن بستهمپها در لودر ماژولها (package maps)
- افزودن گزینه فشردهسازی گواهی در TLS
- افزودن گزینههای جدید TCP keepalive در net.setKeepAlive()
- افزودن زیرسیستم جدید node:vfs و تغییرات مرتبط، و غیره
🔖 #nodejs, #web, #js, #release
💎 @DevelopixJavascript🏆آفرهای جام جهانی ۲۰۲۶ هاستایران فعال شد!
با کمپین «ترکیب برنده سایتت»، زیرساخت سایتت رو برای روزهای پرترافیک آماده کن:
🔥 ۲۵٪ تخفیف روی پلنهای ۳ ماهه هاست اشتراکی ایران
⚡ ۵۰٪ تخفیف روی پلنهای یکماهه سرویس ابری در دیتاسنترهای تهران، مشهد و اهواز
🧠 مشاوره رایگان زیرساخت توسط کارشناسان هاستایران
فرصت استفاده از تخفیفها و ثبت فرم مشاوره محدود است.
📌 برای کپی کدهای تخفیف و ثبتنام در فرم مشاوره، روی لینک زیر کلیک کنید:
📌صفحه فرم مشاوره
📌تلگرام هاستایران
📌بله هاستایران
#هاست_ایران #سرور_ابری_هاست_ایران #هاست_اشتراکی #دیتاسنتر #مشاوره_زیرساخت #جام_جهانی2026
⏱ جلوگیری از اجرای اضافی event با debounce ساده
تو پروژههای فرانت، eventهایی مثل scroll و input میتونن تو هر ثانیه دهها بار فایر بشن و باعث لگ، مصرف CPU و رندر اضافه بشن. یک تکنیک ساده برای کنترل این ماجرا، استفاده از debounce هست. 😉
ایده: تا وقتی کاربر داره پشتسرهم تایپ یا اسکرول میکنه، تابع اصلی اجرا نشه؛ فقط وقتی یک مدت کوتاه هیچ eventی نیومد، تابع رو صدا بزن.
function debounce(fn, delay) {
let timeoutId;
return function (...args) {
if (timeoutId) clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
const handleSearch = debounce((event) => {
console.log("Search:", event.target.value);
}, 400);
const input = document.querySelector("#search");
input.addEventListener("input", handleSearch);
💡 این کار تعداد requestهای سرچ، رندر مجدد و لاگها رو بهشدت کم میکنه و UX نرمتری میسازه.
مرجع بیشتر در مورد timing ها و eventها:
MDN - setTimeout
امتحانش روی inputهای سرچ یا resize و scroll نتیجه خیلی ملموسی میدهد. 🚀
🔖 #Javascript #JS #جاوااسکریپت #JavaScript #debounce #performance #events #frontend
👤 Developix
💎 Channel: @DevelopixJavascript+1
در نمونهکد بالا برای فیلتر کردن یک آرایه بزرگ، در هر بار تکرار حلقه دوباره sort و filter روی کل دادهها اجرا شده که هم باعث پیچیدگی زمانی بسیار بالا (حدود O(n² log n)) و هم مصرف اضافی مموری میشود. در نسخهٔ بهبودیافته، ابتدا دادهها یکبار نرمالسازی و مرتب میشوند و سپس فقط یکبار روی آنها فیلتر و جستوجو انجام میگیرد.
به نظر شما چرا استفاده از متغیرهای میانی و جلوگیری از ایجاد آرایههای موقت متعدد میتواند در این سناریو باعث کاهش مصرف مموری و افزایش سرعت برنامه، مخصوصاً روی لیستهای بزرگ (مثلاً > ۱۰۰هزار آیتم)، شود؟
🔖 #Javascript #JS #جاوااسکریپت
👤 Developix
💎 Channel: @DevelopixJavascript
کتابخونه 🐻 Zustand یه state manager مینیمال برای React هست که بدون ceremony اضافی، state سراسری رو برات حل میکنه.
مزیتش نسبت به Redux و بقیه چیه؟
• API خیلی ساده و مستقیم
• بدون providerهای تو در تو؛ فقط یک store
• performance عالی با رندر کمتر کامپوننتها
• پشتیبانی از TypeScript بدون دردسر
یه مثال ساده:
npm install zustand
import { create } from 'zustand'
const useBearStore = create((set) => ({
bears: 0,
increase: () => set((state) => ({ bears: state.bears + 1 })),
}))
function Counter() {
const bears = useBearStore((state) => state.bears)
const increase = useBearStore((state) => state.increase)
return <button onClick={increase}>Bears: {bears}</button>
}
برای پروژههایی که Redux براشون زیادی سنگینه، Zustand گزینهایه که هم کد رو تمیز نگه میداره هم مقیاسپذیره. مخصوصاً برای dashboardها، panelهای ادمین و appهای data-heavy خیلی جواب میده.
مستندات و سورس:
GitHub
Docs
یک بار تو یه پروژه واقعی تستش کن، معمولاً بعدش برگردوندنش به عقب سخته 😄
🔖 #Javascript #JS #جاوااسکریپت #JavaScript #React #Zustand #State_Management #Frontend
👤 Developix
💎 Channel: @DevelopixJavascriptدر کد زیر سازندهی کلاس تلاش میکند با استفاده از
async/await و forEach دادهها را بهصورت غیرهمزمان لود کند، اما رفتار نهایی با انتظار نویسندهی کد فرق دارد و this.data در زمان استفاده هنوز کامل مقداردهی نشده است.
سؤال: در این کد چه چیزی باید تغییر کند تا اجرای غیرهمزمان بهدرستی منتظر اتمام تمام درخواستها بماند و سپس this.data کامل آماده باشد؟
class DataLoader {
constructor(apiUrls) {
this.data = [];
this.load(apiUrls);
}
async load(urls) {
urls.forEach(async (url) => {
const res = await fetch(url);
const json = await res.json();
this.data.push(json);
});
}
}
const loader = new DataLoader([
"https://example.com/api/users",
"https://example.com/api/posts"
]);
// بعداً در جایی دیگر:
console.log("Loaded:", loader.data.length); // مقدار اینجا غیرقابل اعتماد است
🔖 #Javascript #JS #جاوااسکریپت
👤 Developix
💎 Channel: @DevelopixJavascriptخروجی این کد JavaScript چیست؟
به ترتیب و با دقت به event loop و صف microtask و macrotask فکر کنید و رشتهای را که در کنسول چاپ میشود، دقیقا به همان ترتیب بنویسید.
const p = Promise.resolve(1);
p.then(v => {
console.log("A", v);
return v + 1;
}).then(v => {
console.log("B", v);
return Promise.resolve(v + 1);
}).then(v => {
console.log("C", v);
});
setTimeout(() => {
console.log("D");
Promise.resolve().then(() => {
console.log("E");
});
}, 0);
console.log("F");
خروجی نهایی کنسول را دقیقا و به ترتیب، در یک خط یا چند خط، بنویسید.
🔖 #Javascript #JS #جاوااسکریپت
👤 Developix
💎 Channel: @DevelopixJavascript+1
در این نمونهکد، برای هر درخواست ورودی چندین بار JSON.parse روی
req.body انجام میشود که میتواند در درخواستهای سنگین باعث کاهش کارایی، افزایش مصرف CPU و حتی بروز خطا در صورت خراب شدن ساختار بدنه شود. در مقابل، در نسخه اصلاحشده با استفاده از یک middleware اختصاصی، فقط یک بار پارس انجام شده و نتیجه در یک فیلد امن روی req ذخیره میشود.
بهنظر شما در پروژههای واقعی، استفاده از این الگو چه مزیتهایی از نظر performance، قابلیت تست و کاهش ریسک Side Effect نسبت به پارس مستقیم JSON در هر هندلر دارد؟
🔖 #Javascript #JS #جاوااسکریپت
👤 Developix
💎 Channel: @DevelopixJavascript🎯 هندلکردن کلیکها با Event Delegation
وقتی تعداد زیادی دکمه یا آیتم در DOM داریم، اضافهکردن یک event listener روی هر عنصر هم کند است، هم کد را شلوغ میکند. با Event Delegation فقط روی والد گوش میدهیم و رویداد را از مسیر
event.target مدیریت میکنیم. 🔥
✅ این کار:
• تعداد listenerها را کم میکند ✂️
• مدیریت عناصر اضافه/حذفشونده را ساده میکند
مثال ساده روی یک لیست:
const list = document.querySelector('#user-list');
list.addEventListener('click', (event) => {
const item = event.target.closest('li');
if (!item || !list.contains(item)) return;
const userId = item.dataset.userId;
console.log('Clicked user:', userId);
});
حالا هر <li data-user-id="123"> که بعداً با JavaScript به #user-list اضافه شود، بدون نیاز به listener جدید، کلیک را هندل میکند. 🚀
برای جزئیات بیشتر: MDN - Event delegation
توی پروژههای سنگین DOM، این الگو هم خوانایی کد را بهتر میکند هم عملکرد را. 😉
🔖 #Javascript #JS #جاوااسکریپت #JavaScript #Event_Delegation #DOM #Performance #ES6
👤 Developix
💎 Channel: @DevelopixJavascriptRepost from ابر ویراک
ویراک کلود | تجربهی ابری بدون محدودیت ☁️🚀
🎁 ۲۰٪ شارژ هدیه روی اولین واریزی
مزیتهایی که واقعاً فرق میسازن:
⚡️ پهنای باند 980 مگ
🌐با IP مازاد
⏱️ راهاندازی فوری
💳 پرداخت ساعتی
🛡 پشتیبانی ۲۴/۷
💬 هر سوالی داشتی، تیم ما کنارتـه
✅ مناسب استارتاپها، تیمهای فنی، تا سازمانهای بزرگ
همین الان شروع کن و با حداکثر منابع، سریعتر رشد کن 👇🏻
📞 تماس سریع: 02191555530
🔗 https://virakcloud.com
✨ ساخت یک Todo List ساده با JavaScript خالص (بدون Framework)
خیلی وقتها برای تمرین JavaScript و DOM، یک پروژه کوچیک و واقعی مثل Todo List بهترین گزینهست. هم رویدادها رو لمس میکنی، هم کار با DOM و هم مدیریت state ساده رو.
یکی از بهترین رفرنسها برای کار با DOM و رویدادها، مستندات MDN هست:
MDN DOM Introduction
در این تمرین، با چند مفهوم مهم سر و کار داریم:
✅ گرفتن elementها با
querySelector
✅ گوش دادن به eventها مثل submit و click
✅ جلوگیری از refresh فرم با event.preventDefault()
✅ دستکاری DOM با createElement و appendChild
مثال زیر یک Todo List خیلی ساده ولی عملی است. کافیست یک فایل index.html بسازی و این کد را داخلش قرار بدهی و در مرورگر باز کنی:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Simple Todo</title>
<style>
body { font-family: sans-serif; max-width: 480px; margin: 40px auto; }
form { display: flex; gap: 8px; }
ul { padding: 0; list-style: none; }
li { display: flex; justify-content: space-between; margin: 4px 0; }
button { cursor: pointer; }
</style>
</head>
<body>
<h1>Todo List</h1>
<form id="todo-form">
<input id="todo-input" placeholder="New task..." required />
<button type="submit">Add</button>
</form>
<ul id="todo-list"></ul>
<script>
const form = document.querySelector('#todo-form');
const input = document.querySelector('#todo-input');
const list = document.querySelector('#todo-list');
form.addEventListener('submit', function (event) {
event.preventDefault();
const text = input.value.trim();
if (!text) return;
const li = document.createElement('li');
const span = document.createElement('span');
span.textContent = text;
const removeBtn = document.createElement('button');
removeBtn.textContent = 'x';
removeBtn.addEventListener('click', function () {
list.removeChild(li);
});
li.appendChild(span);
li.appendChild(removeBtn);
list.appendChild(li);
input.value = '';
input.focus();
});
</script>
</body>
</html>
نکتههای ریز 👇
• استفاده از trim() جلوی اضافه شدن تسک خالی را میگیرد.
• با event.preventDefault() فرم صفحه را reload نمیکند و کنترل دست ما میماند.
• با addEventListener روی خود دکمه حذف کار میکنیم تا ساختار کد تمیزتر بماند.
این تمرین پایه خوبی برای قدمهای بعدی مثل ذخیرهسازی در localStorage، اضافه کردن فیلتر (Completed / Active) یا بعداً پیادهسازی همین ایده در React یا Vue است.
امتحانش روی یک فایل ساده لوکال حس خوبی از «کار کردن کد» میدهد و درک DOM را خیلی محکمتر میکند. اگر به درد دوستی میخورد که تازه JavaScript را شروع کرده، برایش بفرست 💚
🔖 #Javascript #JS #جاوااسکریپت #JavaScript #DOM #Todo #Frontend #ES6 #VanillaJS
👤 Developix
💎 Channel: @DevelopixJavascriptقانون «یک سطح انتزاع در هر تابع» در JavaScript 🧠✨
یکی از نکات طلایی در Clean Code این است که هر تابع فقط با یک سطح انتزاع کار کند. یعنی یا درگیر جزئیات low-level باشد، یا فقط کارهای high-level را صدا بزند؛ نه هر دو را قاطی.
این قانون کمک میکند:
• خوانایی کد بالا برود 👀
• Refactor کردن سادهتر شود 🔧
• تستنویسی راحتتر شود ✅
🍂 یک مثال از کد شلوغ در Node.js / Express
app.post('/api/users', async (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ message: 'Invalid data' });
}
if (!email.includes('@')) {
return res.status(400).json({ message: 'Invalid email' });
}
const exists = await db.collection('users').findOne({ email });
if (exists) {
return res.status(409).json({ message: 'Already exists' });
}
const hash = await bcrypt.hash(password, 10);
const user = {
email,
password: hash,
createdAt: new Date()
};
await db.collection('users').insertOne(user);
res.status(201).json({ id: user._id, email: user.email });
});
این تابع هم validation انجام میدهد، هم کار دیتابیس، هم جزئیات hash، هم پاسخ HTTP. سطحهای انتزاع قاطی شدهاند.
🌱 Refactor با یک سطح انتزاع در هر تابع
const validateUserPayload = (body) => {
const { email, password } = body;
if (!email || !password) return 'Invalid data';
if (!email.includes('@')) return 'Invalid email';
return null;
};
const createUser = async ({ email, password }, db, hasher) => {
const exists = await db.collection('users').findOne({ email });
if (exists) return { error: 'Already exists' };
const passwordHash = await hasher(password);
const user = {
email,
password: passwordHash,
createdAt: new Date()
};
const result = await db.collection('users').insertOne(user);
return { id: result.insertedId, email: user.email };
};
app.post('/api/users', async (req, res) => {
const validationError = validateUserPayload(req.body);
if (validationError) {
return res.status(400).json({ message: validationError });
}
const result = await createUser(
req.body,
db,
(password) => bcrypt.hash(password, 10)
);
if (result.error) {
return res.status(409).json({ message: result.error });
}
res.status(201).json(result);
});
حالا:
• تابع validateUserPayload فقط validation است ✅
• تابع createUser فقط منطق ساخت کاربر را دارد ✅
• route handler فقط orchestration انجام میدهد ✅
این جداسازی باعث میشود بعداً راحتتر TypeScript اضافه کنید، Unit Test بنویسید، یا منطق ساخت کاربر را در سرویس دیگری (مثلاً در یک worker) استفاده کنید.
منابع برای مطالعه بیشتر:
• Refactoring.Guru
• MDN – Learn JS
قدمبهقدم همین الگو را روی قسمتهای شلوغ پروژههای Node.js / React / Next.js خود پیاده کنید؛ هر بار که یک تابع را به یک سطح انتزاع محدود میکنید، کدتان قابلاعتمادتر و نگهداریپذیرتر میشود 🚀
🔖 #Javascript #JS #جاوااسکریپت #Clean_Code #JavaScript #Node_js #Express #Refactoring #Best_Practices
👤 Developix
💎 Channel: @DevelopixJavascriptدر کد زیر یک خطای ظریف در استفاده از async/await و Array.prototype.map وجود دارد که باعث میشود رفتار برنامه مطابق انتظار نباشد.
چه چیزی باید در این کد تغییر کند تا همه درخواستها به صورت async درست اجرا شوند و مقدار نهایی
results به درستی شامل پاسخهای resolve شده باشد؟
const urls = [
"https://api.example.com/user/1",
"https://api.example.com/user/2",
"https://api.example.com/user/3",
];
async function fetchUsers() {
let results = [];
urls.map(async (url) => {
const res = await fetch(url);
const data = await res.json();
results.push(data);
});
return results;
}
fetchUsers().then((users) => {
console.log("Users:", users);
});
🔖 #Javascript #JS #جاوااسکریپت
👤 Developix
💎 Channel: @DevelopixJavascriptدر کد زیر توسعهدهنده میخواهد یک حلقه از توابع async بسازد که بهترتیب و با فاصله زمانی اجرا شوند، اما نتیجهی نهایی آرایهای خالی یا ناقص برمیگردد و همهی async ها درست منتظر نمیمانند.
سوال: در این کد چه چیزی باید اصلاح شود تا Promise chain بهدرستی کار کند و همهی درخواستهای async بهترتیب انجام شده و در نهایت آرایه
results بعد از تکمیل همهی عملیات برگردانده شود؟
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function fetchData(id) {
await delay(100);
console.log("fetched", id);
return { id, time: Date.now() };
}
function runSequential(ids) {
const results = [];
ids.forEach(async (id) => {
const data = await fetchData(id);
results.push(data);
});
return Promise.resolve(results);
}
runSequential([1, 2, 3]).then(console.log);
🔖 #Javascript #JS #جاوااسکریپت
👤 Developix
💎 Channel: @DevelopixJavascriptگاهی کد async/await خیلی شلوغ میشه چون پر از try/catch تکراریه. یه الگوی جمعوجور میتونه هم کد رو تمیز کنه، هم مدیریت خطاها رو واضحتر کنه.
ایده اینه: بهجای try/catch دور هر await، یه helper کوچک مینویسیم که همیشه نتیجه رو به شکل یک آرایه برگردونه: [err, data]. شبیه سبک Node.js، ولی مدرن و تمیز 😎
const to = (promise) => promise
.then((data) => [null, data])
.catch((err) => [err, null]);
async function fetchUser(userId) {
const [err, res] = await to(
fetch(`https://api.example.com/users/${userId}`)
);
if (err) {
console.error('خطا در درخواست:', err);
return null;
}
const [parseErr, data] = await to(res.json());
if (parseErr) {
console.error('خطا در parse کردن JSON:', parseErr);
return null;
}
return data;
}
نکات مهم ✅
• ساختار کنترل خطا توی تابع مشخص و خطی میمونه، بدون چندین try/catch تو در تو.
• میشه این الگو رو برای هر Promise (مثل عملیات دیتابیس، fetch، کار با فایل در Node.js و ...) دوباره استفاده کرد.
• حواست باشه همیشه یا هر دو مقدار [err, data] رو destructure کنی، یا حداقل err رو چک کنی تا Memory Leak یا رفتار غیرمنتظره نگیری.
برای ساخت API تمیز و قابل تست، این الگو کنار TypeScript یا JSDoc خیلی خوب جواب میده، چون نوع خروجی همیشه قابل پیشبینی و یکنواخته.
امتحان این pattern روی فانکشنهای async کوچیک شروع میشه، بعد کمکم میتونه تبدیل بشه به style اصلیت برای هندل کردن Promiseها 🙌
مرجع بیشتر درباره Promise و خطاها تو MDN:
MDN - Promise
🔖 #Javascript #JS #جاوااسکریپت #JavaScript #async_await #Promise #error_handling #ES6
👤 Developix
💎 Channel: @DevelopixJavascriptRepost from کانال رسمی تک نت | Taknet
🚀 سرور اختصاصی با تنوع منابع برای هر نوع نیاز
⏺پورت اختصاصی
⏺آپلود رایگان
⏺تخفیف پلکانی ترافیک
⏺آپتایم 99.99%
⏺24 ساعت تست رایگان
⏺رائه IP مازاد
⏺پشتیبانی 24/7
⏺تحویل فوری
⏺ارائه سرویس Colocation
⏺بدون قطعی
⏺پرداخت ماهیانه
⏰ تعداد محدود – برای استفاده از این تخفیف ویژه سریع اقدام کن!
برای اطلاعات بیشتر و سفارش، تماس بگیر:
🔺 02191555530
💻 خرید سرور اختصاصی
