-
المساهمات
2443 -
تاريخ الانضمام
-
تاريخ آخر زيارة
-
عدد الأيام التي تصدر بها
3
نوع المحتوى
ريادة الأعمال
البرمجة
التصميم
DevOps
التسويق والمبيعات
العمل الحر
البرامج والتطبيقات
آخر التحديثات
قصص نجاح
أسئلة وأجوبة
كتب
دورات
كل منشورات العضو عبد الوهاب بومعراف
-
مع الأسف لا يوجد حاليا توثيق رسمي ل Pandas في موسوعة حسوب، لكن يمكنك أن تجد الكثير من المعلومات والمصادر داخل مقالات أكاديمية حسوب من هنا: وفي نهاية الصفحة ستجد عدة روابط أخرى يمكها أن تفيدك أكثر:
- 3 اجابة
-
- 1
-
-
رغم الأداء المتفوق الذي تقدمه Bun، خاصة في سرعة تنفيذ العمليات حيث بعد بحث قصير وجدت أن بعض الاختبارات التي تم إجراؤها أظهرت أنه أسرع من Node.js بثلاثة أضعاف في طلبات HTTP إلا أن الإحصائيات الرسمية لعام 2024 و2025 تؤكد أن Node.js لا يزال المسيطر في السوق. فبحسب استطلاع Stack Overflow 2024، يستخدم أكثر من 40.8% من المطورين Node.js، وتظهر تقارير مثل W3Techs أن أكثر من 4.6% من المواقع تستخدمه، مع أكثر من 1.4 مليار عملية تنزيل تاريخيا. كما أنّ Node.js يحظى بدعم واسع في المؤسسات الكبرى ولديه نظام بيئي ناضج يضم ملايين الحزم على npm. في المقابل لا تزال Bun حديثة نسبيا حيث أطلقت نسختها المستقرة الأولى في سبتمبر 2023 وتفتقر إلى الاستقرار الكامل والتبني المؤسسي على نطاق واسع.
-
يوجد فرق واضح بينهما رغم أن المفهومين مرتبطان ببعضهما فنمذجة الكائنات هي مرحلة تحليل وتصميم تسبق كتابة الكود، وتركز على تمثيل النظام من خلال كائنات (Objects) تحاكي مكونات العالم الحقيقي. في هذه المرحلة نستخدم أدوات مثل الرسومات التخطيطية ك UML لتحديد الكائنات، خصائصها (السمات)، وسلوكها (الوظائف أو الدوال)، وكيفية تفاعلها معا والهدف منها هو الفهم العميق للنظام المطلوب بناءه وتنظيمه بطريقة منطقية قبل الدخول في عملية البرمجة. أما البرمجة كائنية التوجه، فهي أسلوب لكتابة الكود بلغة تدعم هذا النمط مثل Java و بايثون C++. في هذا الأسلوب نقوم بتحويل التصميم أو النموذج الذي أنشأناه في مرحلة النمذجة إلى كود حقيقي من خلال إنشاء "Classes" و"Objects"، واستخدام مفاهيم مثل الوراثة (Inheritance)، التغليف (Encapsulation)، والتعددية الشكلية (Polymorphism).
- 4 اجابة
-
- 1
-
-
لا داعلي للقلق ففي HTML بعض الوسوم مثل <link> لا تحتاج أن تكتب في آخرها /، لأنها وسوم ذاتية الإغلاق ففي HTML5 كتابة الوسم بدون / صحيحة تماما وليس فيها أي مشكلة فالشرطة المائلة / كانت ضرورية في نسخ قديمة مثل XHTML فقط.
- 3 اجابة
-
- 1
-
-
هندسة البرومبت هي فن وعلم صياغة التعليمات أو الأسئلة الموجهة لنماذج الذكاء الاصطناعي، وخاصة النماذج اللغوية الكبيرة لتحقيق أفضل النتائج الممكنة، و تعتمد على فهم كيفية تفاعل النموذج مع المدخلات، واستخدام تقنيات مثل التوضيح، التدرج في الأسئلة، أو تضمين أمثلة في البرومبت لتحسين دقة ومصداقية الإجابة، لتعلمها ابدأ بدراسة أساسيات الذكاء الاصطناعي واللغويات التطبيقية، ثم تدرب على صياغة أسئلة متنوعة وتحليل استجابات النموذج، و بالتأكيد الممارسة المستمرة والتجريب هما المفتاح لإتقان هذا المجال سريع التطور.
- 5 اجابة
-
- 1
-
-
بالنسبة لأدوات التصميم، فإن Canva يعتبر بسيط جدا لمشاريع الويب المحترفة، وبدلا منه يمكنك تجربة Figma أو Adobe XD لإنشاء نماذج أولية وتصاميم تفصيلية قبل التنفيذ، و أيضا لا تنسَ استخدام أطر عمل مثل Bootstrap أو Tailwind CSS لتسريع عملية التطوير، و المفتاح هو البدء بالأساسيات ثم التدرج نحو الأدوات الاحترافية مع تطور مهاراتك.
-
في React نستخدم map بدلا من الحلقات التقليدية مثل for وwhile لأن map ستعيد لنا مصفوفة جديدة تحتوي على عناصر JSX جاهزة للعرض مباشرة داخل دالة render أو داخل return للدوال المركبة وهو ما يتماشى مع التصميم الدالي (Functional) لرياكت. بعكس for وwhile التي تستخدم لأغراض تكرار عام وتحتاج إلى إنشاء مصفوفة خارجية ثم دفع العناصر إليها يدويا فإن map تبقي الكود أكثر نظافة وتسمح بتعيين key لكل عنصر بسهولة وتجنب التعديلات الجانبية. وهذه ميزة في React بحيث تسهل تتبّع العناصر وإعادة رسمها بكفاءة عند التحديث ونستخدمها بكثرة لأنها متوافقة تماما مع نمط JSX الذي يتطلب إرجاع عناصر قابلة للعرض مباشرة ضمن البنية الشجرية للمكوّن.
-
كلامك صحيح ولهذا Python يستخدم Event Loop من مكتبة asyncio لتنظيم المهام غير المتزامنة. فعندما يواجه كلمة await سيتوقف عن تنفيذ هذه المهمة مؤقتا وينتقل لتنفيذ مهام أخرى، ثم يعود إليها عندما تصبح جاهزة. وكل هذا يحدث في نفس الخيط الرئيسي، ولكن بطريقة تعاونية بحيث كل مهمة تعطي الفرصة للمهام الأخرى عند الانتظار. لاحظ الكود التالي: import asyncio async def task1(): await asyncio.sleep(2) async def task2(): await asyncio.sleep(1) asyncio.run(asyncio.gather(task1(), task2())) في البداية قمنا باستيراد المكتبة asyncio ثم عندما يبدأ تنفيذ task1 ويصل ل: await asyncio.sleep(2) يتركها فورا وينتقل ل task2 وعندما يصل ل: await asyncio.sleep(1) يتركها أيضا ويعود للأولى أو ينتظر وهكذا يدور بينهما لأن task2 تحتاج ثانية واحدة فقط بينما task1 تحتاج ثانيتين أي ستنتهي task2 أولا رغم أن task1 بدأت قبلها، وهذا يثبت أن Event Loop يشغلهما بالتوازي وليس واحدة تلو الأخرى.
-
للأسف لا يمكنك تحميل دروس الدورة في الوقت الحالي وتم منع ذلك تفاديا لإعادة نشر الدروس خارج منصة الأكاديمية وهذا لتحقيق العدل بين مشتركي الأكاديمية فلا يعقل أن يشترك البعض لكي يستفيدوا من الدروس بينما آخرون يأخذونها على طبق من ذهب. لذا بدلا من تحميل الفيديو يمكنك خفض جودته إلى 540 وهي جودة مناسبة لمتابعة الدروس بسلاسة.
-
يجب عليك إنشاء ملف حتى يظهر لديك زر run، أرجوا الضغط على File و من ثم إختر new file من هناك، أو يمكنك فتح ملف بايثون مباشرة إذا كان متوفر لديك و بعدها يمكنك الضغط على run.
-
وعليكم السلام. بداية في حال كان سؤالك متعلقا بإحدى دروس الدورة التي قمت بالاشتراك فيها فأرجو طرح أسئلتك هناك أسفل الدرس فهنا نجيب فقط على الأسئلة العامة، على العموم فلو أخذنا فرضا أنك تقصد العمل ب Vue Js فلتفعيل النموذج عند حدث submit في <form> يمكننا استخدام التوجيه كالتالي: @submit.prevent="methodName" حيث يقوم @submit بالاستماع إلى الحدث و.prevent تمنع إعادة تحميل الصفحة الافتراضية عند الإرسال وأما methodName هو اسم الدالة التي تنفّذ عند الإرسال لماذا ذلك؟ لأنه في إطار Vue.js تعد إدارة النماذج سهلة وفعالة بفضل نظام التوجيه (directives) وعند التعامل مع نموذج، مثل تسجيل الدخول أو إنشاء حساب ستحتاج إلى التقاط الحدث الذي يحدث عند الضغط على زر "إرسال". وللقيام بذلك نستخدم عنصر <form> ونربطه بحدث submit عبر التوجيه @submit وتفاديا السلوك الافتراضي الذي يتمثل في إعادة تحميل الصفحة نضيف .prevent، فيصبح @submit.prevent. داخل هذا النموذج ويرتبط كل حقل ب v-model ليتم ربط بيانات النموذج بحالة (state) المكون ثم تعرّف دالة في قسم methods للتعامل مع البيانات عند إرسال النموذج كالتالي: بمجرد أن يضغط المستخدم على زر "Send"، يتم تنفيذ دالة handleSubmit دون إعادة تحميل الصفحة. تُستخدم هذه الطريقة بشكل واسع في التعامل مع النماذج، خاصة عند إرسال بيانات إلى API أو التحقق من صحة المدخلات. استخدام v-model يجعل البيانات متزامنة بين الواجهة والنموذج، مما يسهل إدارتها. كما يمكن توسيع هذه التقنية لتشمل التحقق من المدخلات، أو إظهار رسائل خطأ، أو إرسال البيانات إلى الخادم باستخدام مكتبات مثل Axios. خلاصة القول، Vue.js توفر أدوات بسيطة وفعالة لتفعيل النماذج والاستجابة لحدث الإرسال بطريقة منظمة وتفاعلية. <template> <form @submit.prevent="handleSubmit"> <input v-model="name" type="text" placeholder="Your name" /> <button type="submit">Send</button> </form> </template> <script> export default { data() { return { name: "" }; }, methods: { handleSubmit() { alert(`Hello, ${this.name}`); } } }; </script> فهنا بمجرد أن يضغط المستخدم على زر "Send" سيتم تنفيذ دالة handleSubmit دون إعادة تحميل الصفحة. وفي حال كنت تعمل على شيء آخر أرجو التوضيح لمساعدتك بشكل دقيق.
-
وعليكم السلام. لديك عدة مشاكل في مشروعك عند فتح المشروع على: http://localhost:3000 يظهر الخطأ التالي: SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON وهذا لأنه ليس لديك هذا المسار /api/languages فهو غير موجود في مشروع Next.js لذا انتقل إلى app ثم أنشئ المجلدات التالية: app/api/languages/route.js ثم داخل ملف route.js ضع التالي: export async function GET() { const data = [ { name: "JavaScript", proficiency: "Advanced" }, { name: "Python", proficiency: "Intermediate" }, { name: "C++", proficiency: "Basic" }, ]; return Response.json(data); } يمكنك التأكد من أن الخطأ زال إذا ظهرت لك بيانات JSON عند التوجه إلى: http://localhost:3000/api/languages ومنه سيعمل الكود في <About /> بدون خطأ. أيضا في ملف components/MyServices.jsx بعض كلاسـات Tailwind مثل: cursor-pointer hover:underline hover:text-main-color هي لا تعمل، والسبب هو أنّه في مشروع Next.js الذي يستخدم App Router أي مجلد app/ بدل pages/ ومنه فجميع المكونات بدون "use client" تعتبر Server Components وكما نعلم فإنّ Server Components لا تدعم التفاعلات مع المستخدم مباشرة، لذلك كلاسـات مثل hover: أو cursor-pointer لا تطبق ومنه في أعلى الملف يجب إضافة: "use client" ليصبح الكود كالتالي: 'use client'; import React from "react"; import Image from "next/image"; import Link from "next/link"; function MyServices() { return ( <div className="p-8"> <h1 className="text-6xl font-bold my-10">My Services</h1> <div className="flex items-center flex-col md:flex-row justify-between gap-10"> <div className="bg-white/30 -z-10 h-96 max-w-[350px] rounded-2xl p-6"> <Image src="/front-end-project.webp" alt="Service 1" className="h-44 rounded-2xl" width={500} height={500} /> <p className="user-select-none text-main-secondary-color font-bold cursor-pointer hover:underline hover:text-main-color"> Project Link </p> <Link href="/" className="text-main-secondary-color font-bold cursor-pointer hover:underline hover:text-main-color" > Github Link </Link> </div> </div> </div> ); } export default MyServices; ولكي يتم استخدام هذا المكون يجب تعديل ملف app/services/page.js لاستعمال المكون كالتالي: 'use client'; import MyServices from "../components/MyServices"; export default function Services() { return <MyServices />; } وعند فتح الرابط على: http://localhost:3000/services ستجد أنه يعمل:
-
المشكلة كما هو موضح في الصورة تحدث لأنك تستخدم معرف وكلمة مرور خاطئة في connection string لذلك يظهر: "Access denied for user 'USER'@'localhost'" بالرجوع إلى ملف app.py في السطر التالي: SQLALCHEMY_DATABASE_URI='mysql+pymysql://USER:PASS@localhost/dashboard' USER و PASS هما placeholders وليسا بيانات حقيقية ومن المفترض أن تستخدم بدلا من ذلك: SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:@localhost/dashboard' وهذا لأنك في ملف docker-compose.yml أنت تستخدم: USER_mysql: 'root' و أما كلمة السر PASSWORD_mysql فهي فارغة في حال استمر المشكل تأكد من أنّ MySQL يعمل وفي حال لم تنشئ قاعدة البيانات قم بإنشائها ثم أعد المحاولة مرة أخرى: CREATE DATABASE dashboard;
-
أنصحك بشدة بتعلم TypeScript بعد إتقان React فهو يضيف نظام الأنواع الثابتة الذي يكتشف الأخطاء أثناء الكتابة، مما يوفر وقت التصحيح. أيضا خاصية الإكمال التلقائي ستصبح أدق وأسرع في محرر النصوص مما يحسن جودة الكود في المشاريع الكبيرة ويسهل العمل الجماعي لأن الأنواع تعمل كتوثيق. كما أنّ معظم الشركات تستخدمه كمعيار أساسي، وهو مطلوب في الوظائف المتقدمة. ولا تقلق بشأن تعلمه فهو سهل لأنك تعرف React مسبقا فقط ستتعلم كتابة الأنواع للمكونات وال props وال state وهذا يساعد في تجنب الأخطاء الشائعة ويجعل إعادة التشكيل أكثر أمانا. بخصوص المكتبات الحديثة فهي توفر دعما ممتازا له كما أنّ الموارد التعليمية كثيرة أنصحك بويكي حسوب فلديها توثيق رسمي له: https://wiki.hsoub.com/TypeScript
-
يمكنك استخدام الصورة من مجلد assets: <link rel="icon" type="image/png" href="/src/assets/your-icon.png" /> أو إذا كانت الصورة في مجلد public: <link rel="icon" type="image/png" href="/your-icon.png" /> أما إذا كنت تستخدم Vite يمكنك وضع الأيقونة في مجلد public وليس assets ليكون بهذه التركيبة: public/ favicon.ico icon.png src/ assets/ ثم في HTML: <link rel="icon" type="image/x-icon" href="/favicon.ico" /> أو: <link rel="icon" type="image/png" href="/icon.png" /> أما إذا كنت تريد استخدام صورة من assets يمكنك نسخ الصورة إلى مجلد public ثم: <link rel="icon" type="image/png" href="/icon.png" /> ولدعم أحجام متعددة استعمل التالي: <link rel="icon" type="image/png" sizes="32x32" href="/icon-32x32.png" /> <link rel="icon" type="image/png" sizes="16x16" href="/icon-16x16.png" /> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
-
نقاط السمعة هي نقاط تدل على كمية تفاعلك داخل الأكاديمية، و تجعلك تعرف العضو النشيط و غير النشيط، هذه هي فائدتها الرئيسية، و الأمر نفسه مع الصاروخ الذي تحدثت عنه حيث يعتبر كمستويات تتعداها عند التفاعل بشكل أكثر و يحتوي حاليا على ثلاث مستويات فقط.
- 3 اجابة
-
- 1
-
-
تأكد من وضع شريط التنقل خارج مكون <Routes> في هيكل التطبيق الرئيسي، بحيث لا يتأثر بتغيير المسارات، مثلا يمكنك وضع شريط التنقل داخل مكون Layout ثابت يستخدم كقالب لجميع الصفحات، أو وضعه مباشرة في ملف App.js مع تغليفه حول <Routes>، و أيضا استخدم خاصية CSS مثل position: fixed أو position: sticky لضمان بقاء الشريط في أعلى الصفحة حتى عند التمرير، كما يجب أن تتأكد من إضافة padding أو margin مناسب للمحتوى الرئيسي لمنع تداخل الشريط مع المحتوى، حيث سيظل شريط التنقل مرئيا ومتاحا للمستخدم بغض النظر عن الصفحة الحالية في التطبيق.
-
تم إعادة تنظيم المحتوى لتحسين تدفق التعلم وتجربة المستخدم، إذا كنت قد أكملت بالفعل جزءا من المسار القديم، فلا داعي لإعادة مشاهدة مقاطع تحليل البيانات إذا كنت قد غطيت المفاهيم الأساسية، ولكن يفضل مراجعة المحتوى الجديد خاصة في تطبيقات المحوّلات Transformers لضمان عدم فقدان أي معلومات مهمة.
- 3 اجابة
-
- 1
-
-
أرجوا تفقد الملفات المرفقة في فيديو المدخل الخاص بالمسار الذي تشاهده حيث ستجد هناك الملفات المرفقة التي تم استخدامها في كل الدورة.
-
SWC هي أداة حديثة تستخدم في تطوير الويب ووظيفتها الأساسية تكمن في تحويل كود JavaScript وTypeScript إلى كود جاهز للتشغيل في المتصفحات. أما كلمة SWC فهي اختصار ل Speedy Web Compiler ومعناها "المترجم السريع للويب" وتم بناؤها SWC بلغة Rust، وهي لغة سريعة جدا في الأداء، وهذا ما يجعل SWC أسرع بعشرات المرات من أدوات تقليدية مثل Babel. بالنسبة لتطوير المواقع فنحن نكتب الكود بلغة حديثة مثل TypeScript أو JavaScript بميزات حديثة ولكن ليس كل المتصفحات تدعم هذه الميزات لذلك نحتاج إلى تحويل هذا الكود إلى نسخة أبسط تستطيع المتصفحات فهمها وهنا يأتي دور SWC حيث يقوم بهذه المهمة بسرعة كبيرة جدا. وما يميز SWC عن غيره هو أمران: السرعة والمرونة فمن ناحية السرعة تأتي من استخدام لغة Rust وهي أسرع بكثير من JavaScript أما المرونة فتعني أن SWC يدعم تحويل TypeScript وJSX الذي يستخدم في React كما يمكن تخصيصه عبر الإضافات (Plugins)، مثل ما كان يفعل المطورون مع Babel. أما اليوم بدأ SWC يستخدم في أدوات شهيرة مثل Next.js، وVite، وTurbopack لأنه يختصر وقت التحويل (build) من دقائق إلى ثوان وهذا يحسن تجربة المطورين بشكل كبير كما يمكن استخدام SWC لتقليل حجم الكود النهائي عبر ضغطه (minify) أو إزالة الأجزاء غير المستخدمة (tree shaking).
-
لا تزال تستخدمه بطبيعة الحالى لأنه يعتبر الركيزة الأساسية لأي تطبيق ويب يعتمد على HTML وJavaScript. فال DOM ليس تقنية قديمة انتهت صلاحيتها، بل هو بنية معيارية ومستمرة لتفاعل المتصفح مع المحتوى، وتستخدم من قبل كل الأطر والمكتبات الحديثة مثل React وVue وAngular وغيرها. وحتى تلك التي تعتمد على مفهوم "Virtual DOM" مثل React، فإنها في النهاية تقوم بتحويل التغيرات إلى DOM حقيقي لعرضها في المتصفح. لكن ربما أنت تقصد التغييرات التي حصلت عليه فما تغير مع الوقت هو طريقة التعامل مع DOM وليس DOM نفسه. فبدلا من التلاعب اليدوي والمباشر به كما كنا نفعل في jQuery، أصبحت الشركات تستخدم أدوات حديثة لتقليل التعامل اليدوي وتحسين الأداء، ولكن النتيجة النهائية تظل DOM يمكنك المطالعة أكثر من هنا:
-
المشكلة هنا تكمن في التعامل الخاطئ مع حالتين خاصتين داخل حلقة do-while والتي تتحكم بدورها في إدخال إجابة المستخدم. فأولا عند إدخالك ل "h" أو "H" للمساعدة فالكود كان يحتوي على تعليق // IDK فقط دون أي تنفيذ فعلي لعرض الخيارات المتاحة من المصفوفة: questions[i][1] مما يعني أن طلب المساعدة كان يتم تجاهله تماما وثانيا المشكلة الأكبر كانت في منطق دالة isValidAnswer() وتفاعلها مع شرط الحلقة، حيث أن هذه الدالة كانت ترجع 0 (false) للنص الفارغ، مما يجعل شرط: while(isValidAnswer(userAnswer)) يتوقف ويخرج من الحلقة، فيتم تمرير النص الفارغ " " إلى مقارنة الإجابة: if(userAnswer == questions[i][2]) حيث يُعتبر إجابة خاطئة حتماً. ولحل المشكلة سيتطلب إعادة هيكلة منطق التحقق بحيث تصبح دالة isValidAnswer() ترجع true لجميع الحالات التي تتطلب البقاء في الحلقة (النص الفارغ، المساعدة، الإدخال غير الصالح) و false فقط للإجابات الصالحة القابلة للتقييم، مع إضافة دالة showHelp() لعرض الخيارات من questions[i][1] عند طلب المساعدة، وإضافة continue بعد كل حالة خاصة للعودة إلى بداية الحلقة دون الخروج إلى فحص صحة الإجابة، بهذا الشكل يتم ضمان أن المستخدم لا يخرج من حلقة السؤال إلا بإدخال إجابة صالحة أو اختيار الخروج من الاختبار كالتالي: else if(userAnswer === "h" || userAnswer === "H"){ alert(`Options:\n1) ${questions[i][1][0]}\n2) ${questions[i][1][1]}\n3) ${questions[i][1][2]}\n4) ${questions[i][1][3]}`); continue; } function isValidAnswer(usrAns){ if(usrAns === "" || usrAns === "h" || usrAns === "H"){ return 1; } if(isNaN(Number(usrAns))){ alert("VALID INPUT") return 1; } return 0; }
-
هذا الكود ينشئ قائمة مهام بسيطة حيث يمكن للمستخدم كتابة مهمة في خانة الإدخال ثم إضافتها بالضغط على الزر. ويتم استخدام useState لحفظ المهام في مصفوفة بحيث يتم عرضها على الشاشة، وأما useRef نستخدمها للوصول مباشرة إلى قيمة الإدخال بدون الحاجة لإعادة تحميل الصفحة أو تحديث الحالة عند كل ضغط على المفاتيح. فمثلا عند الضغط على زر Add يتم أخذ النص من حقل الإدخال باستخدام ref.current.value ثم يضاف إلى القائمة باستخدام setTodos، وبعدها يتم إفراغ حقل الإدخال. والكود يظهر المهام في النهاية باستخدام map داخل قائمة غير مرتبة <ul>.
-
الفرق بين var و let يكمن في أربعة جوانب رئيسية أولا من ناحية النطاق ف var يعمل في كامل الدالة حتى لو تم تعريفه داخل بلوك فرعي مثل الشروط أو الحلقات، بينما let يعمل فقط داخل البلوك الذي عُرِّف فيه فقط، مما يجعله أكثر دقة في التحكم بالمتغيرات. ثانيا عند الاستخدام قبل التعريف ف var لا يظهر خطأ بل يعطي قيمة undefined بسبب خاصية الرفع، أما let فيظهر خطأ لأنه لا يمكن الوصول إليه قبل تعريفه. الفرق الثالث هو أنّ var يسمح بإعادة تعريف نفس المتغير عدة مرات في النطاق الواحد دون مشاكل، بينما let يرفض ذلك ويظهر خطأ لحماية البرنامج من الأخطاء غير المقصودة. وأخيرا في الحلقات var يستخدم نفس المتغير في جميع الدورات مما يسبب مشاكل مع الدوال المؤجلة، أما let فينشئ متغيرا منفصلا لكل دورة وفي البرمجة الحديثة ينصح باستخدام let لكونه أكثر أمانا ووضوحا من var الذي يحمل مشاكل تقنية عديدة. let في JavaScript var في JavaScript
