404 Not Found

404 Not Found


nginx

الكائنات في جافاسكريبت

الكائنات هي أهم بنية بيانات في جافاسكريبت. فكّر فيها كـ بطاقات معلومات — الأمامية تقول "الاسم: سارة" والخلفية تقول "العمر: 20". كل قطعة معلومات لها مفتاح وقيمة، يشكلان زوج مفتاح-قيمة.

إنشاء الكائنات الحرفية

استخدم الأقواس المقوسة {} لكتابة كائن مباشرة — هذا هو الأسلوب الأكثر شيوعًا:

HTML
<script>
const student = {
  name: "سارة",
  age: 20,
  major: "علوم الحاسب"
};
console.log(student);
</script>

أزواج المفتاح-قيمة مفصولة بنقطتين، والأزواج مفصولة بفواصل. الفاصلة الأخيرة بعد الزوج الأخير مسموح بها (ومريحة للإضافات المستقبلية).

الوصول إلى الخصائص

طريقتان للوصول إلى خصائص الكائن:

الطريقة البناء متى تستخدم
بنية النقطة obj.name عندما يكون اسم الخاصية مُعرّفًا صالحًا
بنية الأقواس obj["name"] عندما يحتوي الاسم على أحرف خاصة أو مخزن في متغير

أكبر ميزة لبنية الأقواس: يمكنك استخدام متغير كمفتاح.

HTML
<script>
const key = "name";
console.log(student[key]); // مثل student["name"]
</script>

تعديل وإضافة الخصائص

بعد إنشاء كائن، يمكنك تعديل الخصائص الحالية أو إضافة جديدة في أي وقت — حتى لو تم إعلان الكائن بـ const (const يُقفل المرجع، وليس المحتوى).

HTML
<script>
student.age = 21;          // تعديل
student.grade = "سنة ثالثة";  // إضافة خاصية جديدة
console.log(student);
</script>

حذف الخصائص

استخدم عامل delete لإزالة خاصية بالكامل:

HTML
<script>
delete student.grade;
console.log(student);
</script>

بعد الحذف، الوصول إلى تلك الخاصية يُرجع undefined.

الأساليب

الدالة داخل كائن تسمى أسلوب. عندما تصبح الدالة قيمة خاصية، يمكن للكائن "فعل أشياء":

HTML
<script>
const dog = {
  name: "ريكس",
  bark() {
    return "نباح! أنا " + this.name;
  }
};
console.log(dog.bark());
</script>

كلمة this

this تشير إلى "الكائن الحالي" — whoever يستدعي الأسلوب، this هو ذلك الكائن. هذا أحد أكثر مفاهيم جافاسكريبت صعوبة: إذا تم استخراج أسلوب واستدعائه بشكل منفصل، this لا تشير إلى الكائن الأصلي.

HTML
<script>
const bark = dog.bark;
console.log(bark()); // this لا تشير إلى dog بعد الآن — قد تكون window أو undefined
</script>

المنشئات

عندما تحتاج لإنشاء كائنات متعددة بنفس الهيكل بشكل جماعي، استخدم دالة المنشئ:

HTML
<script>
function Person(name, age) {
  this.name = name;
  this.age = age;
  this.sayHi = function() {
    return "مرحبا، أنا " + this.name;
  };
}

const p1 = new Person("أحمد", 25);
const p2 = new Person("محمد", 30);
console.log(p1.sayHi());
console.log(p2.sayHi());
</script>

new تفعل ثلاثة أشياء: تُنشئ كائنًا فارغًا → تُعيّن this لت pointing إليه → تُرجع الكائن.

Object.keys / values / entries

هذه الطرق الثلاثة الثابتة تُرجع مصفوفات بمفاتيح الكائن وقيمه وأزواج المفتاح-قيمة:

الطريقة الإرجاع
Object.keys(obj) ["name", "age"]
Object.values(obj) ["سارة", 20]
Object.entries(obj) [["name","سارة"], ["age",20]]

مفيدة للغاية لتكرار الكائنات: Object.keys(obj).forEach(key => ...).


مثال: إنشاء كائن طالب وعرض المعلومات

HTML
<!DOCTYPE html>
<html lang="ar">
<head>
  <meta charset="UTF-8">
  <title>أساسيات الكائنات</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    .card { border: 2px solid #4a90d9; border-radius: 8px; padding: 16px; max-width: 360px; background: #f0f7ff; }
    .card h3 { margin: 0 0 8px; color: #4a90d9; }
    .card p { margin: 4px 0; }
  </style>
</head>
<body>
  <h2>بطاقة معلومات الطالب</h2>
  <div id="output"></div>
  <script>
    const student = {
      name: "سارة",
      age: 20,
      major: "علوم الحاسب",
      gpa: 3.7,
      introduce() {
        return `اسمي ${this.name}، عمري ${this.age} سنة، أدرس ${this.major} بمعدل ${this.gpa}.`;
      }
    };

    const output = document.getElementById("output");
    output.innerHTML = `
      <div class="card">
        <h3>${student.name}</h3>
        <p>العمر: ${student.age}</p>
        <p>التخصص: ${student.major}</p>
        <p>المعدل: ${student.gpa}</p>
        <p><em>${student.introduce()}</em></p>
      </div>
    `;
  </script>
</body>
</html>
▶ جرّب الكود

مثال: بنية النقطة مقابل بنية الأقواس

HTML
<!DOCTYPE html>
<html lang="ar">
<head>
  <meta charset="UTF-8">
  <title>طرق الوصول إلى الخصائص</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    .result { background: #f5f5f5; padding: 12px; border-radius: 6px; margin: 8px 0; }
    code { background: #e0e0e0; padding: 2px 6px; border-radius: 3px; }
  </style>
</head>
<body>
  <h2>مقارنة الوصول إلى الخصائص</h2>
  <div id="output"></div>
  <script>
    const user = {
      name: "أحمد",
      age: 28,
      "home-city": "القاهرة"
    };

    const key = "name";
    const results = [];

    results.push(`user.name → ${user.name}`);
    results.push(`user["name"] → ${user["name"]}`);
    results.push(`user[key](key="name") → ${user[key]}`);
    results.push(`user["home-city"] → ${user["home-city"]}`);

    document.getElementById("output").innerHTML = results
      .map(r => `<div class="result"><code>${r}</code></div>`)
      .join("");
  </script>
</body>
</html>
▶ جرّب الكود

مثال: إضافة وتعديل وحذف الخصائص ديناميكيًا

HTML
<!DOCTYPE html>
<html lang="ar">
<head>
  <meta charset="UTF-8">
  <title>العمل مع الخصائص</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    table { border-collapse: collapse; margin: 12px 0; }
    td, th { border: 1px solid #ccc; padding: 8px 14px; text-align: left; }
    th { background: #4a90d9; color: #fff; }
    .action { color: #888; font-style: italic; margin: 8px 0; }
  </style>
</head>
<body>
  <h2>عمليات خصائص الكائن</h2>
  <div id="output"></div>
  <script>
    const product = { name: "لابتوب", price: 999 };
    const log = [];

    function showState(label) {
      log.push({ label, snapshot: JSON.stringify(product) });
    }

    showState("الحالة الأولية");
    product.price = 899;
    showState("تغيير السعر إلى 899");
    product.brand = "لينوفو";
    showState("إضافة خاصية العلامة التجارية");
    delete product.brand;
    showState("حذف خاصية العلامة التجارية");

    const output = document.getElementById("output");
    output.innerHTML = "<table><tr><th>الإجراء</th><th>حالة الكائن</th></tr>" +
      log.map(r => `<tr><td>${r.label}</td><td>${r.snapshot}</td></tr>`).join("") +
      "</table>";
  </script>
</body>
</html>
▶ جرّب الكود

مثال: المنشئات وObject.keys/values/entries

HTML
<!DOCTYPE html>
<html lang="ar">
<head>
  <meta charset="UTF-8">
  <title>المنشئات وطرق الكائنات</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    .section { margin: 16px 0; padding: 12px; background: #f9f9f9; border-radius: 6px; }
    .section h3 { margin-top: 0; color: #4a90d9; }
    ul { padding-left: 20px; }
    li { margin: 4px 0; }
  </style>
</head>
<body>
  <h2>المنشئات وطرق الكائنات الثابتة</h2>
  <div id="output"></div>
  <script>
    function Phone(brand, model, price) {
      this.brand = brand;
      this.model = model;
      this.price = price;
      this.showInfo = function() {
        return `${this.brand} ${this.model} — $${this.price}`;
      };
    }

    const p1 = new Phone("سامسونج", "Galaxy S24", 899);
    const p2 = new Phone("آبل", "iPhone 15", 999);

    const keys = Object.keys(p1);
    const values = Object.values(p1);
    const entries = Object.entries(p1);

    document.getElementById("output").innerHTML = `
      <div class="section">
        <h3>كائنات أُنشئت بالمنشئ</h3>
        <p>${p1.showInfo()}</p>
        <p>${p2.showInfo()}</p>
      </div>
      <div class="section">
        <h3>Object.keys(p1)</h3>
        <ul>${keys.map(k => `<li>${k}</li>`).join("")}</ul>
      </div>
      <div class="section">
        <h3>Object.values(p1)</h3>
        <ul>${values.map(v => `<li>${v}</li>`).join("")}</ul>
      </div>
      <div class="section">
        <h3>Object.entries(p1)</h3>
        <ul>${entries.map(([k, v]) => `<li><code>${k}</code>: <code>${v}</code></li>`).join("")}</ul>
      </div>
    `;
  </script>
</body>
</html>
▶ جرّب الكود

📖 ملخص

  1. الكائنات هي أزواج مفتاح-قيمة، تُنشأ ببناء {}
  2. بنية النقطة obj.name لأنظف; بنية الأقواس obj["name"] للمفاتيح الديناميكية
  3. const يُقفل مرجع الكائن، وليس المحتوى — يمكنك تعديل الخصائص بحرية
  4. الأساليب هي دوال داخل كائنات; this تشير إلى الكائن الحالي
  5. المنشئات تُنشئ كائنات متعددة بنفس الهيكل; new يُنشئ كائنًا ويربط this
  6. Object.keys/values/entries تُرجع مصفوفات بالمفاتيح والقيم والأزواج — مثالية للتكرار

❓ أسئلة شائعة

س هل يمكنني تعديل خصائص كائن مُعلن بـ const؟
ج نعم. const يُقفل مرجع المتغير (يعني أنه يشير دائمًا إلى نفس الكائن)، وليس محتوى الكائن. يمكنك إضافة وتعديل وحذف الخصائص بحرية — لكن لا يمكنك إعادة التعيين بـ obj = {}.
س متى يجب استخدام بنية الأقواس بدلاً من بنية النقطة؟
ج عندما يحتوي اسم الخاصية على مسافات أو شرطات (مثل "home-city")، أو عندما يكون الاسم مخزنًا في متغير للوصول الديناميكي، يجب استخدام الأقواس. لكل شيء آخر، بنية النقطة أنظف ومفضلة.
س ماذا يحدث إذا نسيت new مع منشئ؟
ج this ست指向 إلى الكائن العالمي (أو undefined في الوضع الصارم)، مما يتسبب في هبوط الخصائص في مكان خاطئ أو إلقاء خطأ. هذا فخ كلاسيكي — بنية class في ES6 تتعامل مع هذا تلقائيًا.

📝 تمارين

  1. أنشئ كائن book بخصائص title وauthor وyear، بالإضافة إلى أسلوب getSummary() يُرجع نصًا مثل "title بقلم author، نُشر في year".
  2. اكتب منشئ Car(brand, model, year)، استخدمه لإنشاء 3 سيارات، ثم استخدم Object.keys لسرد جميع أسماء خصائص سيارة واحدة.
  3. أضف أسلوب drive() ديناميكيًا إلى أي من السيارات أعلاه (يُرجع "brand model يقود")، ثم استدعِه. لاحظ كيف this تشير إلى الكائن الحالي داخل الأسلوب.
100%