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
```smart header="This article is for understanding old scripts"
5
-
The information in this article is useful for understanding old scripts.
4
+
```smart header="هذه المقالة من أجل فهم النصوص القديمة"
5
+
المعلومات داخل هذه المقالة تساعدنا فى فهم النصوص القديمة أكثر ولا تحتوي علي أي معلومات عن كيفية كتابة كود جديد
6
6
7
-
That's not how we write a new code.
8
7
```
9
8
10
-
In the very first chapter about [variables](info:variables), we mentioned three ways of variable declaration:
9
+
ذكرنا في أوائل الفصول حين تكلمنا عن [المتغيرات](info:variables), ذكرنا ثلاث طرائق للتصريح عنها:
11
10
12
11
1.`let`
13
12
2.`const`
14
13
3.`var`
15
14
16
-
`let` and `const` behave exactly the same way in terms of Lexical Environments.
17
15
18
-
But `var` is a very different beast, that originates from very old times. It's generally not used in modern scripts, but still lurks in the old ones.
16
+
تصرّف كلا الإفادتين `let` و`const` بذات الطريقة (بالمقايسة مع البيئات المُعجمية).
19
17
20
-
If you don't plan on meeting such scripts you may even skip this chapter or postpone it, but then there's a chance that it bites you later.
18
+
بينما `var` فهو وحش آخر مختلف جذريًا ويعود في أصله إلى قرون سحيقة. لا نستعمله عادةً في السكربتات الحديثة ولكنّك ستجده حتمًا خلف إحدى صخور السكربتات القديمة.
19
+
20
+
لو لم ترغب بالتعرّف على هذه السكربتات فيمكنك تخطّي هذا الفصل أو تأجيله لوقت لاحق. ولكن لا تنسَ احتمالية ندمك لاحقًا فيغدر بك هذا الوحش.
21
+
22
+
من أول وهلة نرى بأنّ تصرّف `var` يشابه تصرّف `let`، أي أنّه يُصرّح (مثل الثاني) عن متغير:
21
23
22
-
From the first sight, `var` behaves similar to `let`. That is, declares a variable:
23
24
24
25
```js run
25
26
functionsayHi() {
26
-
var phrase ="Hello"; //local variable, "var" instead of "let"
27
+
var phrase ="Hello"; //متغير محلي، استعملنا «var» بدل «let»
27
28
28
29
alert(phrase); // Hello
29
30
}
30
31
31
32
sayHi();
32
33
33
-
alert(phrase); // Error, phrase is not defined
34
+
alert(phrase); // خطأ، phrase غير معرّف
35
+
34
36
```
35
37
36
-
...But here are the differences.
38
+
ولكن... ما خفي كان أعظم. إليك الفروق.
37
39
38
40
## "var" has no block scope
39
41
40
-
Variables, declared with `var`, are either function-wide or global. They are visible through blocks.
42
+
حين نصرّح عن المتغيرات باستعمال `var` نكون جعلناها معروفة للدالة كاملةً (لو كانت في دالة) أو عمومية في السكربت. يمكنك أن ترى تلك المتغيرات إن اخترقت «جدران» الكُتل.
43
+
44
+
مثال:
41
45
42
-
For instance:
43
46
44
47
```js run
45
48
if (true) {
46
-
var test =true; //use "var" instead of "let"
49
+
var test =true; //نستعمل «var» بدل «let»
47
50
}
48
51
49
-
*!*
50
-
alert(test); // true, the variable lives after if
51
-
*/!*
52
+
alert(test); // الناتج true، أي أنّ المتغير «حيّ يُرزق» بعد إفادة if
53
+
52
54
```
53
55
54
-
As `var` ignores code blocks, we've got a global variable `test`.
55
56
56
-
If we used `let test` instead of `var test`, then the variable would only be visible inside `if`:
57
+
تجاهل `var` كتل الشيفرة، وبهذا صار متغير `test` عموميًا.
58
+
59
+
لو استعملنا `let test` بدل `var test` فسيكون المتغير ظاهرًا لباقي الشيفرة داخل إفادة `if` فقط لا غير:
60
+
57
61
58
62
```js run
59
63
if (true) {
60
-
let test =true; //use "let"
64
+
let test =true; //نستعمل «let»
61
65
}
62
66
63
-
*!*
64
-
alert(test); // Error: test is not defined
65
-
*/!*
66
-
```
67
+
alert(test); // خطأ: لم يُعرّف عن test
67
68
68
-
The same thing for loops: `var` cannot be block- or loop-local:
69
+
```
70
+
يسري الأمر ذاته على الحلقات فلا يمكن أن يكون `var` محليًا حسب الكتلة أو حسب الحلقة:
69
71
70
72
```js
71
73
for (var i =0; i <10; i++) {
72
74
// ...
73
75
}
74
76
75
-
*!*
76
-
alert(i); // 10, "i" is visible after loop, it's a global variable
77
-
*/!*
77
+
alert(i); // 10، ظهر «i» بعد الحلقة فهو متغير عمومي
78
+
78
79
```
79
80
80
-
If a code block is inside a function, then `var` becomes a function-level variable:
81
+
لو كتبت كتلة شيفرة في دالة فسيصير `var` متغيرًا على مستوى الدالة كاملةً.
81
82
82
83
```js run
83
84
functionsayHi() {
84
85
if (true) {
85
86
var phrase ="Hello";
86
87
}
87
88
88
-
alert(phrase); //works
89
+
alert(phrase); //يمكننا فعل هذا
89
90
}
90
91
91
92
sayHi();
92
-
alert(phrase); // Error: phrase is not defined (Check the Developer Console)
93
+
alert(phrase); // خطأ: phrase غير معرّف (طالِع مِعراض المطوّر)
94
+
93
95
```
94
96
95
-
As we can see, `var` pierces through `if`, `for` or other code blocks. That's because a long time ago in JavaScript blocks had no Lexical Environments. And `var` is a remnant of that.
97
+
كما نرى فإفادة `var` تخترق كُتل `if` و`for` وغيرها من كُتل شيفرة. يعزو ذلك إلى أنّه في الزمن الماضي الجميل لم تكن لكُتل جافاسكربت بيئات مُعجمية. و`var` إحدى آثار ذلك الزمن.
98
+
99
+
## تُعالج التصريحات باستعمال `var` عند بدء الدالة
96
100
97
-
## "var" declarations are processed at the function start
101
+
ُعالج التصريحات باستعمال `var` متى ما بدأت الدالة (أو بدأ السكربت، للمتغيرات العمومية).
98
102
99
-
`var` declarations are processed when the function starts (or script starts for globals).
103
+
أي أنّ متغيرات `var` تُعرّف من بداية الدالة مهما كان مكان تعريفها (هذا لو لم يكن التعريف في دالة متداخلة أخرى).
100
104
101
-
In other words, `var` variables are defined from the beginning of the function, no matter where the definition is (assuming that the definition is not in the nested function).
105
+
يعني ذلك أنّ هذه الشيفرة:
102
106
103
-
So this code:
104
107
105
108
```js run
106
109
functionsayHi() {
107
110
phrase ="Hello";
108
111
109
112
alert(phrase);
110
113
111
-
*!*
112
114
var phrase;
113
-
*/!*
114
115
}
115
116
sayHi();
116
-
```
117
117
118
-
...Is technically the same as this (moved `var phrase` above):
118
+
```
119
+
متطابقة تقنيًا مع هذه (بتحريك `var phrase` إلى أعلى):
119
120
120
121
```js run
121
122
functionsayHi() {
122
-
*!*
123
123
var phrase;
124
-
*/!*
125
124
126
125
phrase ="Hello";
127
126
128
127
alert(phrase);
129
128
}
130
129
sayHi();
131
-
```
132
130
133
-
...Or even as this (remember, code blocks are ignored):
131
+
```
134
132
133
+
أو حتى هذه (لا تنسَ بأنّ كُتل الشيفرات مُهملة):
135
134
```js run
136
135
functionsayHi() {
137
136
phrase ="Hello"; // (*)
138
137
139
-
*!*
140
138
if (false) {
141
139
var phrase;
142
140
}
143
-
*/!*
144
141
145
142
alert(phrase);
146
143
}
147
144
sayHi();
145
+
148
146
```
147
+
يدعو الناس هذا السلوك بسلوك «الطفو» _hoisting_ (أو الرفع) إذ أنّ متغيرات `var` «تطفو» إلى أعلى الدالة (أو ترتفع إلى أعلاها).
149
148
150
-
People also call such behavior "hoisting" (raising), because all `var` are "hoisted" (raised) to the top of the function.
149
+
أي أنّه في المثال أعلاه، الفرع `if (false)` من الإفادة لا يعمل قط ولكن هذا ليس بمهم، إذ أنّ `var` داخله سيُعالج في بداية الدالة، وحين تصل عملية التنفيذ إلى `(*)` سيكون المتغير موجودًا لا محالة.
151
150
152
-
So in the example above, `if (false)` branch never executes, but that doesn't matter. The `var` inside it is processed in the beginning of the function, so at the moment of `(*)` the variable exists.
151
+
**التصريحات تطفو صحيح، ولكنّ ليس عبارات الإسناد.**
153
152
154
-
**Declarations are hoisted, but assignments are not.**
153
+
الأفضل لو نمثّل ذلك في هذا المثال:
155
154
156
-
That's best demonstrated with an example:
157
155
158
156
```js run
159
157
functionsayHi() {
160
158
alert(phrase);
161
159
162
-
*!*
163
160
var phrase ="Hello";
164
-
*/!*
165
161
}
166
162
167
163
sayHi();
164
+
168
165
```
169
166
170
-
The line `var phrase = "Hello"` has two actions in it:
167
+
في السطر `var phrase = "Hello"` إجراءان اثنان:
168
+
169
+
1. التصريح عن المتغير باستعمال `var`
170
+
2. إسناد قيمة للمتغير باستعمال `=`.
171
171
172
-
1. Variable declaration `var`
173
-
2. Variable assignment `=`.
172
+
يتعامل المحرّك مع التصريحات متى بدء تنفيذ الدالة (إذ التصريحات تطفو)، ولكنّ عبارة الإسناد لا تعمل إلّا حيثما ظهرت، فقط. إذًا فالشيفرة تعمل بهذا النحو فعليًا:
174
173
175
-
The declaration is processed at the start of function execution ("hoisted"), but the assignment always works at the place where it appears. So the code works essentially like this:
176
174
177
175
```js run
178
176
functionsayHi() {
179
-
*!*
180
-
var phrase; // declaration works at the start...
181
-
*/!*
177
+
var phrase; // بادئ ذي بدء، يعمل التصريح...
182
178
183
-
alert(phrase); //undefined
179
+
alert(phrase); //غير معرّف
184
180
185
-
*!*
186
-
phrase ="Hello"; // ...assignment - when the execution reaches it.
187
-
*/!*
181
+
phrase ="Hello"; // ...هنا.
188
182
}
189
183
190
184
sayHi();
185
+
191
186
```
192
187
193
-
Because all `var` declarations are processed at the function start, we can reference them at any place. But variables are undefined until the assignments.
188
+
يُعالج المحرّك التصريحات `var` حين تبدأ الدوال، وبهذا يمكننا الإشارة إليها أينما أردنا في الشيفرة. ولكن انتبه فالمتغيرات غير معرّفة حتى تُسند إليها قيم.
189
+
190
+
في الأمثلة أعلاه عمل التابِع `alert` دون أيّ أخطاء إذ أن المتغير `phrase` موجود. ولكن لم تُسند فيه قيمة بعد فعرض `undefined`.
191
+
194
192
195
-
In both examples above `alert` runs without an error, because the variable `phrase` exists. But its value is not yet assigned, so it shows `undefined`.
193
+
### تعريف الدالة المناداة تواً (IIFE)
196
194
197
-
### IIFE
195
+
في الماضي كان هناك فقط `var`, وليس له مستوي كتلة, لكن المبرمجين إخترعوا طريقة لحل ذلك. التي تسمي
198
196
199
-
As in the past there was only `var`, and it has no block-level visibility, programmers invented a way to emulate it. What they did was called "immediately-invoked function expressions" (abbreviated as IIFE).
That's not something we should use nowadays, but you can find them in old scripts.
199
+
هذا لا يستخدم حالياً, لكن تستطيع إيجادهم في النصوص القديمة.
202
200
203
-
An IIFE looks like this:
201
+
طريقة كتابة (IIFE):
204
202
205
203
```js run
206
204
(function() {
@@ -211,13 +209,13 @@ An IIFE looks like this:
211
209
212
210
})();
213
211
```
212
+
هذا يعتبر تعريف دالة صُنعت وتمت مناداتها على الفور. لذلك يتم تنفيذ الكود ولها متغيراتها الخاصة.
214
213
215
-
Here a Function Expression is created and immediately called. So the code executes right away and has its own private variables.
214
+
يتم تغليف تعريف الدالة يتم تغليفه بداخل قوسين (function {...})`, لأن عندما تقابل جافاسكريبت `"function"` في الكود الأساسي, تفهمها علي أنها بداية تعريف دالة ولكن بدون إسم لذلك يعطينا خطأ:
216
215
217
-
The Function Expression is wrapped with parenthesis `(function {...})`, because when JavaScript meets `"function"` in the main code flow, it understands it as the start of a Function Declaration. But a Function Declaration must have a name, so this kind of code will give an error:
218
216
219
217
```js run
220
-
//Try to declare and immediately call a function
218
+
//محاولة صنع دالة فورية التنفيذ
221
219
function() { // <-- Error: Function statements require a function name
222
220
223
221
let message ="Hello";
@@ -226,19 +224,19 @@ function() { // <-- Error: Function statements require a function name
226
224
227
225
}();
228
226
```
229
-
230
-
Even if we say: "okay, let's add a name", that won't work, as JavaScript does not allow Function Declarations to be called immediately:
227
+
حتي لو وضعنا إسم, لن يعمل هذا, لأن جافاسكريبت لا تسمح بتعريف دالة ستتم مناداتها فورياً:
231
228
232
229
```js run
233
-
//syntax error because of parentheses below
230
+
//هذا خطأ بسبب الأقواس الموجودة بالأسفل
234
231
functiongo() {
235
232
236
-
}();// <-- can't call Function Declaration immediately
233
+
}();
237
234
```
238
235
239
-
So, the parentheses around the function is a trick to show JavaScript that the function is created in the context of another expression, and hence it's a Function Expression: it needs no name and can be called immediately.
236
+
لذلك, الأقواس حول الدالة تعتبر خدعة لجعل جافاسكريبت فهم أننا نصنع سياق أخر للتعريف, لذلك إن تعريف الدالة: لا يحتاج إلي اسم لذلك تتم مناداتها علي الفور
237
+
240
238
241
-
There exist other ways besides parentheses to tell JavaScript that we mean a Function Expression:
239
+
هناك أيضاً طرق أخرى:
242
240
243
241
```js run
244
242
// Ways to create IIFE
@@ -260,15 +258,14 @@ There exist other ways besides parentheses to tell JavaScript that we mean a Fun
260
258
}();
261
259
```
262
260
263
-
In all the above cases we declare a Function Expression and run it immediately. Let's note again: nowadays there's no reason to write such code.
261
+
## ملخص
264
262
265
-
## Summary
263
+
هناك فرقين جوهرين بين `var` موازنةً بِـ `let/const`:
266
264
267
-
There are two main differences of `var` compared to `let/const`:
265
+
1. ليس لمتغيرات `var` نطاقًا كتليًا وأصغر نطاق لها هو في الدوال.
266
+
2. تُعالج التصريحات باستعمال `var` عند بدء الدالة (أو بدء السكربت، للمتغيرات العمومية).
268
267
269
-
1.`var` variables have no block scope, they are visible minimum at the function level.
270
-
2.`var` declarations are processed at function start (script start for globals).
268
+
هناك فرق آخر صغير يتعلّق بالكائن العمومي وسنشرحه في الفصل التالي.
271
269
272
-
There's one more very minor difference related to the global object, that we'll cover in the next chapter.
270
+
بهذا، غالبًا ما يكون استعمال `var` أسوأ بكثير من `let` بعدما عرفت الفروق بينها، فالمتغيرات على مستوى الكُتل أمر رائع جدًا ولهذا السبب تمامًا أُضيفت `let` إلى معيار اللغة منذ زمن وصارت الآن الطريقة الأساسية (هي و`const`) للتصريح عن متغير.
273
271
274
-
These differences make `var` worse than `let` most of the time. Block-level variables is such a great thing. That's why `let` was introduced in the standard long ago, and is now a major way (along with `const`) to declare a variable.
0 commit comments