صفوف

قدّمت ES6 مفهوم "الصفوف" في JavaScript، وهو ما يختلف عن دروسًا في لغات البرمجة الأخرى. هنا، الفئات هي دوال خاصة تعمل كنماذج لإنشاء عناصر تحتوي على بيانات وخصائص المرتبطة بتلك البيانات، والطرق المتعلقة بمعالجة تلك البيانات. ويطلق على هذه الكائنات والخصائص والأساليب مجتمعة اسم "الأعضاء" من الصف.

لتحديد فئة، استخدِم الكلمة الرئيسية class. يعد اتباع أفضل الممارسات التي تم إنشاؤها بواسطة دوال الدالة الإنشائية المضمنة في JavaScript، ابدأ أي معرِّف فئة بحرف كبير:

class MyClass {}

وتهدف الصفوف إلى توفير طرق أكثر سهولة للتعامل مع المستويات المتقدمة ميزات النماذج الأولية ودوال الإنشاء:

class MyClass {}

typeof MyClass;
> "function"

وذلك لأنّه تمت إضافة صفوف جزئيًا لتسهيل العمل على JavaScript المتقدّم ميزات أسهل وأكثر جاذبية، يُشار إليها أحيانًا باسم "السكر تركيبي" ومع ذلك، فإن الفصول الدراسية تفعل أكثر من مجرد تقديم اختصار مفيد للعمل مع التوريث النموذجي. إن تقديم بناء الجملة للصف خلق فرصًا لمعالجة التصميم الطويل المشكلات في JavaScript دون مواجهة مشكلات التوافق مع الأنظمة القديمة. كواحد سبيل المثال، يتم دائمًا تقييم جميع التعليمات البرمجية داخل نص الفئة الوضع المتشدد.

لإنشاء مثيل من فئة معيّنة، استخدِم عامل التشغيل new.

class MyClass {}

const myClassInstance = new MyClass();

myClassInstance
;
> Object { }

تتعرض الدوال المحددة داخل نص أي فئة كطرق لكل مثال لهذه الفئة.

class MyClass {
    classMethod
() {
        console
.log( "My class method." );
   
}
}

const myClassInstance = new MyClass();

myClassInstance
.classMethod();
> "My class method."

تصبح الطريقة المحددة داخل فئة معينة طريقة على النموذج الأولي المثيل الناتج. نظرًا لطبيعة سلسلة نموذج أولي، يمكنك استدعاء هذه الطرق مباشرة على الكائن الناتج:

class MyClass {
  classMethod
() {
    console
.log( "My class method." );
 
}
}

const myClassInstance = new MyClass( "A string." );

myClassInstance
;
> Object { }
   
<prototype>: Object { }
        classMethod
: function classMethod()
        constructor
: class MyClass { constructor(myPassedValue) }
       
<prototype>: Object { }

myClassInstance
.classMethod();
> "My class method."

يستدعي إنشاء مثيل لفئة طريقة constructor() خاصة تجري أي "إعداد" ضروري للمثيل الذي تم إنشاؤه حديثًا ويتم إعداده وأي خصائص مرتبطة به. أي وسيطات يتم تمريرها إلى الفئة عند يتم إنشاء المثيل بالطريقة constructor():

class MyClass {
  constructor
( myPassedValue ) {
    console
.log( myPassedValue );
 
}
}

const myClassInstance = new MyClass( "A string." );
> "A string."

في نص إحدى الفئات، تشير قيمة this إلى المثيل نفسه، مع عرض أي سمات محدّدة في this كسمات لكل مثيل تلك الفئة:

class MyClass {
  constructor
( myPassedValue ) {
   
this.instanceProperty = myPassedValue;
 
}
}

const myClassInstance = new MyClass( "A string." );

myClassInstance
;
> Object { instanceProperty: "A string." }

وتتوفّر هذه السمات أيضًا لجميع الطرق ضمن نص الفئة:

class MyClass {
  constructor
( myPassedValue ) {
   
this.instanceProp = myPassedValue;
 
}
  myMethod
() {
    console
.log( this.instanceProp );
 
}
}

const myClassInstance = new MyClass( "A string." );

myClassInstance
.myMethod();
> "A string."

إذا لم تحدّد constructor() لصفك الدراسي، سيستخدم محرك JavaScript "تلقائيًا" فارغًا constructor يمكن لكل صف أن يكون له طابع خاص واحد فقط طريقة اسمها constructor():

class MyClass {
  constructor
() {}
  constructor
() {}
}
> Uncaught SyntaxError: A class may only have one constructor

يمكنك تحديد أي فئة باستخدام إما بيان الفئة أو تعبير الفئة. كانت كل الأمثلة السابقة عبارة عن تصريحات فئوية، والتي تتطلب استدعاء الأسماء باستخدام new. يمكن تسمية تعبيرات الفئة أو تُترك بدون اسم لإنشاء "مجهول" الصف.

let ClassExpression = class {
    constructor
() {}
};

ClassExpression;
> class  {}

أحد الأشياء التي يمكنك استخدام تعبيرات الفئة المجهولة له هو الدوال التي إنشاء الفئات "سريعًا":

function classMaker() {
 
return class {
    constructor
() {}
 
};
}

let
MyVariable = classMaker();

MyVariable;
> class  {}

تؤدي إعادة تعريف فئة باستخدام تعريف الفئة إلى حدوث خطأ في البنية:


class MyClass {
    constructor
( ) {
        console
.log( "My class." );
   
}
};

class MyClass {
    constructor
() {
        console
.log( "My new class." );
   
}
};
> Uncaught SyntaxError: redeclaration of class MyClass

مع ذلك، تتيح لك تعبيرات الفئة إعادة تحديد فئة:

let ClassExpression = class MyClass { };

ClassExpression = class MyOtherClass {
    constructor
( myString ) {
       
this.myProp = myString;
   
}
};

new ClassExpression( "String." );
> MyOtherClass {myProp: 'String.'}

لا يمكنك استدعاء تعبير فئة مسماة بالاسم بالطريقة التي يمكنك بها استدعاء فئة . ومع ذلك، يتاح الاسم المعين لتعبير الفئة باعتباره المثيل الذي تم إنشاؤه، لتسهيل تصحيح الأخطاء:

let MyVariable = class MyClass {};

MyClass;
> Uncaught ReferenceError: MyClass is not defined

MyVariable;
> class MyClass {}

MyVariable.name;
> "MyClass"

عند تهيئة متغير باستخدام تعبير فئة، قواعد الرفع اتباع هذا المتغير كما هو متوقع. تتبع إعلانات الصفوف "المنطقة الثابتة المؤقتة" ذاتها القاعدتين مثل let وconst، والتصرف كما لو لم يتم رفعها إلى قمة نطاقها الحالي، مما يعني أن استدعاء فئة قبل تعريف الفئة يتسبب في حدوث خطأ:

{
    let myVar
= new MyClass( "Property string." );

   
class MyClass {
        myProp
;

        constructor
( myString ) {
           
this.myProp = myString;
       
}
   
};
};
> Uncaught ReferenceError: Cannot access 'MyClass' before initialization

التحقق من فهمك

أي مما يلي يحدد الفئة بشكل صحيح؟

myClass = class {}
new class()
class MyClass {}

كم عدد طرق constructor() التي يمكن أن تتضمّنها إحدى الفئات؟

واحد
غير محدودة
لا ينطبق