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
As a result we have two independent variables, each one is storing the string`"Hello!"`.
14
+
تكون النتيجة هي متغيران منفصلان كل منهما به كلمة`"Hello!"`.
15
15
16
16

17
17
18
-
Objects are not like that.
18
+
الكائنات ليست كذلك.
19
19
20
-
**A variable stores not the object itself, but its "address in memory", in other words "a reference" to it.**
20
+
**المتغير لا يحمل الكائن نفسه بل يحمل "عنوانه في الذاكرة" وبكلمات أخرى يحمل "مؤشر له".**
21
21
22
-
Here's the picture for the object:
22
+
هذه صورة الكائن:
23
23
24
24
```js
25
25
let user = {
26
-
name:"John"
26
+
name:"John",
27
27
};
28
28
```
29
29
30
30

31
31
32
-
Here, the object is stored somewhere in memory. And the variable `user`has a "reference" to it.
32
+
هنا يتم تخزين الكائن في مكان ما في الذاكرة والمتغير `user`لديه مؤشر لذلك المكان.
33
33
34
-
**When an object variable is copied -- the reference is copied, the object is not duplicated.**
34
+
**عندما يتم نسخ الكائن -- يتم نسخ المؤشر ولا يتم تكرار الكائن.**
35
35
36
36
For instance:
37
37
38
38
```js no-beautify
39
39
let user = { name:"John" };
40
40
41
-
let admin = user; //copy the reference
41
+
let admin = user; //ينسخ المؤشر
42
42
```
43
43
44
-
Now we have two variables, each one with the reference to the same object:
44
+
الآن لدينا متغيرين كل منهما به مؤشر لنفس الكائن:
45
45
46
46

47
47
48
-
We can use any variable to access the object and modify its contents:
48
+
يمكننا استخدام أي متغير لنصل للكائن ونعدل فيه:
49
49
50
50
```js run
51
51
let user = { name:'John' };
52
52
53
53
let admin = user;
54
54
55
55
*!*
56
-
admin.name='Pete'; //changed by the "admin" reference
56
+
admin.name='Pete'; //تم تغييرها بواسطة المؤشر "admin"
57
57
*/!*
58
58
59
-
alert(*!*user.name*/!*); //'Pete', changes are seen from the "user" reference
59
+
alert(*!*user.name*/!*); //'Pete', التغيرات مرئية بواسطة مؤشر "user"
60
60
```
61
61
62
-
The example above demonstrates that there is only one object. As if we had a cabinet with two keys and used one of them (`admin`) to get into it. Then, if we later use another key (`user`) we can see changes.
62
+
المثال بالأعلى يوضح أن لدينا كائن واحد فقط. فإذا كان لدينا متغيرين واستخدمنا احدهما للوصول للكائن (`admin`) فعندما نستخدم اللآخر (`user`) يمكن رؤية التغيرات.
63
63
64
-
## Comparison by reference
64
+
## المقارنة بالمؤشرات
65
65
66
-
The equality `==`and strict equality `===`operators for objects work exactly the same.
66
+
العامل `==`والعامل `===`هما نفس الشئ مع الكائنات.
67
67
68
-
**Two objects are equal only if they are the same object.**
68
+
**الكائنان يكونان متساويان فقط إذا كانا يشيران لنفس الكائن.**
69
69
70
-
Here two variables reference the same object, thus they are equal:
70
+
هنا المتغيران يشيران لنفس الكائن لذا هما متساويان:
71
71
72
72
```js run
73
73
let a = {};
74
-
let b = a; //copy the reference
74
+
let b = a; //نسخ المؤشر
75
75
76
-
alert(a == b); // true, both variables reference the same object
77
-
alert(a === b); // true
76
+
alert(a == b); // true, كلاهما يشيران لنفس الكائن
77
+
alert(a === b); // true
78
78
```
79
79
80
-
And here two independent objects are not equal, even though both are empty:
80
+
وهنا كائنان منفصلان غير متساويان حتى ولو كانا فارغين:
81
81
82
82
```js run
83
83
let a = {};
84
-
let b = {}; //two independent objects
84
+
let b = {}; //كائنان منفصلان
85
85
86
-
alert(a == b); // false
86
+
alert(a == b); // false
87
87
```
88
88
89
-
For comparisons like `obj1 > obj2`or for a comparison against a primitive `obj ==5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons occur very rarely, usually as a result of a coding mistake.
89
+
مقارنة مثل `obj1 > obj2`أو مقارنة كائن مع قيمة primitive `obj ==5` يتم تحويل الكائنات إلى primitives. سنتكلم لاحقًا عن طريقة التحويل ولكن في الحقيقة هذه المقارنات نادرًا ما تحدث وفي الغالب تكون خطأ برمجي.
90
90
91
-
## Cloning and merging, Object.assign
91
+
## نسخ ودمج, Object.assign
92
92
93
-
So, copying an object variable creates one more reference to the same object.
93
+
نسخ المتغير ينشئ مؤشر آخر لنفس الكائن.
94
94
95
-
But what if we need to duplicate an object? Create an independent copy, a clone?
95
+
لكن ماذا إذا أردنا نسخ الكائن نفسه كنسخة منفصلة ؟
96
96
97
-
That's also doable, but a little bit more difficult, because there's no built-in method for that in JavaScript. Actually, that's rarely needed. Copying by reference is good most of the time.
97
+
هذا ممكن ولكنه صعب قليلًا حيث لا توجد دالة جاهزة في الجافاسكربت تقوم بذلك. في الجقيقة هذا الأمر نادر الحدوث ودائمًا ما يكون نسخ المؤشرات هو الأكثر فاعلية.
98
98
99
-
But if we really want that, then we need to create a new object and replicate the structure of the existing one by iterating over its properties and copying them on the primitive level.
99
+
لكن إذا أردنا ذلك حقًا يمكننا فعل ذلك عن طريق عمل كائن آخر والمرور على خواص الكائن الحالي ونسخها واحدة تلو الأخرى.
100
100
101
-
Like this:
101
+
كالتالي:
102
102
103
103
```js run
104
104
let user = {
@@ -107,49 +107,50 @@ let user = {
107
107
};
108
108
109
109
*!*
110
-
let clone = {}; //the new empty object
110
+
let clone = {}; //كائن جديد فارغ
111
111
112
-
//let's copy all user properties into it
112
+
//هيا ننسخ كل خواص user له
113
113
for (let key in user) {
114
114
clone[key] = user[key];
115
115
}
116
116
*/!*
117
117
118
-
//now clone is a fully independent object with the same content
119
-
clone.name="Pete"; //changed the data in it
118
+
//الآن النسخة منفصلة تمامًا وبها نفس المحتوى
119
+
clone.name="Pete"; //تغيير البيانات
120
120
121
-
alert( user.name ); //still John in the original object
121
+
alert( user.name ); //تبقى John في الكائن الأصلي
122
122
```
123
123
124
-
Also we can use the method [Object.assign](mdn:js/Object/assign) for that.
124
+
أيضًا يمكننا استخدام [Object.assign](mdn:js/Object/assign) لذلك.
125
125
126
126
The syntax is:
127
127
128
128
```js
129
129
Object.assign(dest, [src1, src2, src3...])
130
130
```
131
131
132
-
- The first argument `dest` is a target object.
133
-
- Further arguments `src1, ..., srcN` (can be as many as needed) are source objects.
134
-
- It copies the properties of all source objects `src1, ..., srcN` into the target `dest`. In other words, properties of all arguments starting from the second are copied into the first object.
135
-
- The call returns `dest`.
132
+
- المعامل الأول `dest` هو الكائن المراد.
133
+
- باقي المعاملات `src1, ..., srcN` (يمكن أن تكون أي عدد) هي المصادر المراد نسخها.
134
+
- تقوم بنسخ خواص المصادر `src1, ..., srcN` إلى الهدف `dest`. بكلمات أخرى يتم نسخ الخواص من كل المعاملات بدءًا من الثاني ويتم وضعها في الأول.
135
+
- وترجع `dest`.
136
+
137
+
مثلًا يمكننا استخدامها لدمج العديد من الكائنات في كائن واحد:
136
138
137
-
For instance, we can use it to merge several objects into one:
138
139
```js
139
140
let user = { name:"John" };
140
141
141
142
let permissions1 = { canView:true };
142
143
let permissions2 = { canEdit:true };
143
144
144
145
*!*
145
-
//copies all properties from permissions1 and permissions2 into user
146
+
//نسخ كل الخواص من permissions1 و permissions2 إلى user
146
147
Object.assign(user, permissions1, permissions2);
147
148
*/!*
148
149
149
150
// now user = { name: "John", canView: true, canEdit: true }
150
151
```
151
152
152
-
If the copied property name already exists, it gets overwritten:
We also can use `Object.assign`to replace `for..in`loop for simple cloning:
163
+
إيضًا يمكننا استخدام `Object.assign`لاستبدال الحلقة التكرارية `for..in`في النسخ البسيط:
163
164
164
165
```js
165
166
let user = {
@@ -172,57 +173,58 @@ let clone = Object.assign({}, user);
172
173
*/!*
173
174
```
174
175
175
-
It copies all properties of `user` into the empty object and returns it.
176
+
تنسخ كل الخواص من `user` إلى كائن فارغ وترجعه.
177
+
178
+
## النسخ المتداخل
176
179
177
-
## Nested cloning
180
+
حتى الآن إفترضنا أن كل خواص `user` هي primitive. ولكن الخواص يمكن أن تكون مؤشرات لكائنات أخرى فماذا سنفعل ؟
178
181
179
-
Until now we assumed that all properties of `user` are primitive. But properties can be references to other objects. What to do with them?
182
+
مثل هذا:
180
183
181
-
Like this:
182
184
```js run
183
185
let user = {
184
-
name:"John",
185
-
sizes: {
186
-
height:182,
187
-
width:50
188
-
}
186
+
name:"John",
187
+
sizes: {
188
+
height:182,
189
+
width:50,
190
+
},
189
191
};
190
192
191
-
alert(user.sizes.height); // 182
193
+
alert(user.sizes.height); // 182
192
194
```
193
195
194
-
Now it's not enough to copy `clone.sizes=user.sizes`, because the `user.sizes`is an object, it will be copied by reference. So `clone`and`user`will share the same sizes:
196
+
الآن ليس كافيًا نسخ `clone.sizes=user.sizes` لأن `user.sizes`هو كائن وسيتم نسخ المؤشر ويكون `clone`و`user`لهما نفس الخاصية sizes:
195
197
196
-
Like this:
198
+
مثل هذا:
197
199
198
200
```js run
199
201
let user = {
200
-
name:"John",
201
-
sizes: {
202
-
height:182,
203
-
width:50
204
-
}
202
+
name:"John",
203
+
sizes: {
204
+
height:182,
205
+
width:50,
206
+
},
205
207
};
206
208
207
209
let clone =Object.assign({}, user);
208
210
209
-
alert(user.sizes===clone.sizes); // true, same object
211
+
alert(user.sizes===clone.sizes); // true, نفس الكائن
210
212
211
-
// user and clone share sizes
212
-
user.sizes.width++; //change a property from one place
213
-
alert(clone.sizes.width); // 51, see the result from the other one
213
+
// user و clone يتشاركان sizes
214
+
user.sizes.width++; //تغيير الخاصية من مكان
215
+
alert(clone.sizes.width); // 51, يجعل التغيير مئي في المكان الآخر
214
216
```
215
217
216
-
To fix that, we should use the cloning loop that examines each value of `user[key]`and, if it's an object, then replicate its structure as well. That is called a "deep cloning".
218
+
لإصلاح ذلك يجب استخدام حلقة نسخ تفصل كل `user[key]`وإذا كان كائن يتم إيضًا نسخ بنيته وهذا يسمى النسخ العميق "deep cloning".
217
219
218
-
There's a standard algorithm for deep cloning that handles the case above and more complex cases, called the [Structured cloning algorithm](https://html.spec.whatwg.org/multipage/structured-data.html#safe-passing-of-structured-data).
220
+
هناك خوارزمية لذلك تتعامل مع ما رأيناه في الأعلى أو أكثر تعقيدًا وتسمى [Structured cloning algorithm](https://html.spec.whatwg.org/multipage/structured-data.html#safe-passing-of-structured-data).
219
221
220
-
We can use recursion to implement it. Or, not to reinvent the wheel, take an existing implementation, for instance [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) from the JavaScript library [lodash](https://lodash.com).
222
+
يمكننا كتابتها باستخدام الغستدعاء الذاتي Recursion أو لا نعيد اختراع العدلة ونستخدم الدالة الجاهزة مثل [\_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) من مكتبة [lodash](https://lodash.com).
221
223
222
-
## Summary
224
+
## ملخص
223
225
224
-
Objects are assigned and copied by reference. In other words, a variable stores not the "object value", but a "reference" (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object.
226
+
الكائنات توضع وتنسخ بالمؤشرات أو بمعنى آخر أن المتغير لا يحمل القيمة نفسها ولكنه يحمل مؤشر لها أي عنوان هذه القيمة في الذاكرة. لذلك نسخ هذا المتغير أو تمريره لدالة لا ينسخ القيمة نفسها بل المؤشر.
225
227
226
-
All operations via copied references (like adding/removing properties) are performed on the same single object.
228
+
كل العمليات التي تتم بواسطة النسخة (مثل إضافة وحذف الخواص) تحدث على نفس الكائن.
227
229
228
-
To make a "real copy" (a clone) we can use `Object.assign`for the so-called "shallow copy" (nested objects are copied by reference) or a "deep cloning" function, such as [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
230
+
لعمل نسخة حقيقية يمكننا استخدام `Object.assign`لما يسمى "shallow copy" (الكائنات الداخلية تنسخ بالمؤشر) أو دالة "deep cloning" مثل [\_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
0 commit comments