diff --git a/1-js/02-first-steps/16-function-expressions/article.md b/1-js/02-first-steps/16-function-expressions/article.md index a8ccd6c6c..62e61c884 100644 --- a/1-js/02-first-steps/16-function-expressions/article.md +++ b/1-js/02-first-steps/16-function-expressions/article.md @@ -1,84 +1,84 @@ -# Function expressions +# اعلان تابع Expression -In JavaScript, a function is not a "magical language structure", but a special kind of value. +در جاوااسکریپت، تابع یک "ساختار جادویی زبان" نیست، بلکه یک نوع خاصی از مقدار است. -The syntax that we used before is called a *Function Declaration*: +سینتکسی که ما قبلا استفاده کردیم یک *Function Declaration* نامیده می‌شود: ```js function sayHi() { - alert( "Hello" ); + alert( "سلام" ); } ``` -There is another syntax for creating a function that is called a *Function Expression*. +یک سینتکس دیگر هم برای ساخت تابع وجود دارد که *Function Expression* نامیده می‌شود. -It looks like this: +اینطور به نظر می‌رسد: ```js let sayHi = function() { - alert( "Hello" ); + alert( "سلام" ); }; ``` -Here, the function is created and assigned to the variable explicitly, like any other value. No matter how the function is defined, it's just a value stored in the variable `sayHi`. +اینجا، تابع ساخته شده و مثل هر مقدار دیگری، صراحتا به متغیر تخصیص داده شده است. فرقی ندارد که تابع چگونه تعریف شده، تابع فقط یک مقدار است که داخل متغیر `sayHi` ذخیره شده است. -The meaning of these code samples is the same: "create a function and put it into the variable `sayHi`". +معنی این مثال‌های کد یکسان است: "یک تابع بساز و آن را داخل متغیر `sayHi` بگذار". -We can even print out that value using `alert`: +ما حتی می‌توانیم آن مقدار را با استفاده از `alert` چاپ کنیم: ```js run function sayHi() { - alert( "Hello" ); + alert( "سلام" ); } *!* -alert( sayHi ); // shows the function code +alert( sayHi ); // کد تابع را نشان می‌دهد */!* ``` -Please note that the last line does not run the function, because there are no parentheses after `sayHi`. There are programming languages where any mention of a function name causes its execution, but JavaScript is not like that. +لطفا در نظر داشته باشید که آخرین خط تابع را اجرا نمی‌کند، چون هیچ پرانتزی بعد از `sayHi` وجود ندارد. زبان‌های برنامه نویسی‌ای وجود دارند که هر اشاره‌ای به اسم تابع سبب اجرا شدن آن می‌شود، اما جاوااسکریپت اینطور نیست. -In JavaScript, a function is a value, so we can deal with it as a value. The code above shows its string representation, which is the source code. +در جاوااسکریپت، تابع یک مقدار است، پس ما می‌توانیم مثل یک مقدار با آن رفتار کنیم. کد بالا نمایش رشته‌ای آن را انجام می‌دهد، که همان کد منبع است. -Surely, a function is a special value, in the sense that we can call it like `sayHi()`. +مسلما، تابع یک مقدار خاص است، به همین دلیل ما می‌توانیم آن را مثل `sayHi()` صدا بزنیم. -But it's still a value. So we can work with it like with other kinds of values. +اما تابع همچنان یک مقدار است. پس ما می‌توانیم با آن مثل انواع دیگر مقدارها کار کنیم. -We can copy a function to another variable: +ما می‌توانیم یک تابع را در یک متغیر دیگر کپی کنیم: ```js run no-beautify -function sayHi() { // (1) create - alert( "Hello" ); +function sayHi() { // (1) ساختن + alert( "سلام" ); } -let func = sayHi; // (2) copy +let func = sayHi; // (2) کپی کردن -func(); // Hello // (3) run the copy (it works)! -sayHi(); // Hello // this still works too (why wouldn't it) +func(); // سلام // (3) کپی را اجرا می‌کنیم (کار می‌کند!) +sayHi(); // سلام // هنوزم کار می‌کند (چرا نکند) ``` -Here's what happens above in detail: +چیزی که بالا اتفاق می‌افتد با جزییات اینجا هست: -1. The Function Declaration `(1)` creates the function and puts it into the variable named `sayHi`. -2. Line `(2)` copies it into the variable `func`. Please note again: there are no parentheses after `sayHi`. If there were, then `func = sayHi()` would write *the result of the call* `sayHi()` into `func`, not *the function* `sayHi` itself. -3. Now the function can be called as both `sayHi()` and `func()`. +1. Function Declaration `(1)` تابع را می‌سازد و آن را داخل متغیر `sayHi` قرار می‌دهد. +2. خط `(2)` آن را داخل متغیر `func` کپی می‌کند. لطفا دوباره در نظر داشته باشید: هیچ پرانتزی بعد از `sayHi` وجود ندارد. اگر وجود داشت، سپس `func = sayHi()` *نتیجه صدا زدن* `sayHi()` را در `func` می‌نوشت، نه خود *تابع* `sayHi`. +3. حالا تابع می‌تواند با `sayHi()` و `func()` صدا زده شود. -Note that we could also have used a Function Expression to declare `sayHi`, in the first line: +همچنین توجه داشته باشید که ما می‌توانستیم از یک Function Expression برای تعریف `sayHi` در خط اول، استفاده کنیم: ```js let sayHi = function() { - alert( "Hello" ); + alert( "سلام" ); }; let func = sayHi; // ... ``` -Everything would work the same. +همه چیز به همان شکل کار خواهد کرد. -````smart header="Why is there a semicolon at the end?" -You might wonder, why does Function Expression have a semicolon `;` at the end, but Function Declaration does not: +````smart header="چرا یک نقطه ویرگول در انتها وجود دارد؟" +شاید برای شما سوال باشد، چرا Function Expression در انتها نقطه ویرگول `;` دارد، اما Function Declaration ندارد: ```js function sayHi() { @@ -90,27 +90,27 @@ let sayHi = function() { }*!*;*/!* ``` -The answer is simple: -- There's no need for `;` at the end of code blocks and syntax structures that use them like `if { ... }`, `for { }`, `function f { }` etc. -- A Function Expression is used inside the statement: `let sayHi = ...;`, as a value. It's not a code block, but rather an assignment. The semicolon `;` is recommended at the end of statements, no matter what the value is. So the semicolon here is not related to the Function Expression itself, it just terminates the statement. +جواب ساده است: +- هیچ نیازی به `;` در انتهای بلوک‌های کد و ساختارهای سینتکس که از آنها مثل `if { ... }`، `for { }`، `function f { }` و... استفاده می‌شود نیست. +- یک Function Expression به عنوان یک مقدار، در داخل دستور استفاده می‌شود: `let sayHi = ...;`.این یک بلوک کد نیست، بلکه یک تخصیص دادن است. نقطه ویرگول `;` در انتهای دستورها پیشنهاد می‌شود، بدون توجه به اینکه مقدار چه چیزی باشد. پس نقطه ویرگول در اینجا به خود Function Expression مربوط نیست، فقط دستور را به پایان می‌رساند. ```` -## Callback functions +## تابع‌های Callback -Let's look at more examples of passing functions as values and using function expressions. +بیایید به مثال‌های بیشتری درباره استفاده کردن از تابع ها به عنوان مقدار و استفاده کردن از function expressions نگاه کنیم. -We'll write a function `ask(question, yes, no)` with three parameters: +ما یک تابع `ask(question, yes, no)` با سه پارامتر می‌نویسیم: `question` -: Text of the question +: متن سوال `yes` -: Function to run if the answer is "Yes" +: تابعی برای اجرا کردن اگر جواب "Yes" باشد `no` -: Function to run if the answer is "No" +: تابعی برای اجرا کردن اگر جواب "No" باشد -The function should ask the `question` and, depending on the user's answer, call `yes()` or `no()`: +تابع باید `question` را بپرسد، و بر اساس جواب کاربر، `yes()` یا `no()` را صدا بزند: ```js run *!* @@ -121,24 +121,24 @@ function ask(question, yes, no) { */!* function showOk() { - alert( "You agreed." ); + alert( "شما موافقت کردید." ); } function showCancel() { - alert( "You canceled the execution." ); + alert( "شما اجرا شدن را لغو کردید." ); } -// usage: functions showOk, showCancel are passed as arguments to ask -ask("Do you agree?", showOk, showCancel); +// نحوه استفاده: تابع‌های showOk، showCancel به عنوان آرگومان به ask داده شده‌اند +ask("آیا موافق هستید؟", showOk, showCancel); ``` -In practice, such functions are quite useful. The major difference between a real-life `ask` and the example above is that real-life functions use more complex ways to interact with the user than a simple `confirm`. In the browser, such function usually draws a nice-looking question window. But that's another story. +در عمل، چنین تابع هایی بسیار مفید هستند. تفاوت اصلی بین یک `ask` در زندگی واقعی و مثال بالا در این است که تابع‌ها در زندگی واقعی از راه‌های پیچیده‌تری نسبت به یک `confirm` ساده برای تعامل با کاربر استفاده استفاده می کنند. در مرورگر، چنین تابع‌هایی معمولا یک پنچره سوال زیبا را طرح می‌کنند. اما آن یک داستان دیگر است. -**The arguments `showOk` and `showCancel` of `ask` are called *callback functions* or just *callbacks*.** +**آرگومان‌های `showOk` و `showCancel` داخل `ask` *callback functions* یا فقط *callbacks* نامیده می‌شوند.** -The idea is that we pass a function and expect it to be "called back" later if necessary. In our case, `showOk` becomes the callback for "yes" answer, and `showCancel` for "no" answer. +ایده اینطور است که ما یک تابع را می‌دهیم و از آن توقع داریم که بعدا اگر نیاز شد "دوباره صدا زده شود". در مورد ما، `showOk` تبدیل به callback برای جواب "yes" می‌شود، و `showCancel` برای چواب "no". -We can use Function Expressions to write the same function much shorter: +ما می توانیم از Function Expressions برای نوشتن بسیار کوتاه‌تر همان تابع استفاده کنیم: ```js run no-beautify function ask(question, yes, no) { @@ -148,33 +148,33 @@ function ask(question, yes, no) { *!* ask( - "Do you agree?", - function() { alert("You agreed."); }, - function() { alert("You canceled the execution."); } + "آیا موافق هستید؟", + function() { alert("شما موافقت کردید."); }, + function() { alert("شما اجرا شدن را لغو کردید."); } ); */!* ``` -Here, functions are declared right inside the `ask(...)` call. They have no name, and so are called *anonymous*. Such functions are not accessible outside of `ask` (because they are not assigned to variables), but that's just what we want here. +اینجا، تابع‌ها دقیقا درون صدا زدن `ask(...)` تعریف شده اند. آنها هیچ اسمی ندارند، و بنابراین *anonymous* نامیده می شود. چنین تابع هایی بیرون از `ask` قابل دسترسی نیستند (چون آنها به متغیری تخصیص داده نشده اند)، اما این چیزی است که ما اینجا می‌خواهیم. -Such code appears in our scripts very naturally, it's in the spirit of JavaScript. +چنین کدی در اسکریپت‌های ما به طور طبیعی نمایان می شوند، این در ذات جاوااسکریپت است. -```smart header="A function is a value representing an \"action\"" -Regular values like strings or numbers represent the *data*. +```smart header="یک تابع مقداری است که یک \"عمل\" را نمایش می‌دهد" +مقدارهای معمولی مثل رشته‌ها یا عددها *داده* را نمایش می‌دهند. -A function can be perceived as an *action*. +یک تابع می‌تواند به عنوان یک *عمل* درک شود. -We can pass it between variables and run when we want. +ما می‌توانیم آن را بین متغیرها رد و بدل کنیم و هر زمان که بخواهیم اجرا کنیم. ``` -## Function Expression vs Function Declaration +## اعلان تابع Expression در مقابل تابع Declaration -Let's formulate the key differences between Function Declarations and Expressions. +بیایید تفاوت‌های کلیدی بین Function Declarations و Expressions را فرمول بندی کنیم. -First, the syntax: how to differentiate between them in the code. +اول، سینتکس: چگونه داخل کد بین آنها فرق قائل شویم. -- *Function Declaration:* a function, declared as a separate statement, in the main code flow. +- *Function Declaration:* یک تابع است، که به عنوان یک دستور جدا، در کد اصلی تعریف می‎شود. ```js // Function Declaration @@ -182,7 +182,7 @@ First, the syntax: how to differentiate between them in the code. return a + b; } ``` -- *Function Expression:* a function, created inside an expression or inside another syntax construct. Here, the function is created at the right side of the "assignment expression" `=`: +- *Function Expression:* یک تابع است، که در داخل یک عبارت یا داخل یک ساختار سینتکس دیگر ساخته می‌شود. اینجا، تابع سمت راست "عبارت تخصیص دادن" `=` ساخته شده است. ```js // Function Expression @@ -191,178 +191,178 @@ First, the syntax: how to differentiate between them in the code. }; ``` -The more subtle difference is *when* a function is created by the JavaScript engine. +تفاوت‌های نامحسوس بیشتر *زمانی* ایجاد می‌شوند که یک تابع توسط موتور جاوااسکریپت ساخته می‌شود. -**A Function Expression is created when the execution reaches it and is usable only from that moment.** +**یک Function Expression زمانی ساخته می‌شود که اجرا شدن به آن می‌رسد و فقط از همان لحظه قابل استفاده است.** -Once the execution flow passes to the right side of the assignment `let sum = function…` -- here we go, the function is created and can be used (assigned, called, etc. ) from now on. +بلافاصله که جریان اجرا شدن به سمت راست تخصیص دادن `let sum = function...` برسد -- د برو که رفتیم، تابع از آن لحظه ساخته شده و می‌تواند استفاده شود (تخصیص داده شود، صدا زده شود، و...). -Function Declarations are different. +Function Declarations متفاوت هستند. -**A Function Declaration can be called earlier than it is defined.** +**یک Function Declaration می‌تواند زودتر از زمانی که تعریف شده باشد صدا شده شود.** -For example, a global Function Declaration is visible in the whole script, no matter where it is. +برای مثال، یک Function Declaration سراسری داخل کل اسکریپت قابل رویت است، هیچ فرقی ندارد که کجا باشد. -That's due to internal algorithms. When JavaScript prepares to run the script, it first looks for global Function Declarations in it and creates the functions. We can think of it as an "initialization stage". +این به دلیل الگوریتم‌های داخلی است. زمانی که جاوااسکریپت برای اجرای اسکریپت آماده می‌شود، اول به دنبال Function Declarationهای سراسری می‌گردد و تابع‌ها را می‌سازد. ما می‌توانیم به عنوان یک "مرحله مقداردهی اولیه" به آن فکر کنیم. -And after all Function Declarations are processed, the code is executed. So it has access to these functions. +و بعد از اینکه همه Function Declarations پردازش شدند، کد اجرا می‌شود. پس به این تابع‌ها دسترسی دارد. -For example, this works: +برای مثال، این کار می‌کند: ```js run refresh untrusted *!* -sayHi("John"); // Hello, John +sayHi("John"); // سلام، John */!* function sayHi(name) { - alert( `Hello, ${name}` ); + alert( `سلام، ${name}` ); } ``` -The Function Declaration `sayHi` is created when JavaScript is preparing to start the script and is visible everywhere in it. +Function Declaration `sayHi` زمانی که جاوااسکریپت برای شروع اسکریپت در حال آماده شدن است ساخته می‌شود و هرجایی داخل آن قابل رویت است. -...If it were a Function Expression, then it wouldn't work: +...اگر این یک Function Expression بود، سپس کار نمی‌کرد: ```js run refresh untrusted *!* -sayHi("John"); // error! +sayHi("John"); // ارور! */!* -let sayHi = function(name) { // (*) no magic any more - alert( `Hello, ${name}` ); +let sayHi = function(name) { // (*) دیگر جادویی وجود ندارد + alert( `سلام، ${name}` ); }; ``` -Function Expressions are created when the execution reaches them. That would happen only in the line `(*)`. Too late. +Function Expressions زمانی که اجرا شدن به آنها می‌رسد ساخته می‌شوند. این فقط در خط `(*)` اتفاق می‌افتد. خیلی دیر است. -Another special feature of Function Declarations is their block scope. +یکی دیگر از ویژگی‌های Function Declaration ویژگی block scope آنها است. -**In strict mode, when a Function Declaration is within a code block, it's visible everywhere inside that block. But not outside of it.** +**در حالت سختگیرانه(strict mode)، زمانی که یک Function Declaration داخل یک بلوک کد است، همه جای آن بلوک قابل رویت است. اما نه خارج از آن.** -For instance, let's imagine that we need to declare a function `welcome()` depending on the `age` variable that we get during runtime. And then we plan to use it some time later. +برای مثال، بیایید تصور کنیم که می‌خواهیم یک تابع `welcome()` تعریف کنیم که به متغیر `age` بستگی دارد که آن را زمان اجرا دریافت می‌کنیم. و سپس می‌خواهیم از آن بعدا استفاده کنیم. -If we use Function Declaration, it won't work as intended: +اگر ما از Function Declaration استفاده کنیم، آن طور که در نظر داریم کار نمی‌کند: ```js run -let age = prompt("What is your age?", 18); +let age = prompt("سن شما چقدر است؟", 18); -// conditionally declare a function +// بر اساس شرط یک تابع تعریف کن if (age < 18) { function welcome() { - alert("Hello!"); + alert("سلام!"); } } else { function welcome() { - alert("Greetings!"); + alert("درود!"); } } -// ...use it later +// ...بعدا از آن استفاده کن *!* -welcome(); // Error: welcome is not defined +welcome(); // ارور: welcome تعریف نشده است */!* ``` -That's because a Function Declaration is only visible inside the code block in which it resides. +دلیل آن این است که یک Function Declaration فقط داخل بلوک کدی که داخل آن مستقر است قابل رویت است. -Here's another example: +اینجا یک مثال دیگر داریم: ```js run -let age = 16; // take 16 as an example +let age = 16; // 16 را به عنوان یک مثال دریافت کنید if (age < 18) { *!* - welcome(); // \ (runs) + welcome(); // \ (اجرا می‌شود) */!* // | function welcome() { // | - alert("Hello!"); // | Function Declaration is available - } // | everywhere in the block where it's declared + alert("سلام!"); // | Function Declaration در دسترس است + } // | هرجایی از بلوکی که داخل آن تعریف شده است // | *!* - welcome(); // / (runs) + welcome(); // / (اجرا می‌شود) */!* } else { function welcome() { - alert("Greetings!"); + alert("درود!"); } } -// Here we're out of curly braces, -// so we can not see Function Declarations made inside of them. +// اینجا ما بیرون از آکولادها هستیم، +// پس ما نمی‌توانیم Function Declarationهایی که داخل آنها ساخته شده‌اند را رویت کنیم. *!* -welcome(); // Error: welcome is not defined +welcome(); // ارور: welcome تعریف نشده است */!* ``` -What can we do to make `welcome` visible outside of `if`? +ما چه کاری می‌توانیم انجام دهیم تا `welcome` را بیرون از `if` قابل رویت کنیم؟ -The correct approach would be to use a Function Expression and assign `welcome` to the variable that is declared outside of `if` and has the proper visibility. +رویکرد درست می‌تواند این باشد که از Function Expression استفاده کنیم و `welcome` را به متغیری تخصیص بدهیم که خارج از `if` تعریف شده باشد و قابل رویت باشد. -This code works as intended: +این کد به طوری که در نظر داریم کار می‌کند: ```js run -let age = prompt("What is your age?", 18); +let age = prompt("سن شما چقدر است؟", 18); let welcome; if (age < 18) { welcome = function() { - alert("Hello!"); + alert("سلام!"); }; } else { welcome = function() { - alert("Greetings!"); + alert("درود!"); }; } *!* -welcome(); // ok now +welcome(); // الان درست است */!* ``` -Or we could simplify it even further using a question mark operator `?`: +یا حتی ما می‌توانیم آن را با استفاده از عملگر علامت سوال `?` ساده‌تر کنیم: ```js run -let age = prompt("What is your age?", 18); +let age = prompt("سن شما چقدر است؟", 18); let welcome = (age < 18) ? - function() { alert("Hello!"); } : - function() { alert("Greetings!"); }; + function() { alert("سلام!"); } : + function() { alert("درود!"); }; *!* -welcome(); // ok now +welcome(); // الان درست است */!* ``` -```smart header="When to choose Function Declaration versus Function Expression?" -As a rule of thumb, when we need to declare a function, the first to consider is Function Declaration syntax. It gives more freedom in how to organize our code, because we can call such functions before they are declared. +```smart header="چه زمانی Function Declaration را انتخاب کنیم و چه زمانی Function Expression؟" +به عنوان یک قاعده کلی، زمانی که ما نیاز به تعریف یک تابع داریم، اولین چیزی که باید سراغ آن برویم سینتکس Function Declaration است. آن به ما آزادی بیشتری برای سازماندهی کردن کد مان به ما می‌دهد، چون ما می‌توانیم چنین تابع‌هایی را قبل از اینکه تعریف شوند صدا بزنیم. -That's also better for readability, as it's easier to look up `function f(…) {…}` in the code than `let f = function(…) {…};`. Function Declarations are more "eye-catching". +همچنین آن برای خوانایی نیز بهتر است، چون پیدا کردن `function f(...) {...}` در کد راحت تر است از `let f = function(...) {...}`. Function Declarationها "چشم نوازتر" هستند. -...But if a Function Declaration does not suit us for some reason, or we need a conditional declaration (we've just seen an example), then Function Expression should be used. +...اما اگر یک Function Declaration برای ما به دلایلی مناسب نبود، یا ما یک تعریف بر اساس شرط نیاز داشتیم (که به تازگی یک مثال از آن دیدیم)، سپس Function Expression باید استفاده شود. ``` -## Summary +## خلاصه -- Functions are values. They can be assigned, copied or declared in any place of the code. -- If the function is declared as a separate statement in the main code flow, that's called a "Function Declaration". -- If the function is created as a part of an expression, it's called a "Function Expression". -- Function Declarations are processed before the code block is executed. They are visible everywhere in the block. -- Function Expressions are created when the execution flow reaches them. +- تابع‌ها مقدار هستند. آنها می‌توانند هرجای کد تخصیص داده شوند، کپی شوند یا تعریف شوند. +- اگر تابع به عنوان یک دستور جداگانه در جریان کد اصلی تعریف شده باشد، یک "Function Declaration" نامیده می‌شود. +- اگر تابع به عنوان بخشی از یک عبارت ساخته شده باشد، یک "Function Expression" نامیده می‌شود. +- Function Declarations قبل از اینکه بلوک کد اجرا شود پردازش می‌شوند. آنها از هرجای بلوک قابل رویت هستند. +- Function Expressions زمانی که جریان اصلی به آنها می‌رسد ساخته می‌شوند. -In most cases when we need to declare a function, a Function Declaration is preferable, because it is visible prior to the declaration itself. That gives us more flexibility in code organization, and is usually more readable. +در اکثر موارد زمانی که ما می‌خواهیم یک تابع تعریف کنیم، یک Function Declaration ترجیح داده می‌شود، چون قبل از اینکه تعریف شود قابل رویت است. آن به ما انعطاف بیشتری برای سازماندهی کد می‌دهد، و معمولا خواناتر است. -So we should use a Function Expression only when a Function Declaration is not fit for the task. We've seen a couple of examples of that in this chapter, and will see more in the future. +پس ما باید فقط زمانی از Function Expression استفاده کنیم که Function Declaration برای کار مناسب نباشد. ما یک جفت مثال از آن در این فصل دیدیم، و در آینده بیشتر خواهیم دید.