<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های امیر محبی</title><link>https://virgool.ir/feed/@amirrmhbi</link><description></description><language>fa</language><pubDate>2026-11-12 06:28:36</pubDate><image><url>https://files.virgool.ir/upload/users/3308294/avatar/AtRI5u.jpg</url><title>امیر محبی</title><link>https://virgool.ir/@amirrmhbi</link></image><item><title>جاوا اسکریپت _ ES6</title><link>https://virgool.ir/@amirrmhbi/جاوا-اسکریپت-es6-izko55nxbofo</link><description>اکمااسکریپت (ECMAScript) 2015 یا ES6، ششمین و بزرگترین نسخه استاندارد ECMAScript است که استاندارد پیاده سازی جاوااسکریپت را مشخص میکند. ES6 تغییرات زیادی را در زبان جاواسکریپت اعمال کرد.بعد از این نسخه مقرر شده است که هر سال یک نسخه جدید با تغییرات کمتر توسط ECMAScript ارائه شود تا مانند ES6، شاهد تغییرات بسیار زیاد در یک نسخه نباشیم. نسخه های جدید ECMAScript را معمولا با نام ESNext یا +ES6 میشناسند.مانند متغیرهای محدود به بلوک (block-scoped variables)، لوپ جدیدی برای آرایه ها و اشیا و تغییرات بسیار زیاد دیگری که کار با جاوااسکریپت را راحت تر و دلچسب میکند. در ادامه به این تغییرات خواهیم پرداخت.letکلمه let برای تعریف متغیرها استفاده میشود. قبل از ES6 برای تعرریف یک متغیر باید از کلمهی var استفاده میکردیم.دو تفاوت اساسی بین let و var وجود دارد. متغیرهایی که با var تعریف شدهاند function-scoped هستند و به بالای محدوده خود به اصطلاح hoist میشوند ولی در عوض متغیرهایی که با let معرفی میشوند block-scoped هستند و hoist در آنها اتفاق نمیافتد.// ES6 syntax&#xA;for(let i = 0; i &lt; 5; i++) {&#xA;    console.log(i); // 0,1,2,3,4&#xA;}&#xA;console.log(i); // undefined&#xA;&#xA;&#xA;// ES5 syntax&#xA;for(var i = 0; i &lt; 5; i++) {&#xA;    console.log(i); // 0,1,2,3,4&#xA;}&#xA;console.log(i); // 5همینطور که در بالا میبینید متغیر i در بلوک اول خارج از حلقهی for قابل دسترس نیست.constکلمه ی جدید const این امکان تعریف مقادیر ثابت را فراهم میآورد. مقادیر ثابت (Constants)، فقط قابل خواندن هستند و امکان اختصاص (Assignment) دوباره را ندارند. همچنین مانند let، این مقادیر نیز block-scoped هستند.const PI = 3.14;&#xA;console.log(PI); // 3.14&#xA;&#xA;PI = 10; // errorالبته امکان تغییر ویژگیهای آرایهها و اشیا(Objects) وجود دارد.// Changing object property value&#xA;const PERSON = {name: &#34;Peter&#34;, age: 28};&#xA;console.log(PERSON.age); // 28&#xA;PERSON.age = 30;&#xA;console.log(PERSON.age); // 30&#xA;&#xA;// Changing array element&#xA;const COLORS = [&#34;red&#34;, &#34;green&#34;, &#34;blue&#34;];&#xA;console.log(COLORS[0]); // red&#xA;COLORS[0] = &#34;yellow&#34;&#xA;console.log(COLORS[0]); // yellowحلقهی for..ofحلقه جدید for..of امکان تکرار (iterate) بر روی آرایه و یا اشیا قابل تکرار (iterable) را به آسانی فراهم میکنند. همچنین کد داخل حلقه برای هر عنصر آرایه و یا شئ اجرا میشود.// Iterating over array&#xA;let letters = [&#34;a&#34;, &#34;b&#34;, &#34;c&#34;, &#34;d&#34;, &#34;e&#34;, &#34;f&#34;];&#xA;&#xA;for(let letter of letters) {&#xA;    console.log(letter); // a,b,c,d,e,f&#xA;}&#xA;&#xA;// Iterating over string&#xA;let greet = &#34;Hello World!&#34;&#xA;&#xA;for(let character of greet) {&#xA;    console.log(character); // H,e,l,l,o, ,W,o,r,l,d,!&#xA;}این حلقه بر روی اشیاء معمول جاوااسکریپت کار نمیکند. برای این اشیاء میتوان از حلقه for-in استفاده کرد.Template Literalsتمپلیت لیترال امکان ساخت رشته های (Strings) چند خطی و رشته های قابل الحاق (interpolation) را فراهم میکنند. با استفاده از این امکان، میتوان متغیرها و عبارات (expressions) را در هر قسمتی از یک رشته وارد کرد.تمپلیت لیترال با استفاده back-tick (``) نوشته میشوند و متغیر یا عبارتی که میخواهیم در آن وارد کنیم باید در داخل براکت بعد از یک علامت دلار ({...}$) نوشته شوند.// Simple multi-line string&#xA;let str = `The quick brown fox&#xA;    jumps over the lazy dog.`;&#xA;&#xA;// String with embedded variables and expression&#xA;let a = 10;&#xA;let b = 20;&#xA;let result = `The sum of ${a} and ${b} is ${a+b}.`;&#xA;console.log(result); // The sum of 10 and 20 is 30.در ES5 برای نوشتن کد بالا باید به این شکل عمل میکردیم:// Multi-line string&#xA;var str = &#39;The quick brown fox\n\t&#39;&#xA;    + &#39;jumps over the lazy dog.&#39;;&#xA;&#xA;// Creating string using variables and expression&#xA;var a = 10;&#xA;var b = 20;&#xA;var result = &#39;The sum of &#39; + a + &#39; and &#39; + b + &#39; is &#39; + (a+b) + &#39;.&#39;;&#xA;console.log(result); // The sum of 10 and 20 is 30.مقادیر پیشفرض برای توابعدر ES6 میتوان برای توابع مقادیر پیشفرضی را برای پارامترها تعیین کرد بدین معنی که اگر در زمانی که یک تابع فراخوانده میشود آرگومانی به آن ارائه نشود، تابع از مقدار پیشفرض استفاده میکند:function sayHello(name=&#39;World&#39;) {&#xA;    return `Hello ${name}!`;&#xA;}&#xA;&#xA;console.log(sayHello()); // Hello World!&#xA;console.log(sayHello(&#39;John&#39;)); // Hello John!در ES5 برای نوشتن کد بالا باید به این شکل عمل میکردیم:function sayHello(name) {&#xA;    var name = name || &#39;World&#39;; &#xA;    return &#39;Hello &#39; +  name + &#39;!&#39;;&#xA;}&#xA;&#xA;console.log(sayHello()); // Hello World!&#xA;console.log(sayHello(&#39;John&#39;)); // Hello John!Arrow Functionsاین نوع توابع امکان مختصر کردن نوشتن یک تابع expression را فراهم میکند. نوشتن این نوع توابع با استفاده از یک پیکان (&lt;=) صورت میگیرد:// Function Expression&#xA;var sum = function(a, b) {&#xA;    return a + b;&#xA;}&#xA;console.log(sum(2, 3)); // 5&#xA;&#xA;// Arrow function&#xA;var sum = (a, b) =&gt; a + b;&#xA;console.log(sum(2, 3)); // 5همانطور که در بالا میبینید، کلمه function و return در تعریف (declaration) تابع بالا وجود ندارد. زمانی که فقط یک پارامتر برای تابع وجود دارد، میتوان پرانتزها را نیز حذف کرد، ولی زمانی صفر پارامتر یا بیشتر از یک پارامتر وجود دارد، وجود پرانتزها الزامی است.همچنین، زمانی که بیش از یک عبارت (expression) در تابع وجود دارد،باید از براکتها ({}) استفاده و کلمه return در توابعی که مقدار بازگشتی دارند، وارد کرد.// Single parameter, single statement&#xA;var greet = name =&gt; alert(&#34;Hi &#34; + name + &#34;!&#34;);&#xA;greet(&#34;Peter&#34;); // Hi Peter!&#xA;&#xA;// Multiple arguments, single statement&#xA;var multiply = (x, y) =&gt; x * y;&#xA;alert(multiply(2, 3)); // 6&#xA;&#xA;&#xA;// Single parameter, multiple statements&#xA;var test = age =&gt; {&#xA;    if(age &gt; 18) {&#xA;        alert(&#34;Adult&#34;);&#xA;    } else {&#xA;        alert(&#34;Teenager&#34;);&#xA;    }&#xA;}&#xA;test(21); // Adult&#xA;&#xA;// Multiple parameters, multiple statements&#xA;var divide = (x, y) =&gt; {&#xA;    if(y != 0) {&#xA;        return x / y;&#xA;    }&#xA;}&#xA;alert(divide(10, 2)); // 5&#xA;&#xA;// No parameter, single statement&#xA;var hello = () =&gt; alert(&#39;Hello World!&#39;);&#xA;hello(); // Hello World!یک تفاوت مهم بین این نوع توابع و توابع معمول وجود دارد. برعکس توابع معمول، این نوع توابع مقدار this که برای خودشان باشد را ندارند و این مقدار را از تابع خارجی، جایی که تعریف شدهاند، میگیرند. برای فهم بهتر مثال زیر را در نظر بگیرید:function Person(nickname, country) {&#xA;    this.nickname = nickname;&#xA;    this.country = country;&#xA;    &#xA;    this.getInfo = function() {&#xA;        // Outer function context (Person object)&#xA;        return function() {&#xA;            // Inner function context (Global object &#39;Window&#39;)&#xA;            alert(this.constructor.name); // Window&#xA;            alert(&#34;Hi, I&#39;m &#34; + this.nickname + &#34; from &#34; + this.country);&#xA;        };&#xA;    }&#xA;}&#xA;&#xA;var p = new Person(&#39;Rick&#39;, &#39;Argentina&#39;);&#xA;var printInfo = p.getInfo();&#xA;printInfo(); // Hi, I&#39;m undefined from undefinedنوشتن کد بالا با استفاده از توابع پیکانی و template literals:function Person(nickname, country) {&#xA;    this.nickname = nickname;&#xA;    this.country = country;&#xA;    &#xA;    this.getInfo = function() {&#xA;        // Outer function context (Person object)&#xA;        return () =&gt; {&#xA;            // Inner function context (Person object)&#xA;            alert(this.constructor.name); // Person&#xA;            alert(`Hi, I&#39;m ${this.nickname} from ${this.country}`);&#xA;        };&#xA;    }&#xA;}&#xA;&#xA;let p = new Person(&#39;Rick&#39;, &#39;Argentina&#39;);&#xA;let printInfo = p.getInfo();&#xA;printInfo(); // Hi, I&#39;m Rick from Argentinaهمانطور که در بالا مشخص است، کلمهی this در مثال بالا به زمینه (context) تابعی که تابع پیکانی در آن قراردارد، که شیء Person میشود، اشاره دارد. ولی در مثال قبلی، کلمهی this به شیء گلوبال Window شاره دارد.کلاسها (Classes)در نسخه های ES5 و قبلتر، در جاوااسکریپت هرگز کلاس وجود نداشت. کلاسها در نسخه ES6 معرفی شدهاند که بسیار شبیه به کلاسهای موجود در دیگر زبانهای برنامه نویسی شیءگرا مانند جاوا، پیاچپی و ...، هستند اما نحوه کار کلاسهای جاوااسکریپت کاملا شبیه به دیگر زبانهای برنامه نویسی نیست. کلاسهای ES6 ساخت اشیاء و پیاده سازی وراثت (inheritance) با استفاده از کلمه extend را فراهم میکنند.در ES6 میتوان یک کلاس را با استفاده از کلمه class و نوشتن نام کلاس بعد از آن تعریف کرد. برای نوشتن نام یک کلاس، نوشتن آن به صورت TitleCase مرسوم است.class Rectangle {&#xA;    // Class constructor&#xA;    constructor(length, width) {&#xA;        this.length = length;&#xA;        this.width = width;&#xA;    }&#xA;    &#xA;    // Class method&#xA;    getArea() {&#xA;        return this.length * this.width;&#xA;    }&#xA;}&#xA;&#xA;// Square class inherits from the Rectangle class&#xA;class Square extends Rectangle {&#xA;    // Child class constructor&#xA;    constructor(length) {&#xA;        // Call parent&#39;s constructor&#xA;        super(length, length);&#xA;    }&#xA;    &#xA;    // Child class method&#xA;    getPerimeter() {&#xA;        return 2 * (this.length + this.width);&#xA;    }&#xA;}&#xA;&#xA;let rectangle = new Rectangle(5, 10);&#xA;alert(rectangle.getArea()); // 50&#xA;&#xA;let square = new Square(5);&#xA;alert(square.getArea()); // 25&#xA;alert(square.getPerimeter()); // 20&#xA;&#xA;alert(square instanceof Square); // true&#xA;alert(square instanceof Rectangle); // true&#xA;alert(rectangle instanceof Square); // falseدر مثال بالا، کلاس Square از کلاس Rectangle، با استفاده از کلمه extend، ارثبری میکند. ار کلاس هایی که از دیگر کلاس ها ارثبری میکنند، به عنوان derived classes و یا child classes یاد میشود.همچنین در کلاس های فرزند، برا دسترسی به زمینه (context) در constructor، باید از کلمه super استفاده کرد. به عنوان مثال اگر در مثال بالا super را حذف کنید و تابع getArea را بر روی شیء Square فراخوانی کنید، از آن جایی که تابع getArea نیاز به this دارد، ارور به وجود میآید.نکته: برعکس توابع، تعریف کلاسها Hoist نمیشود. بنابراین، باید قبل از دسترسی به کلاس آن را تعریف کنیم وگرنه با ReferenceError میشویم.Modulesقبل از ES6، پشتیبانی به صورت بومی (native) برای ماژول ها در جاوااسکریپت وجود نداشت. همه چیز در یک برنامه جاوا اسکریپت، به طور مثال متغیرها در فایل های مختلف، در یک محدوده (scope) بودند. ES6 ماژول برپایه فایل را معرفی کرد که در آن هر ماژول با یک فایل جدا ارائه میشود. حالا، میتوان از export و import در یک ماژول برای export یا import کردن متغیرها، توابع، کلاس ها و غیره، از/به ماژول ها و یا فایل های دیگر استفاده کرد.در مثال زیر یک فایل با نام main.js میسازیم:let greet = &#34;Hello World!&#34;&#xA;const PI = 3.14; &#xA;&#xA;function multiplyNumbers(a, b) {&#xA;    return a * b;&#xA;}&#xA;&#xA;// Exporting variables and functions&#xA;export { greet, PI, multiplyNumbers };حال یک فایل دیگر با نام app.js درست میکنیم:import { greet, PI, multiplyNumbers } from &#39;./main.js&#39;;&#xA;&#xA;alert(greet); // Hello World!&#xA;alert(PI); // 3.14&#xA;alert(multiplyNumbers(6, 15)); // 90در آخر یک فایل HTML با نام test.html درست میکنیم (به &#34;type=&#34;module در تگ script دقت کنید):&lt;!DOCTYPE html&gt;&#xA;&lt;html lang=&#34;en&#34;&gt;&#xA;&lt;head&gt;&#xA;    &lt;meta charset=&#34;utf-8&#34;&gt;&#xA;    &lt;title&gt;ES6 Module Demo&lt;/title&gt;&#xA;&lt;/head&gt;&#xA;&lt;body&gt;&#xA;    &lt;script type=&#34;module&#34; src=&#34;app.js&#34;&gt;&#xA;&lt;/body&gt;&#xA;&lt;/html&gt;The Rest Parametersنسخه ES6 ویژگی rest parameters معرفی کرده که به ما این اجازه را میدهد تا بتوان تعداد نامعلومی پارامتر را به یک تابع اختصاص داد. این ویژگی زمانی مفید است که میخواهید چند پارامتر به یک تابع بدهید ولی تعداد آن را نمیدانید.یک rest parameter با اضافه کردن اپراتور rest (...) به یک پارامتر ساخته میشود. rest parameter را فقط میتوان به عنوان آخرین پارامتر یک تابع تعریف کرد و تنها یک rest parameter در هر تابع میتواند وجود داشته باشد.function sortNames(...names) {&#xA;    return names.sort();&#xA;}&#xA;&#xA;alert(sortNames(&#34;Sarah&#34;, &#34;Harry&#34;, &#34;Peter&#34;)); // Harry,Peter,Sarah&#xA;alert(sortNames(&#34;Tony&#34;, &#34;Ben&#34;, &#34;Rick&#34;, &#34;Jos&#34;)); // John,Jos,Rick,Tonyزمانی که rest parameter تنها پارامتر موجود در تابع باشد، تمام آرگومان های وارد شده به تابع را میگیرد، درغیر این صورت تمام پارامترهایی که بعد از پارامترهای نامگذاری شده را از آن خود میکند.function myFunction(a, b, ...args) {&#xA;    return args;&#xA;}&#xA;&#xA;alert(myFunction(1, 2, 3, 4, 5)); // 3,4,5&#xA;alert(myFunction(-7, 5, 0, -2, 4.5, 1, 3)); // 0,-2,4.5,1,3نکته: rest parameter ارتباطی به REST (REpresentational State Transfer) ندارد.The Spread Operatorاین اپراتور، که با سه نقطه (...) مشخص میشود، دقیقا برعکس اپراتور rest عمل میکند. اپراتور spread (گسترش) یک آرایه را تفکیک و گسترده میکند و مقادیر آن را وارد تابع میکند.function addNumbers(a, b, c) {&#xA;    return a + b + c;&#xA;}&#xA;&#xA;let numbers = [5, 12, 8];&#xA;&#xA;// ES5 way of passing array as an argument of a function&#xA;alert(addNumbers.apply(null, numbers)); // 25&#xA;&#xA;// ES6 spread operator&#xA;alert(addNumbers(...numbers)); // 25اپراتور spread همچنین میتواند عناصر یک تابع را، بدون استفاده از متدهای push(), unshift() concat()و غیره، وارد یک آرایه دیگر کند.let pets = [&#34;Cat&#34;, &#34;Dog&#34;, &#34;Parrot&#34;];&#xA;let bugs = [&#34;Ant&#34;, &#34;Bee&#34;];&#xA;&#xA;// Creating an array by inserting elements from other arrays&#xA;let animals = [...pets, &#34;Tiger&#34;, &#34;Wolf&#34;, &#34;Zebra&#34;, ...bugs];&#xA;&#xA;alert(animals); // Cat,Dog,Parrot,Tiger,Wolf,Zebra,Ant,BeeDestructing Assignmentاین یک عبارت (expression) که خارج کردن مقادیر از یک آرایه یا ویژگی ها از یک شیء و تبدیل آنها به متغیرهای مجزا را آسان میکند.دو نوع destructing assignment وجود دارد. یک نوع برای آرایه ها و یکی برای اشیاء.The array destructing assignmentقبل از ES6 برای گرفتن یک مقدار مجزا از یک آرایه باید به صورت زیر عمل میکردیم:// ES5 syntax&#xA;var fruits = [&#34;Apple&#34;, &#34;Banana&#34;];&#xA;&#xA;var a = fruits[0];&#xA;var b = fruits[1];&#xA;alert(a); // Apple&#xA;alert(b); // Bananaدر ES6 به این گونه عمل میکنیم:// ES6 syntax&#xA;let fruits = [&#34;Apple&#34;, &#34;Banana&#34;];&#xA;&#xA;let [a, b] = fruits; // Array destructuring assignment&#xA;&#xA;alert(a); // Apple&#xA;alert(b); // Bananaهمچنین میتوان از اپراتور rest نیز استفاده کرد:// ES6 syntax&#xA;let fruits = [&#34;Apple&#34;, &#34;Banana&#34;, &#34;Mango&#34;];&#xA;&#xA;let [a, ...r] = fruits;&#xA;&#xA;alert(a); // Apple&#xA;alert(r); // Banana,Mango&#xA;alert(Array.isArray(r)); // trueThe object destructing assignmentقبل از ES6 برای گرفتن مقادیر ویژگی اشیاء باید به صورت زیر عمل میکردیم:// ES5 syntax&#xA;var person = {name: &#34;Peter&#34;, age: 28};&#xA;&#xA;var name = person.name;&#xA;var age = person.age;&#xA;&#xA;alert(name); // Peter&#xA;alert(age); // 28در ES6 به این گونه عمل میکنیم:// ES6 syntax&#xA;let person = {name: &#34;Peter&#34;, age: 28};&#xA;&#xA;let {name, age} = person; // Object destructuring assignment&#xA;&#xA;alert(name); // Peter&#xA;alert(age); // 28</description><category>امیر محبی</category><author>امیر محبی</author><pubDate>Sun, 08 Sep 2024 17:29:18 +0330</pubDate></item></channel></rss>