6. رشتهها
رشتههای جاوااسکریپت بسیار شبیه رشتههای موجود در PHP هستند.

6.1. اسکریپت [str-01]
اولین چیزی که باید درک کرد این است که به محض ایجاد یک رشته، دیگر نمیتوان آن را تغییر داد. روشهای متعددی برای تولید یک رشته جدید از روی رشته اصلی وجود دارد، اما خود رشته اصلی همیشه بدون تغییر باقی میماند. علاوه بر این، یک رشته میتواند از دو نوع باشد:
- [string] زمانی که با یک عبارت رشتهای مقداردهی اولیه میشود؛
- [object] زمانی که بهعنوان نمونهای از کلاس [String] ایجاد میشود؛
''use strict';
//رشتهها فقط-خواندنی هستند (نمیتوان آنها را تغییر داد)
//یک رشته
const chaîne1 = "abcd ";
// نوع
console.log("typeof(chaîne1)=", typeof (chaîne1));
//کاراکتر شمارهٔ ۲
console.log("chaîne1[2]=", chaîne1[2]);
//باعث خطا میشود
chaîne1[2] = "0";
اجرا
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Temp\19-09-01\javascript\strings\str-01.js"
typeof(chaîne1)= string
chaîne1[2]= c
c:\Temp\19-09-01\javascript\strings\str-01.js:1
TypeError: Cannot assign to read only property '2' of string 'abcd '
at Object.<anonymous> (c:\Temp\19-09-01\javascript\strings\str-01.js:12:12)
at Generator.next (<anonymous>)
6.2. اسکریپت [str-02]
این اسکریپت نشان میدهد که یک رشتهٔ کاراکتری را میتوان به دو روش ساخت.
''use strict';
//رشتهها میتوانند از دو نوع باشند
//یک عبارت رشتهای
const chaîne1 = "abcd ";
// نوع
console.log("typeof(chaîne1)=", typeof (chaîne1));
// مثال رشته
const chaîne2 = new String("xyzt");
// نوع
console.log("typeof(chaîne2)=", typeof (chaîne2));
// نوتاسیون جایگزین (بدون 'new') – نوع [string] و نه [object]
const chaîne3 = String("12 34");
// نوع
console.log("typeof(chaîne3)=", typeof (chaîne3));
// نوع [string] و نوع [object] متدهای یکسانی را ارائه میدهند، که همان متدهای کلاس String هستند
console.log("chaîne1.length=", chaîne1.length);
console.log("chaîne2.length=", chaîne2.length);
توضیحات
- خط ۶: روش استاندارد برای تعریف یک رشته. [chaîne1] از نوع [string] خواهد بود؛
- خط ۱۰: یک رشته را میتوان با استفاده از سازنده کلاس [String] ساخت. [chaîne2] از نوع [object] خواهد بود؛
اجرا
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\strings\str-02.js"
typeof(chaîne1)= string
typeof(chaîne2)= object
typeof(chaîne3)= string
chaîne1.length= 5
chaîne2.length= 4
نوع [string] به متدهای کلاس [String] دسترسی دارد.
6.3. اسکریپت [str-03]
این اسکریپت یک رشتهٔ خاص را با درج متغیر نمایش میدهد.
'use strict';
//رشته
const chaîne = "Introduction à Javascript par l'exemple";
//رشته با درج متغیر
const str = `[${chaîne}].substr(3, 2)=` + chaîne.substr(3, 2)
console.log(str);
توضیحات
- خط ۶: رشتهها میتوانند شامل عبارتهای ${variable} باشند که با مقدار متغیر جایگزین میشوند. این منطق مشابه متغیرهای $ در رشتههای PHP است. به نشانهگذاری چنین رشتهای توجه کنید: این رشته در «تیرکهای پشتی» یا آپاستروفهای معکوس (AltGr-7 روی صفحهکلید فرانسوی) قرار میگیرد؛
اجرا
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Temp\19-09-01\javascript\strings\tempCodeRunnerFile.js"
[Introduction à Javascript par l'exemple].substr(3, 2)=ro
6.4. اسکریپت [str-04]
تلفیق رشتهای با متغیرها هنوز کافی نیست. در واقع، امکان جایگزینی یک عبارت به جای متغیر در عبارت ${variable} وجود ندارد. برای کسانی که با C برنامهنویسی کردهاند، هیچ چیز به خوبی توابع [printf, sprintf] برای نوشتن یا ساختن رشتههای قالببندیشده نیست. صدها توسعهدهنده هزاران بسته جاوااسکریپت ایجاد کردهاند که اکوسیستم وسیعی را شکل میدهند. وقتی نیازی باشد که جاوااسکریپت بهطور بومی آن را برآورده نمیکند، وقت آن است که به دنبال بستهای باشیم که آن نیاز را برآورده کند. برای این کار از مدیر بستههای [npm] استفاده میکنیم. این ابزار دارای یک گزینه [search] است که به شما امکان میدهد در میان توضیحات بستهها جستجو کنید. [npm] فهرست بستههایی را که با جستجو مطابقت دارند، بازمیگرداند. بنابراین، ما عبارت [sprintf] را در میان توضیحات بستهها جستجو خواهیم کرد:

- در ستون [4]، کلمات کلیدی برای بستهها در ستون [3]؛
- در ستون [5]، توضیحات بسته از ستون [3]؛
مرحله بعدی این است که به وبسایت ابزارهای [npm] و [https://www.npmjs.com/] مراجعه کرده و توضیحات بستهها را بخوانید:

در [3]، فهرست بستهها را مرور کرده و یکی را انتخاب کنید.

توضیحات بسته حاوی اطلاعاتی در مورد نحوه نصب و استفاده از آن است:

ما بسته [sprintf-js] را در یک ترمینال [VSCode] نصب میکنیم:

این نصب فایل [package.json] را که در ریشه پوشه [javascript] [2] قرار دارد، تغییر خواهد داد:

همانطور که در بالا مشاهده میشود، این بسته در [dependencies] نصب شده است، یعنی در بستههای مورد نیاز برای اجرای پروژه. شایان ذکر است که بستههای مورد نیاز فقط در حین توسعه پروژه در [devDependencies] قرار میگیرند. این بستهها در حین اجرا استفاده نمیشوند. این تمایز هنگام ایجاد نسخه نهایی پروژه برای استقرار اهمیت دارد. ابزارهایی برای این منظور در دسترس هستند:
- ادغام تمام فایلهای jS مورد نیاز برای اجرا در یک فایل واحد. بنابراین، بستههای [devDependencies] در این فایل نهایی گنجانده نمیشوند؛
- کوچکسازی این فایل، یعنی کاهش اندازه آن تا حد امکان. برای دستیابی به این هدف، برای مثال، تمام نظرات (کامنتها) حذف میشوند؛
- کد را «پیچیده» (obfuscate) کنید تا فهم آن دشوار شود. برای مثال، متغیرهای «rate»، «salary» و «tax» با متغیرهای «a»، «b» و «c» جایگزین خواهند شد؛
- انجام بهینهسازیهای دیگر؛
این بهینهسازی فایل نهایی برای پروژه jS در برنامهنویسی وب استفاده میشود. یک برنامه وب ممکن است به تعداد زیادی فایل جاوااسکریپت وابسته باشد. بارگذاری این فایلها در مرورگر میتواند نمایش صفحه اول برنامه را کند کند. بهینهسازی فوق با هدف بهبود این زمان بارگذاری انجام میشود. اگر کاربران زمان بارگذاری را بیش از حد طولانی بدانند، از برنامه استفاده نخواهند کرد.
اکنون که بسته [sprintf-js] را داریم، باید از آن استفاده کنیم. این اسکریپت [str-04] است:
'use strict';
// استفاده از یک بستهٔ خارجی برای دسترسی به تابع sprintf
import { sprintf } from 'sprintf-js';
// رشته
const chaîne = "Introduction à Javascript par l'exemple";
// متد
console.log(sprintf("[%s].substr(3,2)=[%s]", chaîne, chaîne.substr(3, 2)));
با ECMAScript 6، از کلمه کلیدی [import] برای وارد کردن ابجکتی که توسط یک بسته صادر شده است، استفاده میکنیم. برای اینکه بدانیم بسته چه چیزی را صادر میکند، میتوانیم به کد آن نگاه کنیم:

- در [1]، روی بستهٔ واردشده کلیک راست کنید؛
- در [2]، میخواهید تعریف آن را مشاهده کنید؛
- در [3-4]، میتوانید ببینید که این بسته تابعی به نام [sprintf] صادر میکند؛
تابع [sprintf] از بسته [sprintf-js] با استفاده از عبارت زیر وارد میشود:
import { sprintf } from 'sprintf-js';
کد کامل:
'use strict';
//استفاده از یک بستهٔ خارجی برای دسترسی به تابع sprintf
import { sprintf } from 'sprintf-js';
// رشته
const chaîne = "Introduction à Javascript par l'exemple";
// روش
console.log(sprintf("[%s].substr(3,2)=[%s]", chaîne, chaîne.substr(3, 2)));
نتایج زیر را تولید میکند:
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\strings\str-04.js"
c:\Temp\19-09-01\javascript\strings\str-04.js:3
import { sprintf } from 'sprintf-js';
^
SyntaxError: Unexpected token {
at new Script (vm.js:79:7)
at createScript (vm.js:251:10)
at Object.runInThisContext (vm.js:303:10)
at Module._compile (internal/modules/cjs/loader.js:657:28)
خط ۳: دستور [import] شناسایی نشد. این به این دلیل است که نسخهٔ 10.15.1 از [node.js] که در این دوره (سپتامبر 2019) استفاده میشود، هنوز با استاندارد ECMAScript برای وارد کردن بستههایی که بهعنوان ماژول شناخته میشوند، مطابقت ندارد. در سال ۲۰۱۹، [node.js] با استاندارد ماژولی به نام CommonJS مطابقت دارد. یکپارچهسازی ماژولهای ECMAScript از طریق [node.js] برای سال ۲۰۲۰ برنامهریزی شده است. بار دیگر، توسعهدهندگان به کار پرداخته و بستههایی را تولید کردهاند که امکان استفاده از ماژولهای ES6 را با [node.js] از هماکنون (۲۰۱۹) فراهم میکنند.
ما از بستهای به نام [esm] (ماژولهای ECMAScript) استفاده خواهیم کرد. آن را در ترمینال برای پروژه [javascript] نصب میکنیم:

در [4]، میتوانیم ببینیم که نصب بستههای [esm] و [1-3]، فایل [javascript/package.json] را تغییر داده است.
ما هنوز تمام نکردهایم. برای اینکه ماژول [esm] توسط [node.js] استفاده شود، باید [node.js] با آرگومان [-r esm] اجرا شود.
بنابراین پیکربندی افزونه [Code Runner] را برای [VSCode] تغییر میدهیم:


در [11]، آرگومان [-r esm] را اضافه کرده و پیکربندی را ذخیره (Ctrl-S) میکنیم.
اکنون میتوانیم اسکریپت [str-04] را اجرا کنیم:
'use strict';
// استفاده از یک بستهٔ خارجی برای دسترسی به تابع sprintf
import { sprintf } from 'sprintf-js';
// رشته
const chaîne = "Introduction à Javascript par l'exemple";
// متد substr
console.log(sprintf("[%s].substr(3,2)=[%s]", chaîne, chaîne.substr(3, 2)));

6.5. اسکریپت [str-05]
در اینجا آنچه مستندات درباره تابع [sprintf] میگوید:
جایگرینها در رشتهٔ قالب با % مشخص میشوند و پس از آن یک یا چند مورد از این عناصر به ترتیب زیر قرار میگیرند:
- یک عدد اختیاری که با علامت $ دنبال میشود و مشخص میکند کدام اندیس آرگومان برای مقدار استفاده شود. اگر مشخص نشود، آرگومانها به همان ترتیبی که در رشته ورودی قرار دارند، قرار میگیرند.
- یک علامت + اختیاری که باعث میشود برای مقادیر عددی، علامت مثبت یا منفی قبل از نتیجه قرار گیرد. به طور پیشفرض، فقط علامت - برای اعداد منفی استفاده میشود.
- یک مشخصکننده پدینگ اختیاری که مشخص میکند در صورت لزوم از کدام کاراکتر برای پدینگ استفاده شود. مقادیر ممکن عبارتند از 0 یا هر کاراکتر دیگری که با ' (نقلقول ساده) شروع شود. مقدار پیشفرض پد کردن با فاصله است.
- یک علامت اختیاری «-» که باعث میشود `sprintf` نتیجه این جایگذاری را چپتراز کند. پیشفرض، تراز کردن نتیجه به سمت راست است.
- یک عدد اختیاری که تعداد کاراکترهایی را که نتیجه باید داشته باشد مشخص میکند. اگر مقداری که باید بازگردانده شود کوتاهتر از این عدد باشد، نتیجه پُر خواهد شد. هنگامی که با مشخصکننده نوع j (JSON) استفاده میشود، طول پُر کردن، اندازه تب مورد استفاده برای تورفتگی را مشخص میکند.
- یک اصلاحگر اعشار اختیاری، شامل یک نقطه (.) و به دنبال آن یک عدد، که مشخص میکند برای اعداد ممیز شناور چند رقم باید نمایش داده شود. هنگامی که با مشخصکننده نوع g استفاده میشود، تعداد ارقام اعشاری معنادار را مشخص میکند. هنگامی که روی یک رشته استفاده شود، باعث میشود خروجی کوتاه شود.
- یک مشخصکننده نوع که میتواند هر یک از موارد زیر باشد:
- % — کاراکتر % را به صورت یک عبارت متنی برمیگرداند
- b — یک عدد صحیح را به صورت عدد دودویی برمیگرداند
- c — یک عدد صحیح را به صورت کاراکتری با آن مقدار ASCII برمیگرداند
- d یا i — یک عدد صحیح را به صورت عدد اعشاری علامتدار برمیگرداند
- e — یک عدد ممیز شناور را با نمایش علمی برمیگرداند
- u — یک عدد صحیح را به صورت اعشاری بدون علامت بازمیگرداند
- f — یک عدد اعشاری را بدون تغییر بازمیگرداند؛ برای توضیحات مربوط به دقت به بالا مراجعه کنید
- g — یک عدد اعشاری را بدون تغییر بازمیگرداند؛ برای توضیحات مربوط به دقت به بالا مراجعه کنید
- o — یک عدد صحیح را به صورت اکتال بازمیگرداند
- s — یک رشته را همانگونه که هست بازمیگرداند
- t — مقدار true یا false را برمیگرداند
- T — نوع آرگومان 1 را برمیگرداند
- v — مقدار اولیه آرگومان مشخص را برمیگرداند
- x — یک عدد صحیح را به صورت عدد هگزادسیمال (با حروف کوچک) بازمیگرداند
- X — یک عدد صحیح را به صورت عدد هگزادسیمال (با حروف بزرگ) بازمیگرداند
- j — یک شیء یا آرایه JavaScript را به صورت یک رشته رمزگذاریشده با JSON بازمیگرداند
اسکریپت [script-05] برخی از این فرمتها را پیادهسازی میکند:
'use strict';
// استفاده از یک بستهٔ خارجی برای دسترسی به تابع sprintf
import { sprintf } from 'sprintf-js';
//رشته
const chaîne = "Javascript";
// رشتههای کاراکتری
console.log(sprintf("[%s, %%s]=>[%s]", chaîne, chaîne));
console.log(sprintf("[%s, %%20s]=>[%20s]", chaîne, chaîne));
console.log(sprintf("[%s, %%-20s]=>[%-20s]", chaîne, chaîne));
// اعداد صحیح
console.log(sprintf("[%d, %%d]=>[%d]", 10, 10));
console.log(sprintf("[%d, %%4d]=>[%4d]", 10, 10));
console.log(sprintf("[%d, %%-4d]=>[%-4d]", 10, 10));
console.log(sprintf("[%d, %%04d]=>[%04d]", 10, 10));
// اعداد ممیز شناور
console.log(sprintf("[%f, %%f]=>[%f]", -10.5, -10.5));
console.log(sprintf("[%f, %%10.2f]=>[%10.2f]", -10.5, -10.5));
console.log(sprintf("[%f, %%-10.2f]=>[%-10.2f]", -10.5, -10.5));
console.log(sprintf("[%f, %%010.3f]=>[%010.3f]", -10.5, -10.5));
// json
console.log(sprintf("personne (%%j)=%j", { nom: "mathieu", âge: 34 }));
// نوع
console.log(sprintf("type personne (%%T)=%T", { nom: "mathieu", âge: 34 }));
// بولین
console.log(sprintf("booléen (%%t)=%t", 4 === 4));
اجرا
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\strings\str-05.js"
[Javascript, %s]=>[Javascript]
[Javascript, %20s]=>[ Javascript]
[Javascript, %-20s]=>[Javascript ]
[10, %d]=>[10]
[10, %4d]=>[ 10]
[10, %-4d]=>[10 ]
[10, %04d]=>[0010]
[-10.5, %f]=>[-10.5]
[-10.5, %10.2f]=>[ -10.50]
[-10.5, %-10.2f]=>[-10.50 ]
[-10.5, %010.3f]=>[-00010.500]
personne (%j)={"nom":"mathieu","âge":34}
type personne (%T)=object
booléen (%t)=true
6.6. اسکریپت [str-06]
اسکریپت [str-06] برخی از متدهای کلاس [String] را نشان میدهد که میتوان از آنها بر روی نوع [string] نیز استفاده کرد:
''use strict';
// استفاده از یک بستهٔ خارجی برای دسترسی به تابع sprintf
import { sprintf } from 'sprintf-js';
// رشته
const chaîne = " Introduction à Javascript ";
// چند روش
// substr(10,2): دو کاراکتر از موقعیت 10
console.log(sprintf("[%s].substr(10,2)=[%s]", chaîne, chaîne.substr(10, 2)));
// trim: حذف فاصلههای خالی در ابتدا و انتهای یک رشته (فاصلههای خالی = \b \t \r \n \f)
console.log(sprintf("[%s].trim()=[%s]", chaîne, chaîne.trim()));
// toLowerCase: تبدیل به حروف کوچک
console.log(sprintf("[%s].toLowerCase=[%s]", chaîne, chaîne.toLowerCase()));
// toUpperCase: تبدیل به حروف بزرگ
console.log(sprintf("[%s].toUpperCase=[%s]", chaîne, chaîne.toUpperCase()));
// indexOf: موقعیت رشته جستجو شده د ر داخل رشته؛ -1 اگر زیررشته وجود نداشته باشد
console.log(sprintf("[%s].indexOf('Java')=[%s]", chaîne, chaîne.indexOf('Java')));
console.log(sprintf("[%s].trim().indexOf('abcd')=[%s]", chaîne, chaîne.indexOf('abcd')));
//شامل: true اگر رشتهٔ جستجو شده در رشته وجود داشته باشد
console.log(sprintf("[%s].includes('Java')=[%s]", chaîne, chaîne.includes('Java')));
// length: طول رشته – این یک متد نیست بلکه یک ویژگی است
console.log(sprintf("[%s].length=[%s]", chaîne, chaîne.length));
// slice (7,10): کاراکترهای 7 تا 9
console.log(sprintf("[%s].slice(7,10)=[%s]", chaîne, chaîne.slice(7, 10)));
// match: در رشته به دنبال یک عبارت میگردد – این عبارت میتواند یک عبارت منظم باشد
// /intro/i: عبارت منظم که با رشته [intro] چه به صورت حروف بزرگ و چه کوچک مطابقت دارد
// مطابقتیافته را بازمیگرداند
console.log(sprintf("[%s].match(/intro/i)=[%s]", chaîne, chaîne.match(/intro/i)));
//replace: رشتهٔ string1 را با string2 در رشته جایگزین میکند
//اولین وقوع i را با x جایگزین میکند
console.log(sprintf("[%s].replace('i','x')=[%s]", chaîne, chaîne.replace('i', 'x')));
//تمام رخدادهای i را با x جایگزین میکند
///i/g یک عبارت منظم است که تمام (g) رخدادهای i را نشان میدهد
console.log(sprintf("[%s].replace(/i/g,'x')=[%s]", chaîne, chaîne.replace(/i/g, 'x')));
//split: رشته را به کلماتی تقسیم میکند که با پارامتر split از هم جدا شدهاند
// یک آرایه از این کلمات را بازمیگرداند
// /\s*/: کلماتی که با صفر یا چند فاصله از هم جدا شدهاند
console.log(sprintf("[%s].split(/\\s*/)=[%s]", chaîne, chaîne.split(/\s*/)));
// /\s+/: کلماتی که با یک یا چند فاصله از هم جدا شدهاند
console.log(sprintf("[%s].split(/\\s+/)=[%s]", chaîne, chaîne.split(/\s+/)));
اجرا
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\strings\str-06.js"
[ Introduction à Javascript ].substr(10,2)=[ti]
[ Introduction à Javascript ].trim()=[Introduction à Javascript]
[ Introduction à Javascript ].toLowerCase=[ introduction à javascript ]
[ Introduction à Javascript ].toUpperCase=[ INTRODUCTION À JAVASCRIPT ]
[ Introduction à Javascript ].indexOf('Java')=[17]
[ Introduction à Javascript ].trim().indexOf('abcd')=[-1]
[ Introduction à Javascript ].includes('Java')=[true]
[ Introduction à Javascript ].length=[28]
[ Introduction à Javascript ].slice(7,10)=[duc]
[ Introduction à Javascript ].match(/intro/i)=[Intro]
[ Introduction à Javascript ].replace('i','x')=[ Introductxon à Javascript ]
[ Introduction à Javascript ].replace(/i/g,'x')=[ Introductxon à Javascrxpt ]
[ Introduction à Javascript ].split(/\s*/)=[,I,n,t,r,o,d,u,c,t,i,o,n,à,J,a,v,a,s,c,r,i,p,t,]
[ Introduction à Javascript ].split(/\s+/)=[,Introduction,à,Javascript,]