Skip to content

Commit d035cc7

Browse files
authored
Merge pull request #61 from NgArab/master
Mixins
2 parents b6305a7 + f5adef4 commit d035cc7

File tree

1 file changed

+58
-59
lines changed

1 file changed

+58
-59
lines changed
Lines changed: 58 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
# Mixins
22

3-
In JavaScript we can only inherit from a single object. There can be only one `[[Prototype]]` for an object. And a class may extend only one other class.
3+
فى جافاسكريبت يمكننا الوراثة من كائن واحد فقط. يمكن ان يوجد `[[Prototype]]` واحد فقط للكائن. و يمكن للـ `class` ان يقوم بـ `extend` فقط من `class` واحد آخر.
44

5-
But sometimes that feels limiting. For instance, we have a class `StreetSweeper` and a class `Bicycle`, and want to make their mix: a `StreetSweepingBicycle`.
5+
و لكن في بعض الأحيان ذلك يوحي بالتقييد. مثال علي ذلك, لدينا `class` هو `StreetSweeper` و `class` آخر هو `Bicycle`, و نريد تكوين ذلك المزيج بينهم: و هو `StreetSweepingBicycle`.
66

7-
Or we have a class `User` and a class `EventEmitter` that implements event generation, and we'd like to add the functionality of `EventEmitter` to `User`, so that our users can emit events.
7+
أو لدينا `class` هو `User` و `class` آخر هو `EventEmitter` الذي يقوم بتنفيذ إستخراج الأحداث, و نريد الآن إضافة دوال `EventEmitter` إلى `User`, لكي يمكن مستخدمينا من إرسال الأحداث.
88

9-
There's a concept that can help here, called "mixins".
9+
يوجد مفهوم يمكن أن يساعدنا هنا, يُسيمى `mixins`.
1010

11-
As defined in Wikipedia, a [mixin](https://en.wikipedia.org/wiki/Mixin) is a class containing methods that can be used by other classes without a need to inherit from it.
11+
كما يتم تعريفه في ويكيبيديا, [mixin](https://en.wikipedia.org/wiki/Mixin) هو `class` يحتوي علي دوال يمكن إستخدامها بواسطة `classes` أخرى بدون الحاجه الى الوراثة منها.
1212

13-
In other words, a *mixin* provides methods that implement a certain behavior, but we do not use it alone, we use it to add the behavior to other classes.
13+
بطريقة أخرى, _mixin_ يمكنها توفير دوال تقوم بتنفيذ سلوك محدد, و لكن نحن لا نستخدمها وحدها, نحن نستخدمها لنضيف سلوك الى `classes` أخرى.
1414

15-
## A mixin example
15+
## مثال علي mixin
1616

17-
The simplest way to implement a mixin in JavaScript is to make an object with useful methods, so that we can easily merge them into a prototype of any class.
17+
أسهل طريقة لتنفيذ `mixin` فى جافاسكريبت هو ان تقوم بعمل كائن له دوال مفيدة, لذا يمكننا بسهولة دمجهم مع `prototype` خاص بأيّ `class`.
1818

1919
For instance here the mixin `sayHiMixin` is used to add some "speech" for `User`:
2020

@@ -24,10 +24,10 @@ For instance here the mixin `sayHiMixin` is used to add some "speech" for `User`
2424
*/!*
2525
let sayHiMixin = {
2626
sayHi() {
27-
alert(`Hello ${this.name}`);
27+
alert(`مرحباً ${this.name}`);
2828
},
2929
sayBye() {
30-
alert(`Bye ${this.name}`);
30+
alert(`الوداع ${this.name}`);
3131
}
3232
};
3333

@@ -40,14 +40,14 @@ class User {
4040
}
4141
}
4242

43-
// copy the methods
43+
// نسخ الدوال
4444
Object.assign(User.prototype, sayHiMixin);
4545

46-
// now User can say hi
47-
new User("Dude").sayHi(); // Hello Dude!
46+
// الآن User يمكن ان يقول مرحباً
47+
new User("Dude").sayHi(); // مرحباً Dude!
4848
```
4949

50-
There's no inheritance, but a simple method copying. So `User` may inherit from another class and also include the mixin to "mix-in" the additional methods, like this:
50+
لا يوجد وراثة, و لكن نسخ دوال ببساطة. لذا `User` ربما يرث من `class` آخر و يقوم بتضمين `mixin` لكي "يمزج" الدوال الإضافية, مثل ذلك:
5151

5252
```js
5353
class User extends Person {
@@ -57,9 +57,9 @@ class User extends Person {
5757
Object.assign(User.prototype, sayHiMixin);
5858
```
5959

60-
Mixins can make use of inheritance inside themselves.
60+
`Mixins` يمكنها الإستفادة من الوراثة داخل نفسها.
6161

62-
For instance, here `sayHiMixin` inherits from `sayMixin`:
62+
مثال علي ذلك, هنا `sayHiMixin` ترث من `sayMixin`:
6363

6464
```js run
6565
let sayMixin = {
@@ -69,11 +69,11 @@ let sayMixin = {
6969
};
7070

7171
let sayHiMixin = {
72-
__proto__: sayMixin, // (or we could use Object.create to set the prototype here)
72+
__proto__: sayMixin, // (او يمكننا إستخدام Object.create لكى نضع prototype هنا)
7373

7474
sayHi() {
7575
*!*
76-
// call parent method
76+
// طلب تنفيذ الدالة الأب
7777
*/!*
7878
super.say(`Hello ${this.name}`); // (*)
7979
},
@@ -88,45 +88,45 @@ class User {
8888
}
8989
}
9090

91-
// copy the methods
91+
// نسخ الدوال
9292
Object.assign(User.prototype, sayHiMixin);
9393

94-
// now User can say hi
95-
new User("Dude").sayHi(); // Hello Dude!
94+
// الآن User يمكن أن يقول مرحباً
95+
new User("Dude").sayHi(); // مرحباً Dude!
9696
```
9797

98-
Please note that the call to the parent method `super.say()` from `sayHiMixin` (at lines labelled with `(*)`) looks for the method in the prototype of that mixin, not the class.
98+
برجاء ملاحظة ان طلب الدالة الأب `super.say()` من `sayHiMixin` (فى السطور المعنونه بـ `(*)`) تبحث عن الداله في `prototype` الخاص بـ `mixin`, ليس الخاص ب `class`.
9999

100-
Here's the diagram (see the right part):
100+
هذا هو الرسم البياني (أنظر الى الجزء الأيمن):
101101

102102
![](mixin-inheritance.svg)
103103

104-
That's because methods `sayHi` and `sayBye` were initially created in `sayHiMixin`. So even though they got copied, their `[[HomeObject]]` internal property references `sayHiMixin`, as shown in the picture above.
104+
هذا بسبب الدالة `sayHi` و `sayBye` الذي تم إنشاؤهما فى `sayHiMixin`. لذا علي الرغم من انه تم نسخهم, `[[HomeObject]]` الخاص بهم هو مرجع الخاصية الداخلية `sayHiMixin`, كما هو موضح فى الصورة اعلاه.
105105

106-
As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`, not `User.[[Prototype]]`.
106+
كما أن `super` يبحث عن الدالة الأب في `[[HomeObject]].[[Prototype]]`, هذا يعني انه يبحث في `sayHiMixin.[[Prototype]]`, و ليس `User.[[Prototype]]`.
107107

108108
## EventMixin
109109

110-
Now let's make a mixin for real life.
110+
الآن دعنا نقوم بعمل مثال حقيقي للـ `mixin` .
111111

112-
An important feature of many browser objects (for instance) is that they can generate events. Events are a great way to "broadcast information" to anyone who wants it. So let's make a mixin that allows us to easily add event-related functions to any class/object.
112+
ميزة مهمة للعديد من كائنات المتصفح (مثال) أنهم يمكنهم استخراج احداث. الأحداث هي طريقة جيدة لـ "نشر المعلومات" لأي شخص يريدها. لذا دعنا نقوم بعمل `mixin` الذي يسمح لنا ان نقوم بسهولة بإضافة دوال متعلقه بالأحداث لأي `class/object`.
113113

114-
- The mixin will provide a method `.trigger(name, [...data])` to "generate an event" when something important happens to it. The `name` argument is a name of the event, optionally followed by additional arguments with event data.
115-
- Also the method `.on(name, handler)` that adds `handler` function as the listener to events with the given name. It will be called when an event with the given `name` triggers, and get the arguments from the `.trigger` call.
116-
- ...And the method `.off(name, handler)` that removes the `handler` listener.
114+
- الـ `mixin` سوف يوفر دالة `.trigger(name, [...data])` لكى "نستخرج الحدث" عندما يحدث شيئ مهم لها. متغير الـ `name` هو إسم الحدث, متبوعاً بشكل إختياري بـ متغيرات إضافية ببيانات الحدث.
115+
- أيضاً الدالة `.on(name, handler)` التى تضيف دالة `handler` التي تقوم بالإستماع للأحداث المُعطي إسمها. سوف يتم طلبها عندما يتم تشغيل حدث ما بالـ `إسم` المُعطي, و الحصول علي المتغيرات عند طلب `.trigger`.
116+
- ...و الدالة `.off(name, handler)` التي تقوم بمسح المستمع `handler`.
117117

118-
After adding the mixin, an object `user` will be able to generate an event `"login"` when the visitor logs in. And another object, say, `calendar` may want to listen for such events to load the calendar for the logged-in person.
118+
بعد إضافة `mixin`, الكائن `user` يمكنه إستخراج حدث `"login"` عندما يقوم الزائر بتسجيل الدخول. و كائن آخر, يقول, `calendar` ربما يريد الإستماع لبعض الأحداث لتحميل النتيجة للشخص الذى قام بتسجيل الدخول.
119119

120-
Or, a `menu` can generate the event `"select"` when a menu item is selected, and other objects may assign handlers to react on that event. And so on.
120+
أو, `menu` يمكنه إستخراج الحدث `"select"` عندما يتم أختيار عنصر من القائمة, و كائنات اخري يمكن ان ترفق `handlers` لكى تتفاعل مع هذا الحدث. و كذلك.
121121

122-
Here's the code:
122+
هذا هو الكود:
123123

124124
```js run
125125
let eventMixin = {
126126
/**
127-
* Subscribe to event, usage:
127+
* الإستماع الى الحدث, الإستخدام:
128128
* menu.on('select', function(item) { ... }
129-
*/
129+
*/
130130
on(eventName, handler) {
131131
if (!this._eventHandlers) this._eventHandlers = {};
132132
if (!this._eventHandlers[eventName]) {
@@ -136,7 +136,7 @@ let eventMixin = {
136136
},
137137

138138
/**
139-
* Cancel the subscription, usage:
139+
* إلغاء المتابعه, الإستخدام:
140140
* menu.off('select', handler)
141141
*/
142142
off(eventName, handler) {
@@ -150,59 +150,58 @@ let eventMixin = {
150150
},
151151

152152
/**
153-
* Generate an event with the given name and data
153+
* إستخراج حدث بالإسم و البيانات المُعطاه
154154
* this.trigger('select', data1, data2);
155155
*/
156156
trigger(eventName, ...args) {
157157
if (!this._eventHandlers || !this._eventHandlers[eventName]) {
158-
return; // no handlers for that event name
158+
return; // لا يوجد handlers لإسم الحدث هذا
159159
}
160160

161-
// call the handlers
162-
this._eventHandlers[eventName].forEach(handler => handler.apply(this, args));
163-
}
161+
// طلب الـ handlers
162+
this._eventHandlers[eventName].forEach((handler) => handler.apply(this, args));
163+
},
164164
};
165165
```
166166
167+
- `.on(eventName, handler)` -- تقوم بتعيين دالة `handler` لتقوم بالعمل عندما يحدث هذا الحدث بذلك الإسم. تقنياً, يوجد خاصية `_eventHandlers` التى تقوم بتخزين مصفوفة من `handlers` لكل إسم حدث, و هى مجرد تقوم بإضافته للقائمة.
168+
- `.off(eventName, handler)` -- تقوم بحذف الدالة من قائمة الـ `handlers`.
169+
- `.trigger(eventName, ...args)` -- تستخرج الحدث: يتم طلب كل الـ `handlers` من `_eventHandlers[eventName]` , بقائمة من المتغيرات `...args`.
167170
168-
- `.on(eventName, handler)` -- assigns function `handler` to run when the event with that name occurs. Technically, there's an `_eventHandlers` property that stores an array of handlers for each event name, and it just adds it to the list.
169-
- `.off(eventName, handler)` -- removes the function from the handlers list.
170-
- `.trigger(eventName, ...args)` -- generates the event: all handlers from `_eventHandlers[eventName]` are called, with a list of arguments `...args`.
171-
172-
Usage:
171+
الإستخدام:
173172
174173
```js run
175-
// Make a class
174+
// إنشئ class
176175
class Menu {
177176
choose(value) {
178177
this.trigger("select", value);
179178
}
180179
}
181-
// Add the mixin with event-related methods
180+
// أضف mixin بـ دوال خاصة بالحدث
182181
Object.assign(Menu.prototype, eventMixin);
183182

184183
let menu = new Menu();
185184

186-
// add a handler, to be called on selection:
185+
// أضف handler, لكى يتم طلبها عند الإختيار:
187186
*!*
188-
menu.on("select", value => alert(`Value selected: ${value}`));
187+
menu.on("select", value => alert(`القيمة المُختارة: ${value}`));
189188
*/!*
190189

191-
// triggers the event => the handler above runs and shows:
192-
// Value selected: 123
190+
// تنفيذ الحدث => الـ handler بالأعلي يعمل و يُظهر:
191+
// القيمة المُختارة: 123
193192
menu.choose("123");
194193
```
195194
196-
Now, if we'd like any code to react to a menu selection, we can listen for it with `menu.on(...)`.
195+
الآن, إذا كنا نريد اى كود يتفاعل عند الإختيار من القائمة, يمكننا الإستماع اليه عن طريق `menu.on(...)`.
197196
198-
And `eventMixin` mixin makes it easy to add such behavior to as many classes as we'd like, without interfering with the inheritance chain.
197+
و `eventMixin` `mixin` جعلته من السهل إضافة هذا السلوك لـ `classes` كثيرة كما نريد, دون التدخل فى سلسلة الميراث.
199198
200-
## Summary
199+
## الملخص
201200
202-
*Mixin* -- is a generic object-oriented programming term: a class that contains methods for other classes.
201+
_Mixin_ -- هو مصطلح عام خاص بالبرمجة الشيئية `object-oriented programming`: الـ `class` الذي يحتوي علي دوال لـ `classes` اخرى.
203202
204-
Some other languages allow multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying methods into prototype.
203+
بعض اللغات الاخرى تسمح بالوراثة المتعددة. جافاسكريبت لا تسمح بالوراثة المتعددة, و لكن `mixins` يمكن تنفيذها عن طريق نسخ الدوال الى `prototype`.
205204
206-
We can use mixins as a way to augment a class by adding multiple behaviors, like event-handling as we have seen above.
205+
يمكننا إستخدام `mixins` كطريقة لزيادة الـ `class` عن طريق إضافة سلوكيات متعددة, مثل تنسيق الحدث الذي رأيناه بالأعلي.
207206
208-
Mixins may become a point of conflict if they accidentally overwrite existing class methods. So generally one should think well about the naming methods of a mixin, to minimize the probability of that happening.
207+
`Mixins` يمكن ان تكون نقطة تضارب اذا قاموا عن طريق الخطأ بالكتابه فوق دوال خاصة بـ `class`. إذا بشكل عام يجب علي المرء أن يفكر جيداً فى طريقة تسمية الدوال الخاصه بـ `mixin`,لتقلل إحتمالية حدوث الأخطاء.

0 commit comments

Comments
 (0)