معايير ترميز JavaScript
معايير JavaScript
Section titled “معايير JavaScript”يتبع XOOPS معايير JavaScript الحديثة (ES6+) مع التركيز على قابلية القراءة والصيانة.
نظرة عامة
Section titled “نظرة عامة”معايير JavaScript في XOOPS تعتمد على:
- ECMAScript 2015+ (ES6 والميزات الحديثة)
- دليل نمط Airbnb JavaScript (مع التعديل)
- اتفاقيات XOOPS للاتساق
- معايير سهولة الوصول (WCAG)
بنية الملفات
Section titled “بنية الملفات”تنظيم الملفات
Section titled “تنظيم الملفات”// 1. تعليق رأس الملف/** * وحدة XOOPS - اسم الميزة * @file يتعامل مع التفاعلات على لوحة المعلومات * @author اسمك <email@example.com> * @copyright 2026 مشروع XOOPS * @license GPL-2.0-or-later */
// 2. الاستيراداتimport { Helper } from './helpers.js';import { API } from './api.js';
// 3. الثوابتconst DEFAULT_TIMEOUT = 5000;const API_ENDPOINT = '/api/v1';
// 4. إعداد الوحدةconst Dashboard = {};
// 5. الدوال الخاصةfunction initializeUI() { // ...}
// 6. الطرق العامةDashboard.init = function () { // ...};
// 7. الصادراتexport default Dashboard;تسمية الملفات
Section titled “تسمية الملفات”// استخدم الأحرف الصغيرة مع الواصلاتdashboard.jsuser-profile.jsform-validator.jsapi-client.js
// مكونات React (PascalCase)UserProfile.jsxFormValidator.jsxDashboard.jsxالمتغيرات والثوابت
Section titled “المتغيرات والثوابت”إعلان المتغيرات
Section titled “إعلان المتغيرات”// استخدم const بشكل افتراضيconst maxRetries = 3;const userName = 'محمد';
// استخدم let للمتغيرات التي تتغيرlet currentIndex = 0;
// تجنب var (قديم)// ❌ var oldStyle = true;
// يمكن تعديل محتويات الكائنات والمصفوفات constconst user = { name: 'محمد' };user.name = 'فاطمة'; // ✅ موافقuser = {}; // ❌ خطأ
const numbers = [1, 2, 3];numbers.push(4); // ✅ موافقnumbers = []; // ❌ خطأتسمية المتغيرات
Section titled “تسمية المتغيرات”// استخدم أسماء وصفيةconst userName = 'محمد'; // ✅const un = 'محمد'; // ❌
// يجب أن تشير متغيرات المنطق إلى الحالةconst isActive = true; // ✅const hasPermission = false; // ✅const canEdit = true; // ✅const active = true; // ❌ غير واضح
// يجب أن تكون المصفوفات بصيغة الجمعconst users = ['محمد', 'فاطمة'];const userList = ['محمد', 'فاطمة'];const items = [];الوظائف
Section titled “الوظائف”إعلان الوظيفة
Section titled “إعلان الوظيفة”// الدوال المسماة (مفضلة لإعادة الاستخدام)function validateEmail(email) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);}
// دوال الأسهم (مفضلة للاستدعاءات)const validateEmail = (email) => { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);};
// دوال أسهم قصيرةconst isPositive = (num) => num > 0;const double = (x) => x * 2;تسمية الوظيفة
Section titled “تسمية الوظيفة”// استخدم أسماء قائمة على الفعل وصفيةfunction getUserById(id) { } // ✅ يصف ما تحصل عليهfunction validateUserInput(data) { } // ✅ يصف الإجراءfunction formatDate(date) { } // ✅ يصف التحويل
// تجنب الأحرف الفردية فقط باستثناء الحالات الواضحة (حلقات)function f(x) { } // ❌function fetch() { } // ❌ يتعارض مع العامل الشاملالفئات والكائنات
Section titled “الفئات والكائنات”تعريف الفئة
Section titled “تعريف الفئة”/** * يمثل مستخدماً في النظام */class User { constructor(name, email) { this.name = name; this.email = email; this.id = null; }
/** * الحصول على اسم عرض المستخدم * @returns {string} */ getDisplayName() { return this.name.trim(); }
/** * التحقق من بريد المستخدم الإلكتروني * @returns {boolean} */ isValidEmail() { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.email); }}
// الاستخدامconst user = new User('محمد علي', 'john@example.com');console.log(user.getDisplayName());كائنات حرفية
Section titled “كائنات حرفية”// استخدم اختصار الكائنconst name = 'محمد';const age = 30;
// اختصار الخصائص (ES6)const person = { name, age, getInfo() { return `${this.name} يبلغ من العمر ${this.age} سنة`; },};التنسيق
Section titled “التنسيق”المسافات والمحاذاة
Section titled “المسافات والمحاذاة”// استخدم 2 مسافات للمحاذاة (أو 4، كن متسقاً)function example() { if (true) { console.log('تم المحاذاة'); }}
// مسافات حول المعاملاتconst x = 5 + 3; // ✅const y = 5+3; // ❌const z = isDone ? 'نعم' : 'لا'; // ✅
// لا توجد مسافة داخل الأقواسif (condition) { } // ✅if ( condition ) { } // ❌
// مسافة قبل أقواس الدالةfunction test() { } // ✅function test(){ } // ❌السلاسل
Section titled “السلاسل”حروف السلسلة
Section titled “حروف السلسلة”// استخدم الاقتباسات الفردية للاتساقconst name = 'محمد'; // ✅
// أو الاقتباسات المزدوجة - فقط كن متسقاًconst name = "محمد";
// استخدم علامات الجنس للقوالب (الاستيفاء)const greeting = `مرحباً، ${name}!`; // ✅
// تجنب الربطconst message = 'مرحباً ' + name; // ❌const message = `مرحباً ${name}`; // ✅المصفوفات
Section titled “المصفوفات”طرق المصفوفة
Section titled “طرق المصفوفة”// فضل طرق المصفوفة الحديثةconst numbers = [1, 2, 3, 4, 5];
// الخريطةconst doubled = numbers.map(n => n * 2); // ✅
// التصفيةconst evens = numbers.filter(n => n % 2 === 0); // ✅
// تقليلconst sum = numbers.reduce((acc, n) => acc + n, 0); // ✅
// بحثconst first = numbers.find(n => n > 3); // ✅
// بعض/كلconst hasEven = numbers.some(n => n % 2 === 0); // ✅const allPositive = numbers.every(n => n > 0); // ✅البرمجة غير المتزامنة
Section titled “البرمجة غير المتزامنة”الوعود
Section titled “الوعود”// وعد أساسيconst promise = new Promise((resolve, reject) => { if (success) { resolve(result); } else { reject(error); }});
// طرق الوعودPromise.all([p1, p2, p3]) .then(results => console.log(results)) .catch(error => console.error(error));Async/Await
Section titled “Async/Await”// مفضل للقراءةasync function fetchUser(userId) { try { const response = await fetch(`/api/users/${userId}`); if (!response.ok) throw new Error('لم يتم العثور على المستخدم'); const data = await response.json(); return data; } catch (error) { console.error('فشل جلب المستخدم:', error); throw error; }}
// الاستخدامconst user = await fetchUser(123);التعليقات والتوثيق
Section titled “التعليقات والتوثيق”تعليقات التعليقات
Section titled “تعليقات التعليقات”// اشرح لماذا وليس ماذاconst result = calculateTotal(items, taxRate); // ✅ لماذا
// ❌ لا شرح الكود الواضحconst x = 5; // اضبط x على 5const sum = a + b; // أضف a و bتعليقات JSDoc
Section titled “تعليقات JSDoc”/** * حساب السعر الإجمالي للعناصر بما في ذلك الضريبة * * @param {Array<Object>} items - مصفوفة من العناصر بخاصية السعر * @param {number} taxRate - معدل الضريبة كعشري (0.1 = 10%) * @returns {number} السعر الإجمالي بما في ذلك الضريبة * @throws {Error} إذا لم تكن العناصر مصفوفة * @example * const total = calculateTotal( * [{ price: 100 }, { price: 50 }], * 0.1 * ); * console.log(total); // 165 */function calculateTotal(items, taxRate = 0) { if (!Array.isArray(items)) { throw new Error('يجب أن تكون العناصر مصفوفة'); }
const subtotal = items.reduce((sum, item) => sum + item.price, 0); return subtotal * (1 + taxRate);}معالجة الأخطاء
Section titled “معالجة الأخطاء”Try/Catch
Section titled “Try/Catch”// تعامل دائماً مع الأخطاءtry { const result = riskyOperation();} catch (error) { console.error('فشل التشغيل:', error);} finally { cleanup();}
// كن محدداً مع الأخطاءtry { const data = JSON.parse(jsonString);} catch (error) { if (error instanceof SyntaxError) { console.error('JSON غير صحيح'); } else { console.error('خطأ غير معروف'); }}أفضل الممارسات الملخصة
Section titled “أفضل الممارسات الملخصة”- استخدم const بشكل افتراضي
- استخدم أسماء وصفية
- استخدم دوال الأسهم للاستدعاءات
- استخدم async/await للوعود
- وثائق الوظائف المعقدة
- ذاكرة تخزين مؤقت عناصر DOM
- استخدم تفويض الحدث
- اكتب وظائف نقية
- حافظ على الوظائف مركزة
لا تفعل
Section titled “لا تفعل”- لا تستخدم var (قديم)
- لا تستخدم المتغيرات الشاملة
- لا تنشئ وظائف طويلة (أكثر من 50 سطر)
- لا تتداخل الأكوام بعمق
- لا تستخدم eval()
- لا تستخدم معالجات الحدث المضمنة
- لا تترك console.log() في الإنتاج
- لا تنشئ تسريبات الذاكرة
- لا تعدل معاملات الدالة
أدوات والفحص
Section titled “أدوات والفحص”تكوين ESLint
Section titled “تكوين ESLint”{ "env": { "browser": true, "es2021": true, "node": true }, "extends": ["eslint:recommended"], "rules": { "indent": ["error", 2], "quotes": ["error", "single"], "semi": ["error", "always"], "no-var": "error", "prefer-const": "error" }}التوثيق ذات الصلة
Section titled “التوثيق ذات الصلة”- إرشادات CSS
- قواعس السلوك
- سير العمل المساهم
- معايير PHP
#xoops #javascript #es6 #coding-standards #best-practices