Skip to content

Commit e8eec52

Browse files
committed
Translate instanceof to AR
1 parent 266cbe9 commit e8eec52

4 files changed

Lines changed: 93 additions & 81 deletions

File tree

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
Yeah, looks strange indeed.
1+
أجل، غريب عجيب حقًا.
22

3-
But `instanceof` does not care about the function, but rather about its `prototype`, that it matches against the prototype chain.
3+
ولكن كما نعرف فلا يكترث المُعامل `instanceof` بالدالة، بل بكائن prototype لها حيث تُطابقه مع غيره في سلسلة prototype.
44

5-
And here `a.__proto__ == B.prototype`, so `instanceof` returns `true`.
5+
وهنا نجد `a.__proto__ == B.prototype`، بذلك يُعيد `instanceof` القيمة `true`.
66

7-
So, by the logic of `instanceof`, the `prototype` actually defines the type, not the constructor function.
7+
إذًا فحسب منطق `instanceof`، كائن `prototype` هو الذي يُعرّف النوع وليس الدالة البانية.

1-js/09-classes/06-instanceof/1-strange-instanceof/task.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
importance: 5
1+
2+
_الأهمية: 5_
23

34
---
45

5-
# Strange instanceof
6+
## instnaceof غريب
67

7-
In the code below, why does `instanceof` return `true`? We can easily see that `a` is not created by `B()`.
8+
في الشيفرة أسفله، لماذا يُعيد `instanceof` القيمة `true`. يتّضح جليًا بأنّ `B()‎` لم يُنشِئ `a`.
89

910
```js run
1011
function A() {}

1-js/09-classes/06-instanceof/article.md

Lines changed: 84 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,65 @@
1-
# Class checking: "instanceof"
1+
# فحص الأصناف عبر instanceof
22

3-
The `instanceof` operator allows to check whether an object belongs to a certain class. It also takes inheritance into account.
3+
يُتيح لنا المُعامل `instanceof` (أهو سيرورة من) فحص هل الكائن ينتمي إلى الصنف الفلاني؟ كما يأخذ الوراثة في الحسبان عند الفحص.
44

5-
Such a check may be necessary in many cases. Here we'll use it for building a *polymorphic* function, the one that treats arguments differently depending on their type.
5+
توجد حالات عديدة يكون فيها هذا الفحص ضروريًا. **سنستعمله هنا لصناعة دالة **، أي دالة تغيّر تعاملها حسب نوع الوسطاء الممرّرة لها.
66

7-
## The instanceof operator [#ref-instanceof]
7+
## معامل instanceof
8+
9+
صياغته هي:
810

9-
The syntax is:
1011
```js
1112
obj instanceof Class
1213
```
1314

14-
It returns `true` if `obj` belongs to the `Class` or a class inheriting from it.
15+
يُعيد المُعامل قيمة `true` لو كان الكائن `obj` ينتمي إلى الصنف `Class` أو أيّ صنف يرثه.
16+
17+
مثال:
1518

16-
For instance:
1719

1820
```js run
1921
class Rabbit {}
2022
let rabbit = new Rabbit();
2123

22-
// is it an object of Rabbit class?
24+
// ‫هل هو كائن من الصنف Rabbit؟
2325
*!*
24-
alert( rabbit instanceof Rabbit ); // true
26+
alert( rabbit instanceof Rabbit ); // نعم
2527
*/!*
2628
```
2729

28-
It also works with constructor functions:
30+
كما يعمل مع الدوال البانية:
2931

3032
```js run
3133
*!*
32-
// instead of class
34+
// ‫بدل استعمال class
3335
function Rabbit() {}
3436
*/!*
3537

36-
alert( new Rabbit() instanceof Rabbit ); // true
38+
alert( new Rabbit() instanceof Rabbit ); // نعم
3739
```
3840

39-
...And with built-in classes like `Array`:
41+
...كما والأصناف المضمّنة مثل المصفوفات `Array`:
4042

4143
```js run
4244
let arr = [1, 2, 3];
43-
alert( arr instanceof Array ); // true
44-
alert( arr instanceof Object ); // true
45+
alert( arr instanceof Array ); // نعم
46+
alert( arr instanceof Object ); // نعم
4547
```
4648

47-
Please note that `arr` also belongs to the `Object` class. That's because `Array` prototypically inherits from `Object`.
49+
لاحظ كيف أنّ الكائن `arr` ينتمي إلى صنف الكائنات `Object` أيضًا، إذ ترث المصفوفات -عبر prototype- الكائناتَ.
50+
51+
عادةً ما يتحقّق المُعامل `instanceof` من سلسلة prototype عند الفحص. كما يمكننا وضع المنطق الذي نريد لكلّ صنف في التابِع الثابت `Symbol.hasInstance`.
4852

49-
Normally, `instanceof` examines the prototype chain for the check. We can also set a custom logic in the static method `Symbol.hasInstance`.
53+
تعمل خوارزمية `obj instanceof Class` بهذه الطريقة تقريبًا:
5054

51-
The algorithm of `obj instanceof Class` works roughly as follows:
55+
1. لو وجدت التابِع الثابت `Symbol.hasInstance` تستدعيه وينتهي الأمر: `Class[Symbol.hasInstance](obj)‎`. يُعيد التابِع إمّا `true` وإمّا `false`. هكذا نخصّص سلوك المُعامل `instanceof`.
5256

53-
1. If there's a static method `Symbol.hasInstance`, then just call it: `Class[Symbol.hasInstance](obj)`. It should return either `true` or `false`, and we're done. That's how we can customize the behavior of `instanceof`.
57+
مثال:
5458

55-
For example:
5659

5760
```js run
58-
// setup instanceOf check that assumes that
59-
// anything with canEat property is an animal
61+
// ‫ضبط instanceOf للتحقق من الافتراض القائل
62+
// ‫بأن كل شيء يملك الخاصية canEat هو حيوان
6063
class Animal {
6164
static [Symbol.hasInstance](obj) {
6265
if (obj.canEat) return true;
@@ -68,101 +71,105 @@ The algorithm of `obj instanceof Class` works roughly as follows:
6871
alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) is called
6972
```
7073

71-
2. Most classes do not have `Symbol.hasInstance`. In that case, the standard logic is used: `obj instanceOf Class` checks whether `Class.prototype` is equal to one of the prototypes in the `obj` prototype chain.
74+
2. ليس لأغلب الأصناف التابِع `Symbol.hasInstance`. في هذه الحالة تستعمل المنطق العادي: يفحص `obj instanceOf Class` لو كان كائن `Class.prototype` مساويًا لأحد كائنات prototype في سلسلة كائنات prototype للكائن `obj`.
75+
76+
وبعبارة أخرى ، وازن بينهم واحدًا تلو الآخر:
7277

73-
In other words, compare one after another:
7478
```js
7579
obj.__proto__ === Class.prototype?
7680
obj.__proto__.__proto__ === Class.prototype?
7781
obj.__proto__.__proto__.__proto__ === Class.prototype?
7882
...
79-
// if any answer is true, return true
80-
// otherwise, if we reached the end of the chain, return false
83+
// ‫لو كانت إجابة أيًا منها true، فتُعيد true
84+
// ‫وإلّا متى وصلت نهاية السلسلة أعادت false
85+
8186
```
8287

83-
In the example above `rabbit.__proto__ === Rabbit.prototype`, so that gives the answer immediately.
88+
في المثال أعلاه نرى `rabbit.__proto__ === Rabbit.prototype`، بذلك تُعطينا الجواب مباشرةً.
89+
90+
أمّا لو كنّا في حالة وراثة، فستتوقّف عملية المطابقة عند الخطوة الثانية:
8491

85-
In the case of an inheritance, the match will be at the second step:
8692

8793
```js run
8894
class Animal {}
8995
class Rabbit extends Animal {}
9096
9197
let rabbit = new Rabbit();
9298
*!*
93-
alert(rabbit instanceof Animal); // true
99+
alert(rabbit instanceof Animal); // نعم
94100
*/!*
95101
96102
// rabbit.__proto__ === Rabbit.prototype
97103
*!*
98-
// rabbit.__proto__.__proto__ === Animal.prototype (match!)
104+
// rabbit.__proto__.__proto__ === Animal.prototype (تطابق!)
99105
*/!*
100106
```
101107

102-
Here's the illustration of what `rabbit instanceof Animal` compares with `Animal.prototype`:
108+
إليك صورة توضّح طريقة موازنة `rabbit instanceof Animal` مع `Animal.prototype`:
103109

104110
![](instanceof.svg)
105111

106-
By the way, there's also a method [objA.isPrototypeOf(objB)](mdn:js/object/isPrototypeOf), that returns `true` if `objA` is somewhere in the chain of prototypes for `objB`. So the test of `obj instanceof Class` can be rephrased as `Class.prototype.isPrototypeOf(obj)`.
112+
كما وهناك أيضًا التابِع [objA.isPrototypeOf(objB)](mdn:js/object/isPrototypeOf)، وهو يُعيد `true` لو كان الكائن `objA` في مكان داخل سلسلة prototype للكائن `objB`. يعني أنّنا نستطيع كتابة الفحص هذا `obj instanceof Class` هكذا: `Class.prototype.isPrototypeOf(obj)`.
107113

108-
It's funny, but the `Class` constructor itself does not participate in the check! Only the chain of prototypes and `Class.prototype` matters.
114+
الأمر مضحك إذ أنّ باني الصنف `Class` نفسه ليس لديه أيّ كلمة عن هذا الفحص! المهم هو سلسلة prototype وكائن `Class.prototype` فقط.
109115

110-
That can lead to interesting consequences when a `prototype` property is changed after the object is created.
116+
يمكن أن يؤدّي هذا إلى عواقب مثيرة متى تغيّرت خاصية `prototype` للكائن بعد إنشائه. طالع:
111117

112-
Like here:
113118

114119
```js run
115120
function Rabbit() {}
116121
let rabbit = new Rabbit();
117122
118-
// changed the prototype
123+
// غيّرنا كائن prototype
119124
Rabbit.prototype = {};
120125
121-
// ...not a rabbit any more!
126+
// ...لم يعد أرنبًا بعد الآن!
122127
*!*
123-
alert( rabbit instanceof Rabbit ); // false
128+
alert( rabbit instanceof Rabbit ); // لا
124129
*/!*
125130
```
126131

127-
## Bonus: Object.prototype.toString for the type
132+
## التابع Object.prototype.toString للأنواع
128133

129-
We already know that plain objects are converted to string as `[object Object]`:
134+
نعلم بأنّ الكائنات العادية حين تتحوّل إلى سلاسل نصية تصير `[object Object]`:
130135

131136
```js run
132137
let obj = {};
133138
134139
alert(obj); // [object Object]
135-
alert(obj.toString()); // the same
140+
alert(obj.toString()); // كما أعلاه
136141
```
137142

138-
That's their implementation of `toString`. But there's a hidden feature that makes `toString` actually much more powerful than that. We can use it as an extended `typeof` and an alternative for `instanceof`.
143+
يعتمد هذا على طريقة توفيرهم لتنفيذ التابِع `toString`. ولكن هناك ميزة مخفيّة تجعل هذا التابِع أكثر فائدة بكثير ممّا هو عليه، أن نستعمله على أنّه مُعامل `typeof` موسّع المزايا، أو بديلًا عن التابِع `toString`.
139144

140-
Sounds strange? Indeed. Let's demystify.
145+
تبدو غريبة؟ أليس كذلك؟ لنُزل الغموض.
141146

142-
By [specification](https://tc39.github.io/ecma262/#sec-object.prototype.tostring), the built-in `toString` can be extracted from the object and executed in the context of any other value. And its result depends on that value.
143147

144-
- For a number, it will be `[object Number]`
145-
- For a boolean, it will be `[object Boolean]`
146-
- For `null`: `[object Null]`
147-
- For `undefined`: `[object Undefined]`
148-
- For arrays: `[object Array]`
149-
- ...etc (customizable).
148+
حسب [المواصفة](https://tc39.github.io/ecma262/#sec-object.prototype.tostring)، فيمكننا استخراج التابِع `toString` المضمّن من الكائن وتنفيذه في سياق أيّ قيمة أخرى نريد، وسيكون ناتجه حسب تلك القيمة.
149+
150+
- لو كان عددًا، فسيكون `[object Number]`
151+
- لو كان قيمة منطقية، فسيكون `[object Boolean]`
152+
- لو كان `null`:`[object Null]`
153+
- لو كان `undefined`:`[object Undefined]`
154+
- لو كانت مصفوفة: `[object Array]`
155+
- ...إلى آخره (ويمكننا تخصيص ذلك).
156+
157+
هيًا نوضّح:
150158

151-
Let's demonstrate:
152159

153160
```js run
154-
// copy toString method into a variable for convenience
161+
// ننسخ التابِع‫ toString إلى متغير ليسهل عملنا
155162
let objectToString = Object.prototype.toString;
156163
157-
// what type is this?
164+
// ما هذا النوع؟
158165
let arr = [];
159166
160-
alert( objectToString.call(arr) ); // [object *!*Array*/!*]
167+
alert( objectToString.call(arr) ); // [object *!*مصفوفة*/!*]
161168
```
162169

163-
Here we used [call](mdn:js/function/call) as described in the chapter [](info:call-apply-decorators) to execute the function `objectToString` in the context `this=arr`.
170+
استعملنا هنا [call](mdn:js/function/call)“ لتنفيذ الدالة `objectToString` بسياق `this=arr`.
164171

165-
Internally, the `toString` algorithm examines `this` and returns the corresponding result. More examples:
172+
تفحص خوارزمية `toString` داخليًا قيمة `this` وتُعيد الناتج الموافق لها. إليك أمثلة أخرى:
166173

167174
```js run
168175
let s = Object.prototype.toString;
@@ -172,11 +179,12 @@ alert( s.call(null) ); // [object Null]
172179
alert( s.call(alert) ); // [object Function]
173180
```
174181

175-
### Symbol.toStringTag
182+
### خاصية Symbol.toStringTag
183+
184+
يمكننا تخصيص سلوك التابِع `toString` للكائنات باستعمال خاصية الكائنات `Symbol.toStringTag` الفريدة.
176185

177-
The behavior of Object `toString` can be customized using a special object property `Symbol.toStringTag`.
186+
مثال:
178187

179-
For instance:
180188

181189
```js run
182190
let user = {
@@ -186,33 +194,36 @@ let user = {
186194
alert( {}.toString.call(user) ); // [object User]
187195
```
188196
189-
For most environment-specific objects, there is such a property. Here are some browser specific examples:
197+
لأغلب الكائنات الخاصّة بالبيئات خاصية مثل هذه. إليك بعض الأمثلة من المتصفّحات مثلًا:
190198
191199
```js run
192-
// toStringTag for the environment-specific object and class:
200+
// تابِع ‫toStringTag للكائنات والأصناف الخاصّة بالمتصفّحات:
193201
alert( window[Symbol.toStringTag]); // window
194202
alert( XMLHttpRequest.prototype[Symbol.toStringTag] ); // XMLHttpRequest
195203

196204
alert( {}.toString.call(window) ); // [object Window]
197205
alert( {}.toString.call(new XMLHttpRequest()) ); // [object XMLHttpRequest]
198206
```
199207
200-
As you can see, the result is exactly `Symbol.toStringTag` (if exists), wrapped into `[object ...]`.
208+
كما نرى فالناتج هو تمامًا ما يقوله `Symbol.toStringTag` (لو وُجد) بغلاف `[object ...‎]`.
209+
210+
في النهاية نجد أن لدينا "نوع من المنشطات" لا تعمل فقط على الأنواع الأولية للبيانات بل وحتى الكائنات المضمنة في اللغة ويمكننا تخصيصها أيضًا.
211+
212+
يمكننا استخدام `‎{}.toString.call` بدلًا من `instanceof` للكائنات المضمنة في اللغة عندما نريد الحصول على نوع البيانات كسلسلة بدلًا من التحقق منها.
213+
201214
202-
At the end we have "typeof on steroids" that not only works for primitive data types, but also for built-in objects and even can be customized.
215+
## الملخص
203216
204-
We can use `{}.toString.call` instead of `instanceof` for built-in objects when we want to get the type as a string rather than just to check.
217+
لنلخّص ما نعرف عن التوابِع التي تفحص الأنواع:
205218
206-
## Summary
219+
| | يعمل على | يُعيد |
220+
|--|--|--|
221+
| `typeof` | الأنواع الأولية | سلسلة نصية |
222+
| `{}.toString` | الأنواع الأولية والكائنات المضمّنة والكائنات التي لها `Symbol.toStringTag` | سلسلة نصية |
223+
| `instanceof` | الكائنات | true/false |
207224
208-
Let's summarize the type-checking methods that we know:
209225
210-
| | works for | returns |
211-
|---------------|-------------|---------------|
212-
| `typeof` | primitives | string |
213-
| `{}.toString` | primitives, built-in objects, objects with `Symbol.toStringTag` | string |
214-
| `instanceof` | objects | true/false |
226+
كما نرى فعبارة `‎{}.toString` هي تقنيًا `typeof` ولكن ”متقدّمة أكثر“.
215227
216-
As we can see, `{}.toString` is technically a "more advanced" `typeof`.
228+
بل إن التابع `instanceof` يؤدي دور مميّز عندما نتعامل مع تسلسل هرمي للأصناف ونريد التحقق من صنفٍ ما مع مراعاة الوراثة.
217229
218-
And `instanceof` operator really shines when we are working with a class hierarchy and want to check for the class taking into account inheritance.

1-js/09-classes/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
# Classes
1+
# الأصناف (Classes)

0 commit comments

Comments
 (0)