إذا كنت تعمل مع PHP فربما لم ترَ جافاسكريبت إلا بنسخ مقاطع الكود. ينفع ذلك ما دام لا يحدث خلل، لكن كل نموذج حي أو قائمة منسدلة أو طلب بلا إعادة تحميل سيوصلك إليها عاجلًا أو آجلًا. والخبر الجيد أن الجزء اللازم للعمل في الواجهة الخلفية صغير.

يغطي هذا الدليل ذلك الجزء فقط ويفترض أن لديك من PHP إلمامًا بالمتغيرات والدوال والشروط.

أين تعمل جافاسكريبت#

يعمل PHP على الخادم ويُخرج HTML. أما جافاسكريبت فتعمل في متصفح المستخدم وتجعل الصفحة المستلمة حية. وكل ما تراه في جافاسكريبت يستطيع المستخدم رؤيته وتعديله أيضًا. وهذا يعني أن التحقق الأساسي من المدخلات والتحكم في الصلاحيات يجب أن يكونا دائمًا في PHP، لا في المتصفح وحده.

المتغيرات والأنواع#

ابتعد عن var. تكفي في الكود الحديث كلمتان:

JavaScript
const siteName = 'di9';     // لا تتغير قيمته
let count = 0;              // تتغير قيمته
count += 1;

const user = { name: 'سارة', age: 30 };
const tags = ['php', 'js'];

القاعدة: عرّف كل شيء بـconst ولا تستخدم let إلا عند الحاجة. وانتبه إلى أن const تعني أن المتغير نفسه لا يأخذ قيمة جديدة، لا أن محتوى الكائن أو المصفوفة يصبح ثابتًا. وأجرِ المقارنة بـ=== لا ==. أما القيم 0 والنص الفارغ وnull وundefined وNaN فتُعد «خاطئة» في الشرط، وقد يفاجئك ذلك أحيانًا.

الدوال#

JavaScript
function add(a, b) {
  return a + b;
}

const double = (n) => n * 2;          // دالة سهمية
const greet = (name = 'ضيف') => `مرحبًا ${name}`; // قيمة افتراضية ونص قالبي

النص القالبي (بالعلامة الخلفية ` ) يضع المتغير داخل النص ويمتد على عدة أسطر أيضًا.

المصفوفات والكائنات#

ثلاث دوال للمصفوفات تحل محل معظم الحلقات اليدوية:

JavaScript
const prices = [1000, 2500, 4000];

const withTax = prices.map((p) => Math.round(p * 1.1));
const expensive = prices.filter((p) => p > 2000);
const total = prices.reduce((sum, p) => sum + p, 0);

وفي الكائنات يختصر التفكيك (destructuring) وعامل النشر العمل:

JavaScript
const { name, age } = user;
const updated = { ...user, age: 31 }; // نسخة مع تعديل
const all = [...tags, 'laravel'];

كما في PHP، المصفوفة الترابطية هي الكائن البسيط؛ فقط تُكتب المفاتيح بلا => وبنقطتين رأسيتين.

DOM والأحداث#

DOM شجرة عناصر الصفحة. اختيارها وتعديلها:

JavaScript
const btn = document.querySelector('#save');
const list = document.querySelector('.items');

btn.addEventListener('click', () => {
  const li = document.createElement('li');
  li.textContent = 'عنصر جديد'; // بدل innerHTML، وهو أكثر أمانًا
  list.append(li);
});

انتبه إلى textContent. فإذا وضعت في الصفحة نصًا قادمًا من المستخدم أو الخادم عبر innerHTML فهذه هي ثغرة XSS نفسها التي رأيناها في أمان كود PHP. للنص البسيط استخدم textContent.

وفي النماذج تلتقط عادةً الحدث submit وتوقف الإرسال المعتاد بـevent.preventDefault() لترسل الطلب بنفسك. وحمّل السكربت بـdefer ليكون DOM جاهزًا:

JavaScript
document.addEventListener('DOMContentLoaded', () => {
  // هنا نتأكد من وجود العناصر
});

الكود غير المتزامن: Promise وasync/await#

طلب الشبكة ليس فوريًا. لا تنتظر جافاسكريبت، بل تأخذ وعدًا (Promise) بدلًا من ذلك. ويجعل async/await قراءته كقراءة الكود العادي:

JavaScript
async function loadUser(id) {
  try {
    const res = await fetch(`/api/users/${id}`);
    if (!res.ok) throw new Error(`خطأ ${res.status}`);
    return await res.json();
  } catch (err) {
    console.error(err);
    return null;
  }
}

نقطة مهمة: لا يرمي fetch خطأً إلا إذا انقطعت الشبكة؛ فالاستجابة 404 أو 500 ليست خطأً وعليك فحص res.ok بنفسك. وتجد مزيدًا من التفاصيل في طلبات AJAX باستخدام fetch.

الوحدات (Modules)#

قسّم الكود إلى ملفات صغيرة:

JavaScript
// utils.js
export const formatPrice = (n) => n.toLocaleString('en-US');

// main.js
import { formatPrice } from './utils.js';

في الصفحة حمّل السكربت بـtype="module". وفي ووردبريس سجّل السكربت دائمًا عبر wp_enqueue_script ومرّر إليه بيانات PHP بـwp_localize_script أو wp_add_inline_script، لا بلصقها يدويًا داخل القالب.

جدول المعادلات لمبرمج PHP#

في PHPفي جافاسكريبت
array_maparr.map()
array_filterarr.filter()
in_arrayarr.includes()
json_encodeJSON.stringify()
json_decodeJSON.parse()
strlenstr.length
$a ?? 'x'a ?? 'x'

يؤدي العامل ?? في اللغتين العمل نفسه تقريبًا.

ما الذي تؤجله الآن#

لا تحتاج في البداية إلى React أو Vue أو أدوات البناء. وما دمت لم تواجه حاجة حقيقية فجافاسكريبت البسيطة كافية. وبعد ذلك يمكنك الانتقال إلى Alpine.js أو Vue في لارافيل. وإن كنت تبني كتلة (block) مخصصة في ووردبريس فستصل هناك إلى React. لكن أساس كل ذلك هو هذه المفاهيم نفسها.

أخطاء شائعة لمبرمجي PHP في جافاسكريبت#

بعض العادات لا تنتقل من PHP إلى جافاسكريبت وتسبب الحيرة. أولًا، مقارنة المصفوفات والكائنات بـ=== تقارن المرجع فقط: فلا تُعد مصفوفتان متطابقتا المحتوى متساويتين ما لم تكونا الكائن نفسه. ثانيًا، يتصرف this بشكل مختلف في الدوال العادية والسهمية؛ فالدالة السهمية تحتفظ بـthis المحيط بها وهي أأمن في دوال callback. ثالثًا، جمع نص مع رقم يُنتج نصًا: '5' + 3 يساوي '53'، لكن '5' - 3 يساوي 2.

ومن ذلك أيضًا كثرة الأخطاء الصامتة في جافاسكريبت. وإذا لم يعمل شيء فافتح أولًا وحدة تحكم المتصفح (عادةً بالمفتاح F12) واقرأ الرسالة الحمراء. فمعظم المشكلات مكتوبة هناك، مثل «Cannot read properties of null» التي تعني أن querySelector لم يجد العنصر.

كيف نتدرب#

أفضل طريقة للتعلم هي بناء عمل صغير حقيقي. مثلًا نموذج تواصل يرسل الرسالة دون إعادة تحميل ويعرض النتيجة. يستعمل هذا التمرين تقريبًا كل موضوعات المقالة: اختيار العنصر، والحدث، وfetch، وasync/await، وعرض النتيجة بأمان. وكلما علقت ابحث عن ذلك المفهوم وحده وتابع. وتوثيق MDN مرجع موثوق ومحدّث دائمًا لكل دالة وميزة في المتصفح.

الخلاصة#

  • تعمل جافاسكريبت في المتصفح؛ فلا تعتمد عليها وحدها في التحقق والصلاحيات.
  • استخدم const وlet بدل var وقارن بـ===.
  • تحل map وfilter وreduce محل معظم الحلقات.
  • للنص البسيط استخدم textContent لا innerHTML.
  • تعلّم async/await مع fetch وافحص res.ok.
  • في ووردبريس سجّل السكربت بـwp_enqueue_script.