You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
الأوّل هو خصائص البيانات _data properties_. نحن بالفعل نعلم كيف نتعامل مع هذا النوع. إذ كلّ ما استعملناه من البداية حتى الآن هو خصائص البيانات.
5
6
6
-
The first kind is *data properties*. We already know how to work with them. All properties that we've been using until now were data properties.
7
+
النوع الثاني من الخصائص هو شيئ ما جديد. و هو _accessor properties_. هي دوال بشكل أساسي تجلب القيم و تضبطها, ولكن في الكود تظهرُ لنا وكأنها خصائص عادية.
7
8
8
-
The second type of properties is something new. It's *accessor properties*. They are essentially functions that work on getting and setting a value, but look like regular properties to an external code.
9
+
## الجالبات والضابطات
9
10
10
-
## Getters and setters
11
-
12
-
Accessor properties are represented by "getter" and "setter" methods. In an object literal they are denoted by `get` and `set`:
11
+
خصائص الوصول تمثل بـ "getter" و "setter". يشار إليهم داخل الكائن بـ `get` and `set`:
13
12
14
13
```js
15
14
let obj = {
16
15
*!*get propName()*/!* {
17
-
//getter, the code executed on getting obj.propName
16
+
//جالب، يُستعمَل لجلب قيمة الخاصية obj.propName
18
17
},
19
18
20
19
*!*set propName(value)*/!* {
21
-
//setter, the code executed on setting obj.propName = value
20
+
//ضابط يُستعمَل لضبط قيمة الخاصية obj.propName إلى value
22
21
}
23
22
};
24
23
```
25
24
26
-
The getter works when `obj.propName` is read, the setter -- when it is assigned.
25
+
يستعمل الجالب عند قراءة الخاصية `obj.propName`, الضابط -- عند ضبط أو إسناد قيمة تلك الخاصية.
27
26
28
-
For instance, we have a `user`object with`name`and`surname`:
Now we want to add a`fullName` property, that should be `"John Smith"`. Of course, we don't want to copy-paste existing information, so we can implement it as an accessor:
36
+
الآن نريد إضافة خاصية الاسم الكامل`fullName`, التى يجب ان تكون `"John Smith"`. بالطبع, طبعًا لا نريد نسخ المعلومات ولصقها, لذا سنُنفذها باستخدام خاصية الوصول (ِget) :
38
37
39
38
```js run
40
39
let user = {
@@ -53,9 +52,9 @@ alert(user.fullName); // John Smith
53
52
*/!*
54
53
```
55
54
56
-
From outside, an accessor property looks like a regular one. That's the idea of accessor properties. We don't *call*`user.fullName`as a function, we *read* it normally: the getter runs behind the scenes.
55
+
من الخارج, لا تبدو خاصية الوصول إلا خاصية عادية. وهذا بالضبط الغرض من هذه الخصائص. فلسنا نريد _إستدعاء_`user.fullName`على أنّها دالة, بل _قراءتها_ بشكل طبيعي: ونترك الجالب يقوم بعمله خلف الكواليس.
57
56
58
-
As of now, `fullName`has only a getter. If we attempt to assign `user.fullName=`, there will be an error:
57
+
حتى الآن, `fullName`لديها فقط جالب. لو حاولنا إسناد قيمة لها عن طريق `user.fullName=`, سوف يحدث خطأ:
59
58
60
59
```js run
61
60
let user = {
@@ -65,11 +64,11 @@ let user = {
65
64
};
66
65
67
66
*!*
68
-
user.fullName="Test"; //Error (property has only a getter)
67
+
user.fullName="Test"; //خطأ (للخاصية جالب فقط)
69
68
*/!*
70
69
```
71
70
72
-
Let's fix it by adding a setter for`user.fullName`:
Getters/setters can be used as wrappers over "real" property values to gain more control over operations with them.
155
+
يمكننا استعمال الجوالب والضوابط كأغلفة لقيم الخاصيات "الفعلية" لكى تستطيع التحكم اكثر في العمليات بينهم.
157
156
158
-
For instance, if we want to forbid too short names for `user`, we can have a setter`name`and keep the value in a separate property`_name`:
157
+
فمثلاً, إذا اردنا منع الأسماء القصيرة لـ `user`, فيمكن ان يكون لدينا الضابط`name`و ترك القيمه في خاصية منفصلة`_name`:
159
158
160
159
```js run
161
160
let user = {
@@ -165,67 +164,66 @@ let user = {
165
164
166
165
setname(value) {
167
166
if (value.length<4) {
168
-
alert("Name is too short, need at least 4 characters");
167
+
alert('Name is too short, need at least 4 characters');
169
168
return;
170
169
}
171
170
this._name= value;
172
-
}
171
+
},
173
172
};
174
173
175
-
user.name="Pete";
174
+
user.name='Pete';
176
175
alert(user.name); // Pete
177
176
178
-
user.name=""; //Name is too short...
177
+
user.name=''; // ...الإسم قصير جدا
179
178
```
180
179
181
-
So, the name is stored in `_name` property, and the access is done via getter and setter.
182
-
183
-
Technically, external code is able to access the name directly by using `user._name`. But there is a widely known convention that properties starting with an underscore `"_"` are internal and should not be touched from outside the object.
180
+
إذاً, سوف يتخزن الإسم في خاصية `_name`, و الوصول سوف يكون عن طريق الجالبات و الضابطات.
184
181
182
+
عملياً, الكود الخارجي يمكن ان يصل الى الإسم بشكل مباشر عن طريق إستخدام `user._name`. ولكن هناك مفهوم شائع هو أنّ الخاصيات التي تبدأ بشرطة سفلية `"_"` هي خاصيات داخلية وممنوع التعديل عليها من خارج الكائن.
185
183
186
-
## Using for compatibility
184
+
## استعمالها لغرض التوافقية
187
185
188
-
One of the great uses of accessors is that they allow to take control over a "regular" data property at any moment by replacing it with a getter and a setter and tweak its behavior.
186
+
إحدى استعمالات خاصيات الوصول هذه هي إتاحة الفرصة للتحكّم بخاصية بيانات "عادية" متى أردنا واستبدالها بدالتي جلب وضبط وتعديل سلوكها.
189
187
190
-
Imagine we started implementing user objects using data properties`name` and `age`:
188
+
لنقل مثلًا بأنّا بدأنا المشروع حيث كانت كائنات المستخدمين تستعمل خاصيات البيانات`name` and `age`:
191
189
192
190
```js
193
191
functionUser(name, age) {
194
192
this.name= name;
195
193
this.age= age;
196
194
}
197
195
198
-
let john =newUser("John", 25);
196
+
let john =newUser('John', 25);
199
197
200
-
alert(john.age); // 25
198
+
alert(john.age); // 25
201
199
```
202
200
203
-
...But sooner or later, things may change. Instead of`age`we may decide to store`birthday`, because it's more precise and convenient:
201
+
...و لكن عاجلاً ام آجلاً, يمكن أن تتغير الأمور. بدلاً من`age`يمكن ان نقرر التخزين في`birthday`, لأنه اكثر دقه و سهوله في الإستعمال:
204
202
205
203
```js
206
204
functionUser(name, birthday) {
207
205
this.name= name;
208
206
this.birthday= birthday;
209
207
}
210
208
211
-
let john =newUser("John", newDate(1992, 6, 1));
209
+
let john =newUser('John', newDate(1992, 6, 1));
212
210
```
213
211
214
-
Now what to do with the old code that still uses `age` property?
212
+
و لكن ماذا نفعل مع الكود القديم الذي ما زال يستخدم خاصية `age`؟
215
213
216
-
We can try to find all such places and fix them, but that takes time and can be hard to do if that code is used by many other people. And besides, `age`is a nice thing to have in `user`, right?
214
+
يمكن إن نبحث عن كل الأماكن التى تستخدمها و نقوم بالإصلاح, و لكن ذلك سوف يتغرق الوقت و يمكن ان يكون من الصعب تنفيذه إذا كان هذا الكود يستخدمه اشخاص آخرون. كما إن وجود عمر المستخدم, `age`داخل `user` هو امر جيد, اليس كذلك ؟
217
215
218
-
Let's keep it.
216
+
دعنا نبقي الخاصية كما هي.
219
217
220
-
Adding a getter for `age`solves the problem:
218
+
إضافة جالب للخاصية `age`سوف يقوم بحل المشكلة:
221
219
222
220
```js run no-beautify
223
221
functionUser(name, birthday) {
224
222
this.name= name;
225
223
this.birthday= birthday;
226
224
227
225
*!*
228
-
//age is calculated from the current date and birthday
226
+
//العمر هو الفرق بين التاريخ اليوم وتاريخ الميلاد
229
227
Object.defineProperty(this, "age", {
230
228
get() {
231
229
let todayYear =newDate().getFullYear();
@@ -237,8 +235,8 @@ function User(name, birthday) {
237
235
238
236
let john =newUser("John", newDate(1992, 6, 1));
239
237
240
-
alert( john.birthday ); //birthday is available
241
-
alert( john.age ); // ...as well as the age
238
+
alert( john.birthday ); //تاريخ الميلاد موجود
239
+
alert( john.age ); // ...وعمر المستخدم أيضًا
242
240
```
243
241
244
-
Now the old code works too and we've got a nice additional property.
242
+
الآن الكود القديم يعمل إيضاً و لدينا خاصية إضافية لطيفه.
0 commit comments