From d3cf00f28b2e5937d73c3e70bc2b91e8ae14372a Mon Sep 17 00:00:00 2001 From: salah elhossiny Date: Sat, 30 May 2020 22:00:28 +0200 Subject: [PATCH 1/2] Class basic syntax --- .../01-class/1-rewrite-to-class/task.md | 8 +- 1-js/09-classes/01-class/article.md | 162 +++++++++--------- 2 files changed, 85 insertions(+), 85 deletions(-) diff --git a/1-js/09-classes/01-class/1-rewrite-to-class/task.md b/1-js/09-classes/01-class/1-rewrite-to-class/task.md index 05365e410..0e400362b 100644 --- a/1-js/09-classes/01-class/1-rewrite-to-class/task.md +++ b/1-js/09-classes/01-class/1-rewrite-to-class/task.md @@ -1,9 +1,9 @@ -importance: 5 +درجة الأهمية : 5 --- -# Rewrite to class +# أعد صياغة الclass -The `Clock` class is written in functional style. Rewrite it the "class" syntax. +The `Clock` class مكتوب بأسلوب وظيفي. أعد كتابتها بصيغة "class". -P.S. The clock ticks in the console, open it to see. +ملاحظة. تدق الساعة في وحدة التحكم ، افتحها لترى. \ No newline at end of file diff --git a/1-js/09-classes/01-class/article.md b/1-js/09-classes/01-class/article.md index 672d40215..6287fca08 100644 --- a/1-js/09-classes/01-class/article.md +++ b/1-js/09-classes/01-class/article.md @@ -1,19 +1,19 @@ -# Class basic syntax +# الصيغة الأساسية للClass ```quote author="Wikipedia" -In object-oriented programming, a *class* is an extensible program-code-template for creating objects, providing initial values for state (member variables) and implementations of behavior (member functions or methods). +في البرمجة الموجهة للكائنات ، * الفئة * عبارة عن قالب رمز برنامج قابل للتوسيع لإنشاء الكائنات ، ويوفر القيم الأولية للحالة (متغيرات الأعضاء) وتنفيذ السلوك (وظائف الأعضاء أو الأساليب). ``` -In practice, we often need to create many objects of the same kind, like users, or goods or whatever. +من الناحية العملية ، نحتاج غالبًا إلى إنشاء العديد من العناصر من نفس النوع ، مثل المستخدمين أو السلع أو أيا كان. -As we already know from the chapter , `new function` can help with that. +كما نعلم بالفعل من الفصل ، يمكن أن تساعد `الوظيفة الجديدة` في ذلك. -But in the modern JavaScript, there's a more advanced "class" construct, that introduces great new features which are useful for object-oriented programming. +ولكن في جافا سكريبت الحديثة ، هناك بنية "صنف" أكثر تقدمًا ، تقدم ميزات جديدة رائعة مفيدة للبرمجة الموجهة للكائنات. -## The "class" syntax +# الصيغة الأساسية للClass -The basic syntax is: +الصيغة الأساسية هي: ```js class MyClass { // class methods @@ -25,11 +25,11 @@ class MyClass { } ``` -Then use `new MyClass()` to create a new object with all the listed methods. +ثم استخدم `New MyClass ()` لإنشاء كائن جديد بكل الطرق المدرجة. -The `constructor()` method is called automatically by `new`, so we can initialize the object there. +يتم استدعاء طريقة `constructor ()` تلقائيًا بواسطة `new` ، حتى نتمكن من تهيئة الكائن هناك. -For example: +فمثلا: ```js run class User { @@ -49,28 +49,28 @@ let user = new User("John"); user.sayHi(); ``` -When `new User("John")` is called: -1. A new object is created. -2. The `constructor` runs with the given argument and assigns `this.name` to it. +عند استدعاء`new User("John")` : +1. يتم إنشاء كائن جديد. +2. يعمل "المُنشئ" مع الوسيطة المحددة ويعين "اسم هذا" إليه. -...Then we can call object methods, such as `user.sayHi()`. +... ثم يمكننا استدعاء طرق الكائن ، مثل `user.sayHi ()`. -```warn header="No comma between class methods" -A common pitfall for novice developers is to put a comma between class methods, which would result in a syntax error. +"` `warn header =" لا فاصلة بين طرق الفصل " +من المشاكل الشائعة للمطورين المبتدئين وضع فاصلة بين طرق الفصل ، مما يؤدي إلى خطأ في بناء الجملة. -The notation here is not to be confused with object literals. Within the class, no commas are required. -``` +لا يجب الخلط بين التدوين هنا وحرف الشيء. داخل الفصل الدراسي ، لا يلزم وجود فواصل. +`` -## What is a class? +## ما هي الclass ؟ -So, what exactly is a `class`? That's not an entirely new language-level entity, as one might think. +إذن ، ما هي "الطبقة" بالضبط؟ هذا ليس كيانًا جديدًا تمامًا على مستوى اللغة ، كما قد يعتقد المرء. -Let's unveil any magic and see what a class really is. That'll help in understanding many complex aspects. +دعونا نكشف عن أي سحر ونرى ما هو الصف حقا. سيساعد ذلك في فهم العديد من الجوانب المعقدة. -In JavaScript, a class is a kind of function. +في JavaScript ، الفئة هي نوع من الوظائف. -Here, take a look: +هنا ، ألق نظرة: ```js run class User { @@ -84,18 +84,18 @@ alert(typeof User); // function */!* ``` -What `class User {...}` construct really does is: +ما يفعله بناء `مستخدم الفئة {... }` حقًا هو: -1. Creates a function named `User`, that becomes the result of the class declaration. The function code is taken from the `constructor` method (assumed empty if we don't write such method). -2. Stores class methods, such as `sayHi`, in `User.prototype`. +1. إنشاء وظيفة باسم "المستخدم" ، والتي تصبح نتيجة لإعلان الفئة. يتم أخذ رمز الوظيفة من طريقة `المنشئ` (يفترض أنها فارغة إذا لم نكتب مثل هذه الطريقة). +2. يخزن طرق الفصل ، مثل `sayHi` ، في` User.prototype`. -After `new User` object is created, when we call its method, it's taken from the prototype, just as described in the chapter . So the object has access to class methods. +بعد إنشاء كائن "مستخدم جديد" ، عندما نسمي أسلوبه ، يتم أخذه من النموذج الأولي ، تمامًا كما هو موضح في الفصل . لذا فإن الكائن لديه حق الوصول إلى أساليب الفصل. -We can illustrate the result of `class User` declaration as: +يمكننا توضيح نتيجة إعلان "مستخدم الفئة" كما يلي: ![](class-user.svg) -Here's the code to introspect it: +إليك كود لتتفكر فيه: ```js run class User { @@ -116,9 +116,9 @@ alert(User.prototype.sayHi); // alert(this.name); alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi ``` -## Not just a syntactic sugar +## ليس مجرد سكر نحوي -Sometimes people say that `class` is a "syntactic sugar" (syntax that is designed to make things easier to read, but doesn't introduce anything new), because we could actually declare the same without `class` keyword at all: +أحيانًا يقول الناس أن "class" عبارة عن "سكر نحوي" (بنية تم تصميمها لتسهيل قراءة الأشياء ، ولكن لا تقدم أي شيء جديد) ، لأنه يمكننا في الواقع أن نعلن الشيء نفسه بدون كلمة "class" على الإطلاق: ```js run // rewriting class User in pure functions @@ -140,13 +140,13 @@ let user = new User("John"); user.sayHi(); ``` -The result of this definition is about the same. So, there are indeed reasons why `class` can be considered a syntactic sugar to define a constructor together with its prototype methods. +نتيجة هذا التعريف هي نفسها. لذا ، هناك بالفعل أسباب تجعل من الممكن اعتبار "class" سكرًا نحويًا لتحديد المنشئ مع طرق النموذج الأولي. -Still, there are important differences. +لا تزال هناك اختلافات مهمة. -1. First, a function created by `class` is labelled by a special internal property `[[FunctionKind]]:"classConstructor"`. So it's not entirely the same as creating it manually. +1. أولاً ، يتم تصنيف دالة تم إنشاؤها بواسطة "class" بواسطة خاصية داخلية خاصة `[[FunctionKind]]:" classConstructor "`. لذلك فهي ليست تمامًا مثل إنشائها يدويًا. - The language checks for that property in a variety of places. For example, unlike a regular function, it must be called with `new`: +     تقوم اللغة بالتحقق من هذه الخاصية في أماكن متنوعة. على سبيل المثال ، على عكس الوظيفة العادية ، يجب أن يتم استدعاؤها بـ `new`: ```js run class User { @@ -157,7 +157,7 @@ Still, there are important differences. User(); // Error: Class constructor User cannot be invoked without 'new' ``` - Also, a string representation of a class constructor in most JavaScript engines starts with the "class..." +أيضًا ، يبدأ تمثيل السلسلة لمنشئ فئة في معظم محركات JavaScript بـ "class ..." ```js run class User { @@ -166,24 +166,23 @@ Still, there are important differences. alert(User); // class User { ... } ``` - There are other differences, we'll see them soon. - -2. Class methods are non-enumerable. - A class definition sets `enumerable` flag to `false` for all methods in the `"prototype"`. + هناك اختلافات أخرى ، سنراها قريبًا. - That's good, because if we `for..in` over an object, we usually don't want its class methods. +2. دوال الclass لا تعد ولا تحصى. +     يقوم تعريف الفئة بتعيين علامة `enumerable` إلى` false` لجميع الطرق في "" prototype "`. -3. Classes always `use strict`. - All code inside the class construct is automatically in strict mode. +     هذا أمر جيد ، لأنه إذا كنا 'for..in` فوق كائن ما ، فإننا عادة لا نريد طرقه الطبقية. -Besides, `class` syntax brings many other features that we'll explore later. +3. الclasses دائمًا "استخدام صارم". +     تكون جميع التعليمات البرمجية داخل بنية الفصل تلقائيًا في وضع صارم. -## Class Expression +بالإضافة إلى ذلك ، فإن بناء جملة `class` يجلب العديد من الميزات الأخرى التي سنستكشفها لاحقًا. -Just like functions, classes can be defined inside another expression, passed around, returned, assigned, etc. +## تعبير الclass -Here's an example of a class expression: +تمامًا مثل functions ، يمكن تعريف الفئات داخل تعبير آخر ، وتمريرها ، وإعادتها ، وتعيينها ، وما إلى ذلك. +إليك مثالاً على تعبير class: ```js let User = class { sayHi() { @@ -192,9 +191,9 @@ let User = class { }; ``` -Similar to Named Function Expressions, class expressions may have a name. +على غرار تعبيرات الوظائف المسماة ، قد يكون لتعبيرات الفئة اسم. -If a class expression has a name, it's visible inside the class only: +إذا كان تعبير فئة له اسم ، فإنه يكون مرئيًا داخل الفصل فقط: ```js run // "Named Class Expression" @@ -210,7 +209,7 @@ new User().sayHi(); // works, shows MyClass definition alert(MyClass); // error, MyClass name isn't visible outside of the class ``` -We can even make classes dynamically "on-demand", like this: +يمكننا أيضًا أن نجعل classes ديناميكيًا "حسب الطلب" ، مثل هذا: ```js run function makeClass(phrase) { @@ -231,9 +230,9 @@ new User().sayHi(); // Hello ## Getters/setters -Just like literal objects, classes may include getters/setters, computed properties etc. +تمامًا مثل الأشياء الحرفية ، قد تتضمن الفئات الحروف / المستوطنين والخصائص المحسوبة وما إلى ذلك. -Here's an example for `user.name` implemented using `get/set`: +في ما يلي مثال لـ `user.name` تم تنفيذه باستخدام` get / set`: ```js run class User { @@ -267,11 +266,11 @@ alert(user.name); // John user = new User(""); // Name is too short. ``` -Technically, such class declaration works by creating getters and setters in `User.prototype`. +من الناحية الفنية ، يعمل إعلان الفئة هذا عن طريق إنشاء الحروف والمستوطنين في `User.prototype`. -## Computed names [...] +## الأسماء المحسوبة [...] -Here's an example with a computed method name using brackets `[...]`: +في ما يلي مثال باسم الطريقة المحسوبة باستخدام الأقواس `[...]`: ```js run class User { @@ -287,19 +286,19 @@ class User { new User().sayHi(); ``` -Such features are easy to remember, as they resemble that of literal objects. +من السهل تذكر هذه الميزات ، لأنها تشبه تلك الموجودة في الأشياء الحرفية. -## Class fields +## حقول class -```warn header="Old browsers may need a polyfill" -Class fields are a recent addition to the language. -``` +"` `warn header =" قد تحتاج المتصفحات القديمة إلى ملف متعدد " +تعد حقول الصف إضافة حديثة للغة. +`` -Previously, our classes only had methods. +في السابق ، كانت فصولنا تمتلك طرقًا فقط. -"Class fields" is a syntax that allows to add any properties. +"حقول class" هي بنية تسمح بإضافة أي خصائص. -For instance, let's add `name` property to `class User`: +على سبيل المثال ، دعنا نضيف خاصية `name` إلى` class User`: ```js run class User { @@ -315,9 +314,9 @@ class User { new User().sayHi(); // Hello, John! ``` -So, we just write " = " in the declaration, and that's it. +لذلك ، نكتب فقط "<اسم الخاصية> = <قيمة>" في الإعلان ، وهذا كل شيء. -The important difference of class fields is that they are set on individual objects, not `User.prototype`: +الاختلاف المهم في حقول الصف هو أنه يتم تعيينها على كائنات فردية ، وليس `User.prototype`: ```js run class User { @@ -331,7 +330,7 @@ alert(user.name); // John alert(User.prototype.name); // undefined ``` -Technically, they are processed after the constructor has done it's job, and we can use for them complex expressions and function calls: +من الناحية الفنية ، تتم معالجتها بعد أن يقوم المنشئ بعمله ، ويمكننا استخدامه بالنسبة لهم التعبيرات المعقدة واستدعاءات الوظائف: ```js run class User { @@ -344,13 +343,14 @@ let user = new User(); alert(user.name); // John ``` -### Making bound methods with class fields +### عمل طرق مرتبطة بحقول class + +كما هو موضح في الفصل ، فإن وظائف JavaScript لها ديناميكية `this`. يعتمد ذلك على سياق المكالمة. -As demonstrated in the chapter functions in JavaScript have a dynamic `this`. It depends on the context of the call. +لذلك إذا تم تمرير طريقة كائن واستدعاؤها في سياق آخر ، فلن يكون `هذا` مرجعاً إلى كائنه بعد الآن. -So if an object method is passed around and called in another context, `this` won't be a reference to its object any more. +على سبيل المثال ، سيُظهر هذا الرمز `undefined`: -For instance, this code will show `undefined`: ```js run class Button { @@ -370,12 +370,12 @@ setTimeout(button.click, 1000); // undefined */!* ``` -The problem is called "losing `this`". +تسمى المشكلة "فقدان" this "". -There are two approaches to fixing it, as discussed in the chapter : +هناك طريقتان لإصلاحها ، كما هو موضح في الفصل : -1. Pass a wrapper-function, such as `setTimeout(() => button.click(), 1000)`. -2. Bind the method to object, e.g. in the constructor: +1. قم بتمرير دالة مجمعة ، مثل `setTimeout (() => button.click ()، 1000)`. +2. ربط طريقة الاعتراض ، على سبيل المثال في المنشئ: ```js run class Button { @@ -398,7 +398,7 @@ setTimeout(button.click, 1000); // hello */!* ``` -Class fields provide a more elegant syntax for the latter solution: +توفر حقول class بنية أكثر أناقة للحل الأخير: ```js run class Button { @@ -417,13 +417,13 @@ let button = new Button("hello"); setTimeout(button.click, 1000); // hello ``` -The class field `click = () => {...}` creates an independent function on each `Button` object, with `this` bound to the object. Then we can pass `button.click` around anywhere, and it will be called with the right `this`. +ينشئ حقل الفئة `click = () => {...}` وظيفة مستقلة على كل كائن `Button` ، مع` this` مرتبطًا بالكائن. ثم يمكننا تمرير "button.click" في أي مكان ، وسيتم استدعاؤها باستخدام `this` الصحيح. -That's especially useful in browser environment, when we need to setup a method as an event listener. +هذا مفيد بشكل خاص في بيئة المتصفح ، عندما نحتاج إلى إعداد طريقة كمستمع للأحداث. -## Summary +## ملخص -The basic class syntax looks like this: +تبدو بنية الصف الأساسية كما يلي: ```js class MyClass { @@ -443,6 +443,6 @@ class MyClass { } ``` -`MyClass` is technically a function (the one that we provide as `constructor`), while methods, getters and setters are written to `MyClass.prototype`. +`MyClass` هي وظيفة من الناحية الفنية (تلك التي نقدمها على أنها `مُنشئ`) ، بينما تتم كتابة الأساليب والرسومات والمستوطنين على` MyClass.prototype`. -In the next chapters we'll learn more about classes, including inheritance and other features. +في الفصول التالية سنتعلم المزيد عن الفصول ، بما في ذلك الميراث والميزات الأخرى. From 47109d586185de351a6626f8fec483fe51dba3d5 Mon Sep 17 00:00:00 2001 From: salah elhossiny Date: Sun, 31 May 2020 08:52:02 +0200 Subject: [PATCH 2/2] Class inheritance --- .../1-class-constructor-error/solution.md | 4 +- .../1-class-constructor-error/task.md | 8 +- .../2-clock-class-extended/task.md | 14 +- .../3-class-extend-object/solution.md | 32 +-- .../3-class-extend-object/task.md | 14 +- .../02-class-inheritance/article.md | 215 +++++++++--------- 6 files changed, 145 insertions(+), 142 deletions(-) diff --git a/1-js/09-classes/02-class-inheritance/1-class-constructor-error/solution.md b/1-js/09-classes/02-class-inheritance/1-class-constructor-error/solution.md index 4711e4827..802a0ab58 100644 --- a/1-js/09-classes/02-class-inheritance/1-class-constructor-error/solution.md +++ b/1-js/09-classes/02-class-inheritance/1-class-constructor-error/solution.md @@ -1,6 +1,6 @@ -That's because the child constructor must call `super()`. +هذا لأنه يجب على منشئ الطفل استدعاء `` super () `. -Here's the corrected code: +إليك الكود المصحح: ```js run class Animal { diff --git a/1-js/09-classes/02-class-inheritance/1-class-constructor-error/task.md b/1-js/09-classes/02-class-inheritance/1-class-constructor-error/task.md index 380a4720b..0cf6eb309 100644 --- a/1-js/09-classes/02-class-inheritance/1-class-constructor-error/task.md +++ b/1-js/09-classes/02-class-inheritance/1-class-constructor-error/task.md @@ -1,12 +1,12 @@ -importance: 5 +درجة الأهمية : 5 --- -# Error creating an instance +# خطأ في إنشاء مثيل -Here's the code with `Rabbit` extending `Animal`. +إليك الرمز الذي يحتوي على "أرنب" يمتد "حيوان". -Unfortunately, `Rabbit` objects can't be created. What's wrong? Fix it. +لسوء الحظ ، لا يمكن إنشاء كائنات "أرنب". ماالخطب؟ اصلحه. ```js run class Animal { diff --git a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/task.md b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/task.md index bbc2c6a43..4828d7b29 100644 --- a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/task.md +++ b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/task.md @@ -1,15 +1,15 @@ -importance: 5 +درجة الأهمية: 5 --- -# Extended clock +# ساعة ممتدة -We've got a `Clock` class. As of now, it prints the time every second. +لدينا فصل "ساعة". حتى الآن ، يطبع الوقت كل ثانية. -[js src="source.view/clock.js"] +[js src = "source.view / clock.js"] -Create a new class `ExtendedClock` that inherits from `Clock` and adds the parameter `precision` -- the number of `ms` between "ticks". Should be `1000` (1 second) by default. +أنشئ فئة جديدة `ExtendedClock` ترث من` Clock` وتضيف المعلمة `الدقة` - عدد` ms` بين "القراد". يجب أن يكون "1000" (ثانية واحدة) افتراضيًا. -- Your code should be in the file `extended-clock.js` -- Don't modify the original `clock.js`. Extend it. +- يجب أن يكون الكود الخاص بك في ملف `ممتد على مدار الساعة. js` +- لا تعدّل "clock.js" الأصلي. توسيعها. \ No newline at end of file diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md b/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md index ca9e80601..8109bb549 100644 --- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md +++ b/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md @@ -1,8 +1,8 @@ -First, let's see why the latter code doesn't work. +أولاً ، دعنا نرى لماذا لا يعمل الكود الأخير. -The reason becomes obvious if we try to run it. An inheriting class constructor must call `super()`. Otherwise `"this"` won't be "defined". +يصبح السبب واضحًا إذا حاولنا تشغيله. يجب على مُنشئ الفصل الموروث استدعاء `` super () `. وإلا فلن يتم تحديد "هذا" ". -So here's the fix: +إذن هذا هو الإصلاح: ```js run class Rabbit extends Object { @@ -19,16 +19,16 @@ let rabbit = new Rabbit("Rab"); alert( rabbit.hasOwnProperty('name') ); // true ``` -But that's not all yet. +لكن هذا ليس كل شيء بعد. -Even after the fix, there's still important difference in `"class Rabbit extends Object"` versus `class Rabbit`. +حتى بعد الإصلاح ، لا يزال هناك اختلاف مهم في "class rabbit يوسع الكائن" "مقابل" class Rabbit ". -As we know, the "extends" syntax sets up two prototypes: +كما نعلم ، فإن الصيغة "الممتدة" تضع نموذجين أوليين: -1. Between `"prototype"` of the constructor functions (for methods). -2. Between the constructor functions themselves (for static methods). +1. بين "النموذج" لوظائف المنشئ (للطرق). +2. بين وظائف المنشئ أنفسهم (للأساليب الثابتة). -In our case, for `class Rabbit extends Object` it means: +في حالتنا ، تعني كلمة "أرنب يمتد الكائن" ما يلي: ```js run class Rabbit extends Object {} @@ -37,7 +37,7 @@ alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true alert( Rabbit.__proto__ === Object ); // (2) true ``` -So `Rabbit` now provides access to static methods of `Object` via `Rabbit`, like this: +إذن يوفر "الأرنب" الآن إمكانية الوصول إلى الأساليب الثابتة لـ "الكائن" عبر "الأرنب" ، على النحو التالي: ```js run class Rabbit extends Object {} @@ -48,9 +48,9 @@ alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // a,b */!* ``` -But if we don't have `extends Object`, then `Rabbit.__proto__` is not set to `Object`. +ولكن إذا لم يكن لدينا `Extended Object` ، فلن يتم تعيين` Rabbit .__ proto__` على `Object`. -Here's the demo: +هنا هو العرض التوضيحي: ```js run class Rabbit {} @@ -65,15 +65,15 @@ alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error */!* ``` -So `Rabbit` doesn't provide access to static methods of `Object` in that case. +لذا `Rabbit` لا يوفر الوصول إلى الأساليب الثابتة لـ "الكائن" في هذه الحالة. -By the way, `Function.prototype` has "generic" function methods, like `call`, `bind` etc. They are ultimately available in both cases, because for the built-in `Object` constructor, `Object.__proto__ === Function.prototype`. +بالمناسبة ، يحتوي `Function.prototype` على طرق وظيفية" عامة "، مثل` call` و` bind` وما إلى ذلك. وهي متاحة في النهاية في كلتا الحالتين ، لأن مُنشئ `Object` المدمج ،` Object .__ proto__ = == Function.prototype`. -Here's the picture: +ها هي الصورة: ![](rabbit-extends-object.svg) -So, to put it short, there are two differences: +لذلك ، باختصار ، هناك اختلافان: | class Rabbit | class Rabbit extends Object | |--------------|------------------------------| diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md b/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md index 1d0f98a74..d0fa92423 100644 --- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md +++ b/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md @@ -1,12 +1,12 @@ -importance: 3 +درجة الأهمية: 3 --- -# Class extends Object? +# فئة تمدد الكائن؟ -As we know, all objects normally inherit from `Object.prototype` and get access to "generic" object methods like `hasOwnProperty` etc. +كما نعلم ، عادة ما ترث جميع الكائنات من `Object.prototype` وتحصل على طرق للكائنات" العامة "مثل` hasOwnProperty` وما إلى ذلك. -For instance: +على سبيل المثال: ```js run class Rabbit { @@ -23,11 +23,11 @@ alert( rabbit.hasOwnProperty('name') ); // true */!* ``` -But if we spell it out explicitly like `"class Rabbit extends Object"`, then the result would be different from a simple `"class Rabbit"`? +ولكن إذا وضحناها صراحة مثل "class class rabbit Extended Object" ، فستكون النتيجة مختلفة عن "class rabbit" بسيطة؟ -What's the difference? +ماهو الفرق؟ -Here's an example of such code (it doesn't work -- why? fix it?): +فيما يلي مثال لمثل هذا الرمز (لا يعمل - لماذا؟ إصلاحه؟): ```js class Rabbit extends Object { diff --git a/1-js/09-classes/02-class-inheritance/article.md b/1-js/09-classes/02-class-inheritance/article.md index 3d3c145eb..3bf496fcf 100644 --- a/1-js/09-classes/02-class-inheritance/article.md +++ b/1-js/09-classes/02-class-inheritance/article.md @@ -1,13 +1,13 @@ -# Class inheritance +# Class توريث ال -Class inheritance is a way for one class to extend another class. +توريث الclass هو وسيلة لفئة واحدة لتمديد فئة أخرى. -So we can create new functionality on top of the existing. +حتى نتمكن من إنشاء وظائف جديدة على رأس القائمة. -## The "extends" keyword +## الكلمة الرئيسية "يمتد" -Let's say we have class `Animal`: +لنفترض أن لدينا فئة `Animal`: ```js class Animal { @@ -28,17 +28,17 @@ class Animal { let animal = new Animal("My animal"); ``` -Here's how we can represent `animal` object and `Animal` class graphically: +إليك كيفية تمثيل كائن "الحيوان" وفئة "الحيوان" بشكل رسومي: ![](rabbit-animal-independent-animal.svg) -...And we would like to create another `class Rabbit`. +... ونود إنشاء "أرنب من الدرجة" آخر. -As rabbits are animals, `Rabbit` class should be based on `Animal`, have access to animal methods, so that rabbits can do what "generic" animals can do. +نظرًا لأن الأرانب حيوانات ، يجب أن تستند فئة "الأرانب" إلى "الحيوانات" ، وأن تكون قادرة على الوصول إلى الأساليب الحيوانية ، حتى تتمكن الأرانب من القيام بما يمكن أن تفعله الحيوانات "العامة". -The syntax to extend another class is: `class Child extends Parent`. +بناء الجملة لتمديد فئة أخرى هو: `class child Extended Parent`. -Let's create `class Rabbit` that inherits from `Animal`: +لنقم بإنشاء "أرنب الطبقة" الذي يرث من "الحيوان": ```js *!* @@ -55,23 +55,23 @@ rabbit.run(5); // White Rabbit runs with speed 5. rabbit.hide(); // White Rabbit hides! ``` -Object of `Rabbit` class have access to both `Rabbit` methods, such as `rabbit.hide()`, and also to `Animal` methods, such as `rabbit.run()`. +يمكن لكائن فئة "أرنب" الوصول إلى كل من طرق "أرنب" ، مثل "أرنب. إخفاء ()" ، وأيضًا إلى طرق "الحيوان" ، مثل "أرنب". () `. -Internally, `extends` keyword works using the good old prototype mechanics. It sets `Rabbit.prototype.[[Prototype]]` to `Animal.prototype`. So, if a method is not found in `Rabbit.prototype`, JavaScript takes it from `Animal.prototype`. +داخليًا ، تعمل الكلمة الرئيسية `` الموسعة '' باستخدام ميكانيكا النموذج القديم الجيدة. يقوم بتعيين "Rabbit.prototype. [[Prototype]]` إلى "Animal.prototype`. لذلك ، إذا لم يتم العثور على طريقة في `Rabbit.prototype` ، فإن JavaScript تأخذها من` Animal.prototype`. ![](animal-rabbit-extends.svg) -For instance, to find `rabbit.run` method, the engine checks (bottom-up on the picture): -1. The `rabbit` object (has no `run`). -2. Its prototype, that is `Rabbit.prototype` (has `hide`, but not `run`). -3. Its prototype, that is (due to `extends`) `Animal.prototype`, that finally has the `run` method. +على سبيل المثال ، للعثور على طريقة `rabbit.run` ، يتحقق المحرك (من أسفل إلى أعلى في الصورة): +1. كائن "الأرنب" (ليس له "تشغيل"). +2. نموذجها الأولي ، وهو "Rabbit.prototype" (به "إخفاء" وليس "تشغيل"). +3. نموذجها الأولي ، أي (بسبب "يمتد") "Animal.prototype" ، الذي يحتوي في النهاية على طريقة "run". -As we can recall from the chapter , JavaScript itself uses prototypal inheritance for built-in objects. E.g. `Date.prototype.[[Prototype]]` is `Object.prototype`. That's why dates have access to generic object methods. +كما يمكننا أن نتذكر من الفصل ، فإن JavaScript نفسها تستخدم الوراثة النموذجية للكائنات المدمجة. على سبيل المثال `Date.prototype. [[Prototype]]` هو `Object.prototype`. هذا هو السبب في أن التواريخ يمكنها الوصول إلى طرق الكائنات العامة. -````smart header="Any expression is allowed after `extends`" -Class syntax allows to specify not just a class, but any expression after `extends`. +````smart header="يسمح بأي تعبير بعد "يمتد" +يسمح بناء جملة الصنف بتحديد ليس فئة فقط ، ولكن أي تعبير بعد "يمتد". -For instance, a function call that generates the parent class: +على سبيل المثال ، استدعاء دالة ينشئ الفئة الأصل: ```js run function f(phrase) { @@ -86,16 +86,16 @@ class User extends f("Hello") {} new User().sayHi(); // Hello ``` -Here `class User` inherits from the result of `f("Hello")`. +هنا يرث `مستخدم class` من نتيجة` f ("Hello") `. -That may be useful for advanced programming patterns when we use functions to generate classes depending on many conditions and can inherit from them. +قد يكون ذلك مفيدًا لأنماط البرمجة المتقدمة عندما نستخدم الدالات لإنشاء فئات اعتمادًا على العديد من الشروط ويمكن أن ترثها. ```` -## Overriding a method +## تجاوز دالة -Now let's move forward and override a method. By default, all methods that are not specified in `class Rabbit` are taken directly "as is" from `class Animal`. +الآن دعنا نمضي قدمًا ونستبدل إحدى الطرق. افتراضيًا ، يتم أخذ جميع الطرق غير المحددة في "class Rabbit" مباشرةً "كما هي" من "class Animal`. -But if we specify our own method in `Rabbit`, such as `stop()` then it will be used instead: +ولكن إذا حددنا طريقتنا الخاصة في "أرنب" ، مثل `stop ()` ، فسيتم استخدامها بدلاً من ذلك: ```js class Rabbit extends Animal { @@ -106,14 +106,14 @@ class Rabbit extends Animal { } ``` -Usually we don't want to totally replace a parent method, but rather to build on top of it to tweak or extend its functionality. We do something in our method, but call the parent method before/after it or in the process. +عادة لا نريد استبدال طريقة رئيسية تمامًا ، ولكن بدلاً من ذلك نبني عليها لاستبدالها أو توسيع وظائفها. نفعل شيئًا في طريقتنا ، ولكن استدعاء الطريقة الأم قبل / بعدها أو في العملية. -Classes provide `"super"` keyword for that. +توفر الفصول كلمة رئيسية `` فائقة '' لذلك. -- `super.method(...)` to call a parent method. -- `super(...)` to call a parent constructor (inside our constructor only). +- `super.method (...)` لاستدعاء طريقة أصل. +- `` super (...) `لاستدعاء مُنشئ أصل (داخل مُنشئنا فقط). -For instance, let our rabbit autohide when stopped: +على سبيل المثال ، دع أرنبا يختبئ تلقائيًا عندما يتوقف: ```js run class Animal { @@ -154,12 +154,13 @@ rabbit.run(5); // White Rabbit runs with speed 5. rabbit.stop(); // White Rabbit stands still. White rabbit hides! ``` -Now `Rabbit` has the `stop` method that calls the parent `super.stop()` in the process. +الآن يحتوي "الأرنب" على طريقة "الإيقاف" التي تستدعي الأصل `super.stop ()` في العملية. -````smart header="Arrow functions have no `super`" -As was mentioned in the chapter , arrow functions do not have `super`. +````smart header="وظائف السهم ليس لها" سوبر " +كما ذكر في الفصل ، فإن دالات الأسهم لا تحتوي على `super`. + +إذا تم الوصول إليه ، فهو مأخوذ من الوظيفة الخارجية. على سبيل المثال: -If accessed, it's taken from the outer function. For instance: ```js class Rabbit extends Animal { stop() { @@ -168,7 +169,7 @@ class Rabbit extends Animal { } ``` -The `super` in the arrow function is the same as in `stop()`, so it works as intended. If we specified a "regular" function here, there would be an error: +وظيفة `super` في وظيفة السهم هي نفسها في` stop () `، لذا فهي تعمل على النحو المنشود. إذا حددنا وظيفة "عادية" هنا ، فسيكون هناك خطأ: ```js // Unexpected super @@ -177,13 +178,13 @@ setTimeout(function() { super.stop() }, 1000); ```` -## Overriding constructor +## تجاوز constructor -With constructors it gets a little bit tricky. +مع المنشئين يصبح الأمر صعبًا بعض الشيء. -Until now, `Rabbit` did not have its own `constructor`. +حتى الآن ، لم يكن لدى "الأرنب" "مُنشئ" خاص به. -According to the [specification](https://tc39.github.io/ecma262/#sec-runtime-semantics-classdefinitionevaluation), if a class extends another class and has no `constructor`, then the following "empty" `constructor` is generated: +وفقًا لـ [المواصفات] (https://tc39.github.io/ecma262/#sec-runtime-semantics-classdefinitionevaluation) ، إذا كان الفصل يمتد إلى فصل آخر ولا يحتوي على "مُنشئ" ، فإن المُنشئ التالي "الفارغ" التالي `يتم إنشاء: ```js class Rabbit extends Animal { @@ -196,9 +197,10 @@ class Rabbit extends Animal { } ``` -As we can see, it basically calls the parent `constructor` passing it all the arguments. That happens if we don't write a constructor of our own. +كما نرى ، فإنه يطلق بشكل أساسي على `المنشئ` الأصل ويمررها جميع الحجج. يحدث هذا إذا لم نكتب مُنشئًا خاصًا بنا. + +الآن دعنا نضيف مُنشئًا مخصصًا لـ "أرنب". ستحدد "طول الأذن" بالإضافة إلى "الاسم": -Now let's add a custom constructor to `Rabbit`. It will specify the `earLength` in addition to `name`: ```js run class Animal { @@ -228,24 +230,24 @@ let rabbit = new Rabbit("White Rabbit", 10); // Error: this is not defined. */!* ``` -Whoops! We've got an error. Now we can't create rabbits. What went wrong? +عفوًا! لدينا خطأ. الآن لا يمكننا إنشاء الأرانب. ماذا حصل؟ -The short answer is: constructors in inheriting classes must call `super(...)`, and (!) do it before using `this`. +الإجابة المختصرة هي: يجب على منشئو الفصول الموروثة استدعاء `super (...)` و (!) قبل ذلك باستخدام `this`. -...But why? What's going on here? Indeed, the requirement seems strange. +...لكن لماذا؟ ماذا يجري هنا؟ في الواقع ، يبدو الشرط غريبًا. -Of course, there's an explanation. Let's get into details, so you'll really understand what's going on. +بالطبع ، هناك تفسير. دعنا ندخل في التفاصيل ، حتى تفهم حقًا ما يحدث. -In JavaScript, there's a distinction between a constructor function of an inheriting class (so-called "derived constructor") and other functions. A derived constructor has a special internal property `[[ConstructorKind]]:"derived"`. That's a special internal label. +في جافا سكريبت ، هناك تمييز بين دالة المُنشئ لفئة وراثية (ما يسمى "مُنشئ مُشتق") ووظائف أخرى. لدى المنشئ المشتق خاصية داخلية خاصة `[[ConstructorKind]]:" مشتق "". هذا تسمية داخلية خاصة. -That label affects its behavior with `new`. +يؤثر هذا التصنيف على سلوكه بـ "جديد". -- When a regular function is executed with `new`, it creates an empty object and assigns it to `this`. -- But when a derived constructor runs, it doesn't do this. It expects the parent constructor to do this job. +- عندما يتم تنفيذ وظيفة عادية باستخدام `new` ، فإنها تنشئ كائنًا فارغًا وتعينه بـ` this`. +- ولكن عندما يعمل منشئ مشتق ، فإنه لا يفعل ذلك. وتتوقع من المُنشئ الأصلي أن يقوم بهذه المهمة. -So a derived constructor must call `super` in order to execute its parent (non-derived) constructor, otherwise the object for `this` won't be created. And we'll get an error. +لذا يجب على المُنشئ المشتق استدعاء `super` من أجل تنفيذ مُنشئه الأصلي (غير المُشتق) ، وإلا فلن يتم إنشاء كائن` this`. وسنحصل على خطأ. -For the `Rabbit` constructor to work, it needs to call `super()` before using `this`, like here: +لكي يعمل مُنشئ "الأرنب" ، يجب الاتصال بـ "super ()` قبل استخدام `this` ، كما يلي: ```js run class Animal { @@ -279,27 +281,28 @@ alert(rabbit.earLength); // 10 ``` -## Super: internals, [[HomeObject]] +## Super: الأجزاء الداخلية ، [[HomeObject]] -```warn header="Advanced information" -If you're reading the tutorial for the first time - this section may be skipped. +```warn header="معلومات متقدمة" +إذا كنت تقرأ البرنامج التعليمي لأول مرة - فقد يتم تخطي هذا القسم. -It's about the internal mechanisms behind inheritance and `super`. -``` +إنه يتعلق بالآليات الداخلية الكامنة وراء الميراث و "السوبر". +`` + +دعونا نتعمق قليلاً تحت غطاء "السوبر". سنرى بعض الأشياء المثيرة للاهتمام على طول الطريق. -Let's get a little deeper under the hood of `super`. We'll see some interesting things along the way. +بادئ ذي بدء ، من كل ما تعلمناه حتى الآن ، من المستحيل أن يعمل "السوبر" على الإطلاق! -First to say, from all that we've learned till now, it's impossible for `super` to work at all! +نعم ، في الواقع ، دعونا نسأل أنفسنا ، كيف يجب أن تعمل تقنيًا؟ عندما يتم تشغيل أسلوب كائن ، فإنه يحصل على الكائن الحالي باسم `هذا`. إذا استدعىنا "super.method ()` ، فسيحتاج المحرك إلى الحصول على "الطريقة" من النموذج الأولي للكائن الحالي. ولكن كيف؟ -Yeah, indeed, let's ask ourselves, how it should technically work? When an object method runs, it gets the current object as `this`. If we call `super.method()` then, the engine needs to get the `method` from the prototype of the current object. But how? +قد تبدو المهمة بسيطة ، لكنها ليست كذلك. المحرك يعرف الكائن الحالي `هذا` ، لذا يمكن أن يحصل على` الطريقة` الرئيسية كـ `هذا .__ بروتو __. الطريقة`. لسوء الحظ ، لن يعمل مثل هذا الحل "الساذج". -The task may seem simple, but it isn't. The engine knows the current object `this`, so it could get the parent `method` as `this.__proto__.method`. Unfortunately, such a "naive" solution won't work. +دعونا نثبت المشكلة. بدون فصول ، استخدام الأشياء البسيطة من أجل البساطة. -Let's demonstrate the problem. Without classes, using plain objects for the sake of simplicity. +يمكنك تخطي هذا الجزء والانتقال أدناه إلى القسم الفرعي [[HomeObject]] `إذا كنت لا تريد معرفة التفاصيل. هذا لن يضر. أو اقرأ إذا كنت مهتمًا بفهم الأشياء بعمق. -You may skip this part and go below to the `[[HomeObject]]` subsection if you don't want to know the details. That won't harm. Or read on if you're interested in understanding things in-depth. +في المثال أدناه ، "rabbit .__ proto__ = animal`. الآن دعنا نحاول: في "rabbit.eat ()` سنطلق عليه `animal.eat ()` ، باستخدام `this .__ proto__`: -In the example below, `rabbit.__proto__ = animal`. Now let's try: in `rabbit.eat()` we'll call `animal.eat()`, using `this.__proto__`: ```js run let animal = { @@ -323,11 +326,11 @@ let rabbit = { rabbit.eat(); // Rabbit eats. ``` -At the line `(*)` we take `eat` from the prototype (`animal`) and call it in the context of the current object. Please note that `.call(this)` is important here, because a simple `this.__proto__.eat()` would execute parent `eat` in the context of the prototype, not the current object. +عند السطر `(*)` نأخذ `نأكل` من النموذج الأولي (` الحيوان`) ونطلق عليه في سياق الكائن الحالي. يرجى ملاحظة أن ".call (هذا)` مهم هنا ، لأن "هذا .__ proto __. -And in the code above it actually works as intended: we have the correct `alert`. +وفي الكود أعلاه يعمل في الواقع على النحو المنشود: لدينا "التنبيه" الصحيح. -Now let's add one more object to the chain. We'll see how things break: +الآن دعنا نضيف كائنًا آخر إلى السلسلة. سنرى كيف تنكسر الأشياء: ```js run let animal = { @@ -358,17 +361,17 @@ longEar.eat(); // Error: Maximum call stack size exceeded */!* ``` -The code doesn't work anymore! We can see the error trying to call `longEar.eat()`. +الكود لم يعد يعمل! يمكننا رؤية الخطأ في محاولة استدعاء `longEar.eat ()`. -It may be not that obvious, but if we trace `longEar.eat()` call, then we can see why. In both lines `(*)` and `(**)` the value of `this` is the current object (`longEar`). That's essential: all object methods get the current object as `this`, not a prototype or something. +قد لا يكون ذلك واضحًا ، ولكن إذا تتبعنا مكالمة `longEar.eat ()` ، فيمكننا معرفة السبب. في كلا الخطين `(*)` و `(**)` قيمة `هذا` هي الكائن الحالي (` longEar`). هذا أمر ضروري: تحصل جميع أساليب الكائن على الكائن الحالي كـ `this` ، وليس كنموذج أولي أو شيء من هذا القبيل. -So, in both lines `(*)` and `(**)` the value of `this.__proto__` is exactly the same: `rabbit`. They both call `rabbit.eat` without going up the chain in the endless loop. +لذا ، في كلا الخطين `(*)` و `(**)` قيمة `هذا .__ proto__` هي نفسها بالضبط:" أرنب ". كلاهما يطلق عليه "rabbit.eat" دون الصعود في السلسلة في الحلقة اللانهائية. -Here's the picture of what happens: +إليك صورة لما يحدث: ![](this-super-loop.svg) -1. Inside `longEar.eat()`, the line `(**)` calls `rabbit.eat` providing it with `this=longEar`. +1. داخل `longEar.eat ()` ، يستدعي السطر `(**)` rabbit.eat` تزويده بـ `this = longEar`. ```js // inside longEar.eat() we have this = longEar this.__proto__.eat.call(this) // (**) @@ -377,7 +380,7 @@ Here's the picture of what happens: // that is rabbit.eat.call(this); ``` -2. Then in the line `(*)` of `rabbit.eat`, we'd like to pass the call even higher in the chain, but `this=longEar`, so `this.__proto__.eat` is again `rabbit.eat`! +2. ثم في السطر `(*)` من 'rabbit.eat` ، نرغب في تمرير المكالمة أعلى في السلسلة ، ولكن `this = longEar` ، لذا` هذا .__ proto __. eat` هو مرة أخرى " أرنب يأكل `! ```js // inside rabbit.eat() we also have this = longEar @@ -388,19 +391,19 @@ Here's the picture of what happens: rabbit.eat.call(this); ``` -3. ...So `rabbit.eat` calls itself in the endless loop, because it can't ascend any further. +3. ... لذا فإن "rabbit.eat" تطلق على نفسها اسمها في الحلقة اللانهائية ، لأنها لا تستطيع الصعود أكثر من ذلك. -The problem can't be solved by using `this` alone. +لا يمكن حل المشكلة باستخدام "هذا" وحده. ### `[[HomeObject]]` -To provide the solution, JavaScript adds one more special internal property for functions: `[[HomeObject]]`. +لتوفير الحل ، تضيف JavaScript خاصية داخلية خاصة أخرى للوظائف: `[[HomeObject]]`. -When a function is specified as a class or object method, its `[[HomeObject]]` property becomes that object. +عند تحديد دالة كفئة أو أسلوب كائن ، تصبح خاصية `[[HomeObject]]` هي ذلك الكائن. -Then `super` uses it to resolve the parent prototype and its methods. +ثم يستخدمه `super` لحل النموذج الأولي وطرقه. -Let's see how it works, first with plain objects: +دعونا نرى كيف يعمل ، أولاً مع الأشياء العادية: ```js run let animal = { @@ -432,17 +435,17 @@ longEar.eat(); // Long Ear eats. */!* ``` -It works as intended, due to `[[HomeObject]]` mechanics. A method, such as `longEar.eat`, knows its `[[HomeObject]]` and takes the parent method from its prototype. Without any use of `this`. +يعمل على النحو المقصود ، بسبب ميكانيكا `[[HomeObject]]. هناك طريقة ، مثل `longEar.eat` ، تعرف` [[HomeObject]] `وتأخذ الطريقة الأم من النموذج الأولي الخاص بها. دون أي استخدام "هذا". -### Methods are not "free" +### الدوال ليست "مجانية" -As we've known before, generally functions are "free", not bound to objects in JavaScript. So they can be copied between objects and called with another `this`. +كما عرفنا من قبل ، تكون الوظائف عمومًا "مجانية" ، وليست مرتبطة بكائنات في JavaScript. لذا يمكن نسخها بين الأشياء واستدعاؤها بـ "هذا" آخر. -The very existence of `[[HomeObject]]` violates that principle, because methods remember their objects. `[[HomeObject]]` can't be changed, so this bond is forever. +إن وجود [[HomeObject]] بحد ذاته ينتهك هذا المبدأ ، لأن الأساليب تتذكر أغراضها. لا يمكن تغيير `[[HomeObject]]` ، لذا فإن هذه الرابطة إلى الأبد. -The only place in the language where `[[HomeObject]]` is used -- is `super`. So, if a method does not use `super`, then we can still consider it free and copy between objects. But with `super` things may go wrong. +المكان الوحيد في اللغة حيث يتم استخدام `[[HomeObject]] - هو` super`. لذلك ، إذا كانت الطريقة لا تستخدم `super` ، فيمكننا اعتبارها مجانية ونسخها بين الكائنات. ولكن مع الأشياء "الفائقة" ، قد تسوء الأمور. -Here's the demo of a wrong `super` result after copying: +في ما يلي عرض توضيحي لنتيجة "خارقة" خاطئة بعد النسخ: ```js run let animal = { @@ -478,24 +481,24 @@ tree.sayHi(); // I'm an animal (?!?) */!* ``` -A call to `tree.sayHi()` shows "I'm an animal". Definitely wrong. +يُظهر استدعاء "tree.sayHi ()` أنا حيوان ". خطأ بالتأكيد. -The reason is simple: -- In the line `(*)`, the method `tree.sayHi` was copied from `rabbit`. Maybe we just wanted to avoid code duplication? -- Its `[[HomeObject]]` is `rabbit`, as it was created in `rabbit`. There's no way to change `[[HomeObject]]`. -- The code of `tree.sayHi()` has `super.sayHi()` inside. It goes up from `rabbit` and takes the method from `animal`. +والسبب بسيط: +- في السطر `(*)` ، تم نسخ الأسلوب `tree.sayHi` من` rabbit`. ربما أردنا فقط تجنب تكرار التعليمات البرمجية؟ +- "[[HomeObject]]` هو "أرنب" ، حيث تم إنشاؤه في "أرنب". لا توجد طريقة لتغيير `[[HomeObject]]`. +- كود `tree.sayHi ()` يحتوي على `super.sayHi ()` بالداخل. يرتفع من "أرنب" ويأخذ الطريقة من "حيوان". -Here's the diagram of what happens: +إليك الرسم البياني لما يحدث: ![](super-homeobject-wrong.svg) -### Methods, not function properties +### الدوال ، وليس خصائص الدوال -`[[HomeObject]]` is defined for methods both in classes and in plain objects. But for objects, methods must be specified exactly as `method()`, not as `"method: function()"`. +يتم تعريف `[[HomeObject]]` للطرق سواء في الفئات أو في الكائنات العادية. ولكن بالنسبة للكائنات ، يجب تحديد الطرق تمامًا باسم `الطريقة ()` ، وليس كـ '' الطريقة: الوظيفة () "`. -The difference may be non-essential for us, but it's important for JavaScript. +قد يكون الاختلاف غير ضروري بالنسبة لنا ، ولكنه مهم لجافا سكريبت. -In the example below a non-method syntax is used for comparison. `[[HomeObject]]` property is not set and the inheritance doesn't work: +في المثال أدناه ، يتم استخدام بناء جملة غير أسلوب للمقارنة. لم يتم تعيين خاصية `[[HomeObject]]` ولا يعمل الميراث: ```js run let animal = { @@ -516,17 +519,17 @@ rabbit.eat(); // Error calling super (because there's no [[HomeObject]]) */!* ``` -## Summary +## ملخص -1. To extend a class: `class Child extends Parent`: - - That means `Child.prototype.__proto__` will be `Parent.prototype`, so methods are inherited. -2. When overriding a constructor: - - We must call parent constructor as `super()` in `Child` constructor before using `this`. -3. When overriding another method: - - We can use `super.method()` in a `Child` method to call `Parent` method. -4. Internals: - - Methods remember their class/object in the internal `[[HomeObject]]` property. That's how `super` resolves parent methods. - - So it's not safe to copy a method with `super` from one object to another. +1. لتمديد الفصل الدراسي: `class child تمديد Parent`: +     - هذا يعني أن "Child.prototype .__ proto__" سيكون "Parent.prototype" ، لذلك يتم توريث الطرق. +2. عند تجاوز منشئ: +     - يجب أن نطلق على مُنشئ الوالدين باسم `super ()` في مُنشئ `Child` قبل استخدام` this`. +3. عند تجاوز طريقة أخرى: +     - يمكننا استخدام `super.method ()` في طريقة `Child` لاستدعاء طريقة` Parent`. +4. الداخلية: +     - تتذكر الأساليب فئتها / كائنها في خاصية `[[HomeObject]] الداخلية. هذه هي الطريقة التي يحل `super` الأساليب الأم. +     - لذا ليس من الآمن نسخ طريقة باستخدام "super" من كائن إلى آخر. -Also: -- Arrow functions don't have their own `this` or `super`, so they transparently fit into the surrounding context. +أيضا: +- لا تحتوي وظائف السهم على "هذا" أو "فائق" خاص بها ، لذا فهي تتناسب بشفافية مع السياق المحيط. \ No newline at end of file