Skip to content

Commit c5fa82f

Browse files
authored
Merge pull request #21 from NgArab/master
Property getters and setters
2 parents 7cf6e75 + c896ea4 commit c5fa82f

2 files changed

Lines changed: 57 additions & 59 deletions

File tree

Lines changed: 55 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,39 @@
1+
# جالبات الخصائص وضابطاتها (Getters and Setters)
12

2-
# Property getters and setters
3+
يوجد نوعين من الخصائص.
34

4-
There are two kinds of properties.
5+
الأوّل هو خصائص البيانات _data properties_. نحن بالفعل نعلم كيف نتعامل مع هذا النوع. إذ كلّ ما استعملناه من البداية حتى الآن هو خصائص البيانات.
56

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_. هي دوال بشكل أساسي تجلب القيم و تضبطها, ولكن في الكود تظهرُ لنا وكأنها خصائص عادية.
78

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+
## الجالبات والضابطات
910

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`:
1312

1413
```js
1514
let obj = {
1615
*!*get propName()*/!* {
17-
// getter, the code executed on getting obj.propName
16+
// ‫جالب، يُستعمَل لجلب قيمة الخاصية obj.propName
1817
},
1918

2019
*!*set propName(value)*/!* {
21-
// setter, the code executed on setting obj.propName = value
20+
// ‫ضابط يُستعمَل لضبط قيمة الخاصية obj.propName إلى value
2221
}
2322
};
2423
```
2524

26-
The getter works when `obj.propName` is read, the setter -- when it is assigned.
25+
يستعمل الجالب عند قراءة الخاصية `obj.propName`, الضابط -- عند ضبط أو إسناد قيمة تلك الخاصية.
2726

28-
For instance, we have a `user` object with `name` and `surname`:
27+
لاحظ مثلا, لدينا كائن `user` و لديه `name` و `surname`:
2928

3029
```js
3130
let user = {
32-
name: "John",
33-
surname: "Smith"
31+
name: 'John',
32+
surname: 'Smith',
3433
};
3534
```
3635

37-
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) :
3837

3938
```js run
4039
let user = {
@@ -53,9 +52,9 @@ alert(user.fullName); // John Smith
5352
*/!*
5453
```
5554

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` على أنّها دالة, بل _قراءتها_ بشكل طبيعي: ونترك الجالب يقوم بعمله خلف الكواليس.
5756

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=`, سوف يحدث خطأ:
5958

6059
```js run
6160
let user = {
@@ -65,11 +64,11 @@ let user = {
6564
};
6665

6766
*!*
68-
user.fullName = "Test"; // Error (property has only a getter)
67+
user.fullName = "Test"; // خطأ (للخاصية جالب فقط)
6968
*/!*
7069
```
7170

72-
Let's fix it by adding a setter for `user.fullName`:
71+
هيًا نُصلح الخطأ ونُضيف ضابطًا للخاصية `user.fullName`:
7372

7473
```js run
7574
let user = {
@@ -87,29 +86,29 @@ let user = {
8786
*/!*
8887
};
8988

90-
// set fullName is executed with the given value.
89+
// ضبط fullName تم بالقيمة المعطاه.
9190
user.fullName = "Alice Cooper";
9291

9392
alert(user.name); // Alice
9493
alert(user.surname); // Cooper
9594
```
9695

97-
As the result, we have a "virtual" property `fullName`. It is readable and writable.
96+
و نتيجة لذلك, لدينا خاصية "وهمية" `fullName`. يمكننا قراءتها والكتابة عليها، ولكنها في واقع الأمر، غير موجودة.
9897

99-
## Accessor descriptors
98+
## واصفات الوصول (Accessor Descriptors)
10099

101-
Descriptors for accessor properties are different from those for data properties.
100+
واصِفات خصائص الوصول (Accessor Properties) تختلف عن واصِفات خصائص البيانات (Data Properties).
102101

103-
For accessor properties, there is no `value` or `writable`, but instead there are `get` and `set` functions.
102+
بالنسبة لخصائص الوصول, لا يوجد `value` او `writable`, و لكن بدلاً من ذلك يوجد دوال `get` و `set`.
104103

105-
That is, an accessor descriptor may have:
104+
أي, واصف الوصول يمكن ان يمتلك ما يلي:
106105

107-
- **`get`** -- a function without arguments, that works when a property is read,
108-
- **`set`** -- a function with one argument, that is called when the property is set,
109-
- **`enumerable`** -- same as for data properties,
110-
- **`configurable`** -- same as for data properties.
106+
- **`get`** -- داله لا تستقبل قيم, و تعمل عند قراءة الخاصية,
107+
- **`set`** -- داله تستقبل قيمة واحدة, و تعمل عند إرادة ضبة الخاصية,
108+
- **`enumerable`** -- خاصية قابلية الإحصاء وهي مشابهة لخاصيّات البيانات,
109+
- **`configurable`** -- خاصية قابلية إعادة الضبط وهي مشابهة لخاصيّات البيانات.
111110

112-
For instance, to create an accessor `fullName` with `defineProperty`, we can pass a descriptor with `get` and `set`:
111+
فمثلاً, لنُنشئ خاصية الوصول `fullName` بإستخدام `defineProperty`, يمكن أن نُمرر واصفاً مثل `get` و `set`:
113112

114113
```js run
115114
let user = {
@@ -134,13 +133,13 @@ alert(user.fullName); // John Smith
134133
for(let key in user) alert(key); // name, surname
135134
```
136135

137-
Please note that a property can be either an accessor (has `get/set` methods) or a data property (has a `value`), not both.
136+
يرجى ملاحظة أن الخاصية يمكن ان تكون خاصية وصول (لها طرق `get/set`) او خاصية بيانات (لديها `value`), و لكن ليس كلاهما.
138137

139-
If we try to supply both `get` and `value` in the same descriptor, there will be an error:
138+
لو حاولنا تقديم `get` و `value` معاً في نفس الواصف, سوف يحدث خطأ:
140139

141140
```js run
142141
*!*
143-
// Error: Invalid property descriptor.
142+
// خطأ: واصِف الخاصية غير صالح.
144143
*/!*
145144
Object.defineProperty({}, 'prop', {
146145
get() {
@@ -151,11 +150,11 @@ Object.defineProperty({}, 'prop', {
151150
});
152151
```
153152

154-
## Smarter getters/setters
153+
## الجوالب والضوابط الذكية
155154

156-
Getters/setters can be used as wrappers over "real" property values to gain more control over operations with them.
155+
يمكننا استعمال الجوالب والضوابط كأغلفة لقيم الخاصيات "الفعلية" لكى تستطيع التحكم اكثر في العمليات بينهم.
157156

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`:
159158

160159
```js run
161160
let user = {
@@ -165,67 +164,66 @@ let user = {
165164

166165
set name(value) {
167166
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');
169168
return;
170169
}
171170
this._name = value;
172-
}
171+
},
173172
};
174173

175-
user.name = "Pete";
174+
user.name = 'Pete';
176175
alert(user.name); // Pete
177176

178-
user.name = ""; // Name is too short...
177+
user.name = ''; // ...الإسم قصير جدا
179178
```
180179

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`, و الوصول سوف يكون عن طريق الجالبات و الضابطات.
184181

182+
عملياً, الكود الخارجي يمكن ان يصل الى الإسم بشكل مباشر عن طريق إستخدام `user._name`. ولكن هناك مفهوم شائع هو أنّ الخاصيات التي تبدأ بشرطة سفلية `"_"` هي خاصيات داخلية وممنوع التعديل عليها من خارج الكائن.
185183

186-
## Using for compatibility
184+
## استعمالها لغرض التوافقية
187185

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+
إحدى استعمالات خاصيات الوصول هذه هي إتاحة الفرصة للتحكّم بخاصية بيانات "عادية" متى أردنا واستبدالها بدالتي جلب وضبط وتعديل سلوكها.
189187

190-
Imagine we started implementing user objects using data properties `name` and `age`:
188+
لنقل مثلًا بأنّا بدأنا المشروع حيث كانت كائنات المستخدمين تستعمل خاصيات البيانات `name` and `age`:
191189

192190
```js
193191
function User(name, age) {
194192
this.name = name;
195193
this.age = age;
196194
}
197195

198-
let john = new User("John", 25);
196+
let john = new User('John', 25);
199197

200-
alert( john.age ); // 25
198+
alert(john.age); // 25
201199
```
202200

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`, لأنه اكثر دقه و سهوله في الإستعمال:
204202

205203
```js
206204
function User(name, birthday) {
207205
this.name = name;
208206
this.birthday = birthday;
209207
}
210208

211-
let john = new User("John", new Date(1992, 6, 1));
209+
let john = new User('John', new Date(1992, 6, 1));
212210
```
213211

214-
Now what to do with the old code that still uses `age` property?
212+
و لكن ماذا نفعل مع الكود القديم الذي ما زال يستخدم خاصية `age`؟
215213

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` هو امر جيد, اليس كذلك ؟
217215

218-
Let's keep it.
216+
دعنا نبقي الخاصية كما هي.
219217

220-
Adding a getter for `age` solves the problem:
218+
إضافة جالب للخاصية `age` سوف يقوم بحل المشكلة:
221219

222220
```js run no-beautify
223221
function User(name, birthday) {
224222
this.name = name;
225223
this.birthday = birthday;
226224

227225
*!*
228-
// age is calculated from the current date and birthday
226+
// العمر هو الفرق بين التاريخ اليوم وتاريخ الميلاد
229227
Object.defineProperty(this, "age", {
230228
get() {
231229
let todayYear = new Date().getFullYear();
@@ -237,8 +235,8 @@ function User(name, birthday) {
237235

238236
let john = new User("John", new Date(1992, 6, 1));
239237

240-
alert( john.birthday ); // birthday is available
241-
alert( john.age ); // ...as well as the age
238+
alert( john.birthday ); // تاريخ الميلاد موجود
239+
alert( john.age ); // ...وعمر المستخدم أيضًا
242240
```
243241

244-
Now the old code works too and we've got a nice additional property.
242+
الآن الكود القديم يعمل إيضاً و لدينا خاصية إضافية لطيفه.

1-js/07-object-properties/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
# Object properties configuration
1+
# خصائص تكوين الكائنات
22

3-
In this section we return to objects and study their properties even more in-depth.
3+
في هذا الفصل قمنا بالعودة الى الكائنات و دراسة خصائصها بشكل اعمق.

0 commit comments

Comments
 (0)