ویرگول
ورودثبت نام
بیژن حجازی
بیژن حجازیسلام! نوشتن به منزله مطالعه «خود» هست. من بیشتر تو زمینه برنامه نویسی و روان شناسی مطلب میذارم. خوشحال میشم نظرات تون رو باهام در میون بذارین.
بیژن حجازی
بیژن حجازی
خواندن ۱۲ دقیقه·۴ سال پیش

رشته ها در javaScript

در jS با کمک متد هایی که رشته ها دارن می تونیم اعمال مد نظرمون رو انجام بدیم.
در jS با کمک متد هایی که رشته ها دارن می تونیم اعمال مد نظرمون رو انجام بدیم.

مقدمه

منظور از رشته (String) در زبان های برنامه نویسی رشته ای از کاراکتر هاست که می تونن در کنار هم یک کلمه، جمله یا عبارت های طولانی تر رو تشکیل بدن. این کاراکتر ها انواع و اقسام مختلفی دارن و از عدد گرفته تا حروف الفبا رو شامل میشن. حتی فضای خالی (space) و شکستن خط (Line break) هم کاراکتر حساب میشن. در ادامه این مقاله به بررسی رشته ها در jS می پردازیم.

اعلان

منظور از اعلان کردن یک متغیر (Declaration) اینه که به صورت رسمی برای یک متغیر نامی در نظر بگیریم. برای مثال در کد زیر متغیر name رو declare کردیم:

let name;

برای اعلان متغیر با توجه به نیازی که داریم باید از کلیدواژه مناسب استفاده کنیم. این کلیدواژه های در jS مدرن let و const هستن. برای مطالعه بیشتر در خصوص let و const این مقاله رو بخون. در اکثر مواقع رشته ها رو با let اعلان می کنیم. در کد زیر به همین متغیری که در کد بالا اعلان کردیم مقدار میدیم (Assignment):

name = 'bizhan';

در ضمن میشد که همزمان هم declare کنیم و هم مقدار بدیم. این طوری:

let name = 'bizhan';

رشته ها رو میشه درون " " و یا درون ' ' اعلان کرد. به " میگن Double Quotation mark و به ' میگن Single Quotation mark. در هر کدوم که اعلان میکنیم نباید جوری کد بنویسیم که jS قاطی کنه اول و آخر رشته رو. اگه قراره بخشی از خود رشته " داشته باشه باید کل رشته داخل ' ' محصور بشه و برعکس. مثلا کد زیر اشتباهه:

let sentence = 'Don't call me';

چون که jS گیج میشه که کدوم دو تا از ۳ تا ' رو ابتدا و انتهای رشته در نظر بگیره. کد بالا رو باید در حقیقت این طوری می نوشتیم:

let sentence = "Don't call me"

این طوری jS می فهمه که چون فقط تا ۲ " داریم این ها ابتدا و انتهای رشته هستن و هر چیزی بین این ها بخشی از رشته است.

Escape characters

خوب حالا فرض کن که یک جمله این طوری داریم:

The signs " and ' are used in jS.

این رو چطوری توی یک متغیر ذخیره کنیم؟! اگه توی ' ' ذخیره اش کنیم با ' قبل از are تداخل داره و اگه توی " ذخیرش کنیم با " قبل از signs تداخل داره!؟ در این موارد باید یک \ (به این کاراکتر میگن backslash) قبل از اون quotation mark داخل جمله که تداخل ایجاد میکنه قرار بدیم تا خنثی اش کنیم.

let sentence = "The signs \" and ' are used in jS."

خیلی چیزا رو میشه با این کاراکتر \ ترکیب کرد (حواست باشه با / که برای تقسیم اعداد استفاده میشه اشتباه نگیری). به این ها اصطلاحا میگن escape characters و اصل کاری هاش شامل این ها میشه:

  • \n خط را می شکند
  • \t فاصله زیاد ایجاد میکند
  • \\ a real backslash
  • \'
  • \"

مثلا فرض کن جمله زیر رو میخایم در یک متغیر ذخیره کنیم:

My Name
is Bizhan
Hejazi.

اگه مثل کد زیر بگیم jS گیج میشه چون " های ابتدا و انتهای رشته رو همیشه در یک خط باید قرار داد:

let sentence = " My Name is Bizhan Hejazi."

در این جاست که از n\ کمک میگیریم:

let sentence = "My Name\nis Bizhan\nHejazi"

برای مشاهده این ۳ خط جدا از هم باید از console.log کمک بگیریم:

console.log(sentence); // 3 lines

جنس داده

حالا که یک داده (data) رو در متغیر name ذخیره کردیم باید درک کنیم که جنس این داده (data type) اش چیه. در jS جنس داده های متنوعی داریم که String هم یکیش عه. برای درک جنس یک رشته در jS از عملگر typeof استفاده میکنیم. مثلا typeof متغیر name میشه 'string':

console.log(typeof name); // 'string'

در بالا ذکر کردیم که جنس داده های رشته String عه. ولی عملگر typeof بهمون 'string' داد ! عملگر typeof به طور پیش فرض جنس داده رو تبدیل به یک رشته lowercase میکنه و تحویل میده. برای مثال اگه متغیری از جنس Object داشتیم هم typeof اش میشد 'object' در حالی که جنس داده اش Object عه. اگر بخایم خیلی دقیق اظهار نظر کنیم باید گفت که متغیر name در حقیقت String literal هست چرا که وقتی با instanceof بررسی اش میکنیم String نیست! (اگه گیج شدی نگران نباش! در ادامه متوجه میشی)

console.log(name instanceof String); // false

در حالی که عملگر typeof میاد و جنس داده رو بررسی میکنه، عملگر instanceof بررسی میکنه که داده از روی چه کلاسی درست شده. به عبارتی عملگر instanceof وقتی کاربرد داره که با String object سر و کار داریم نه با String literal. برای اعلان کردن یک رشته به صورت String object باید این طوری بگیم:

let name = new String('bizhan'); console.log(typeof name); // 'object' console.log(name instanceof String); // true

در کد بالا برای این که از کلیدواژه new استفاده کردیم (این کلیدواژه واسه ایجاد object از روی کلاس استفاده میشه) متغیر name تبدیل به object ای شد که از روی کلاس String درست شده. برای همین typeof اش میشه 'object' و instanceof String اش true از آب در میاد.

از همین الان یاد بگیر که رشته ها رو به صورت literal اعلان کنی. استفاده از String object ها سرعت کد رو میاره پایین و مشکلات دیگری هم داره.

موقعیت کاراکتر

هر کاراکتری در یک رشته دارای موقعیت (index, position) عه. اولین کاراکتر هر رشته موقعیت ۰ داره و کاراکتر های بعدی به همین ترتیب موقعیت هاشون اضافه میشه. برای خوندن کاراکتری از یک رشته در یک موقعیت خاص می تونیم با رشته مثل آرایه رفتار کنیم و از [ ] استفاده کنیم.

let name = 'bizhan'; console.log(name[0]); // 'b' console.log(name[1]); // 'i'

اگر بخایم برعکس رشته رو بخونیم هم می تونیم از ویژگی (property) ای به نام length که طول رشته رو بهمون میده استفاده کنیم:

console.log(name[name.length - 1]); // 'n'

حالا برای تک به تک خوندن کاراکتر های یک رشته می تونیم از یک حلقه for ساده استفاده کنیم (سعی کن کدش رو اول خودت بنویسی حتی شده با سرچ تو گوگل):

for (let i = 0; i < name.length; i++) { console.log(name[i]); }

در ورژن های مدرن jS با حلقه for of این کار راحت تر صورت می گیره:

for (let char of name) { console.log(char); }

به کاری که در کد بالا کردن اصطلاحا میگن loop کردن در یک رشته.

تغییر ناپذیری

در زبان jS رشته ها تغییر ناپذیر هستن. این یعنی که شما می تونی کاراکتر هاش رو دونه دونه بخونی، بخشی از رشته رو ببری، حتی می تونی یک کاراکتر رو با کاراکتر جدید جایگزین کنی ... ولی همه ی این کار ها اثری روی متغیر اولیه نداره بلکه مقدار جدید return میشه و اون مقدار رو می تونی توی یک متغیر دیگه ذخیره کنی. اصطلاحا میگن که رشته ها immutable هستن. در مقایسه با رشته ها Array ها رو داریم که mutable هستن و می تونیم خود آرایه اولیه رو عوض کنیم. کد زیر رو در نظر بگیر:

let nums = [1,2,3,4,5,6,7,8,9]; nums[0] = 10; // WORKS

کد بالا بدون هیچ مشکلی اجرا میشه و مقدار متغیر nums که یک آرایه هست رو عوض میکنه. ولی اگه همین کار رو بخایم با یک رشته انجام بدیم هیچ اثری نداره (ارور نمیده ولی اثری هم نداره):

let name = 'bizhan'; name[0] = 'B'; // DOESN'T WORK

همین داستان دست نخورده باقی موندن رشته اصلی وقتی با متد های رشته ها هم کار میکنیم تکرار میشه و مقدار اولیه سالم باقی می مونه.

متد های رشته ها

اگه با برنامه نویسی شئ گرا آشنا باشی (OOP) می دونی که بر اساس class ای که یک object از روش نوشته میشه این object یک سری property ها و یک سری method هایی داره. در jS هم کلاس String داریم و می تونیم String Object درست کنیم تا از متد هاش بهره ببریم. ولی یک کار خیلی قشنگی که jS میکنه اینه که می تونیم با String literal هم از متد ها استفاده کنیم. وقتی که جلوی یک string literal نقطه میذاریم jS در نظر میگیره (هر چند واقعا مقدار ما object نباشه) که این یک object از کلاس String عه و مثلا یک object باهاش رفتار میکنه. مثلا متد includes بررسی میکنه که آیا مقدار خاصی در رشته وجود داره یا نه:

let name = 'bizhan'; console.log(name.includes('z')); // true

اگه با برنامه نویسی شئ گرا آشنا نیستی ایرادی نداره. بذار این طور برات توضیح بدم: متد ها ابزار های دم دستی ای هستن که می تونیم باهاشون یک سری اعمالی رو انجام بدیم. در ادامه به بررسی متد های مهمی که رشته ها دارن می پردازیم.

indexOf

این متد بررسی میکنه که اولین موقعیت یک رشته (می تونه یک کاراکتر باشه یا یک کلمه یا هر چی) کجای رشته است. اگر پیدا نکنه اون کاراکتر رو 1- بر می گردونه:

"banana".indexOf('n'); // 2 "my name is bizhan".indexOf('bizhan'); // 11

می تونستیم یک آرگومان (همین چیزایی که به متد ها میدیم توی پرانتز) دومی هم به متد indexOf بدیم که موقعیت شروع به جست و جو باشه و هر کاراکتری در موقعیت های قبلی رو بی خیال بشه.

"banana".indexOf('n',3); // 4

lastIndexOf

این متد هم مثل متد قبلی عه با این تفاوت که برعکس رشته رو بررسی میکنه و موقعیت آخرین حضور رشته مد نظر درون رشته اصلی رو میده. اگر هم پیدا نکنه 1- پس میده :

"banana".lastIndexOf('n'); // 4 "bizhan is always bizhan".lastIndexOf('bizhan'); // 17

می تونستیم یک آرگومان دومی هم به متد lastIndexOf بدیم که موقعیت شروع به جست و جو باشه و هر کاراکتری در موقعیت های قبلی رو بی خیال بشه. (به برعکس سیر کردن این متد دقت کن)

"banana".lastIndexOf('n', 3); // 2

replace

اولین حضور یک رشته رو درون یک رشته پیدا میکنه و با رشته دیگری جایگزین میکنه:

"I love music.".replace("music","movies");

دقت کن که این متد فقط اولین باری که اون کلمه پیدا میشه رو عوض میکنه. برای این که همه مصادیق رشته مد نظرت رو جایگزین کنی باید از متد replaceAll استفاده کنی. میشه از این دو تا متد حرفه ای تر هم استفاده کرد که در حوصله بحث نمی گنجه.

slice

این متد رشته رو برش میده. منظور از برش دادن یک رشته جدا کردن بخشی از رشته است. برای این که بدونه از کجا بریدن رو شروع کنه و کجا تموم کنه ۲ تا مقدار باید بهش بدیم که اولش موقعیت شروع به برش و دومیش موقعیت توقف برش عه (خود کاراکتری که در موقعیت توقف حضور داره بریده نمیشه چون مشخصا در این موقعیت بریدن متوقف میشه!)

let sentence = "She has 2 apples." let sliced = sentence.slice(0, 3); console.log(sentence); // 'She has 2 apples' console.log(sliced); // She

همون طوری که قبلا هم گفتیم رشته های immutable هستن و هر کاری که باهاشون بکنیم رشته اصلی تغییری نمیکنه. اگر به متد slice فقط یک مقدار بدیم برش رو از همون موقعیت شروع میکنه و تا آخر رشته رو می بره. مثلا با همین متغیر های بالا:

let sliced = sentence.slice(4); console.log(sliced) // 'has 2 apples.'

search

این متد رشته رو برای اولین حضور یک regular Expression بررسی میکنه و موقعیت اش رو به ما میده. منظور از regular expression ترکیبی از نشانه ها و علائم هست که می تونه مصادیقی در رشته داشته باشه. بذار با مثال توضیح بدم. با متد indexOf می تونیم موقعیت کاراکتر 9 در جمله زیر رو گیر بیاریم:

let sentence = "I have 9 apples." console.log(sentence.indexOf('9'));

ولی اگه نمیدونستیم عدد مون دقیقا چنده چی؟! اینجاست که Regular Expression ها به کار ما میان که به اختصار بهشون میگن RegEx. RegEx ها مخصوص زبان jS نیستن و در اکثر زبان ها با مقدار ناچیزی تفاوت میشه ازشون استفاده کرد. مثلا در همین چالش بالا:

console.log(sentence.search(/\d/)); // 7

در کد بالا بخشی که bold شده همون RegEx عه. RegEx ها موضوع شیرین، ساده و قدرتمندی هستن که آشنایی و تسلط بهشون به هر برنامه نویسی توانایی بالایی میده. در این مقاله تخصصا به RegEx ها نمی پردازیم.

match

این متد قسمت هایی از رشته ما رو که با RegEx خاصی match میشه استخراج میکنه. مثلا در کد زیر همه کاراکتر های Capital رو از رشته اولیه استخراج کردیم و به صورت یک array تحویل گرفتیم:

let input = 'AaBbCcDd'; console.log(input.match(/[A-Z]/g)); // ['A','B','C','D'];

در خصوص RegEx ها بحث تخصصی میشه و در حوصله این مقاله نیست.

toUpperCase

این متد رشته رو به صورت UpperCase تحویل میده. یعنی همه کاراکتر هاش Capital میشن. مشابه همین متد toLowerCase هم داریم که باز اون همه کاراکتر های رو small میکنه.

let upper = "bizhan".toUpperCase(); console.log(upper); // BIZHAN

split

از متد های مهم رشته ها هست. این متد یک رشته رو به آرایه تبدیل میکنه (واسه مطالعه درباره آرایه ها به این لینک مراجعه کن). همون طوری که از اسمش مشخصه یک رشته رو جدا میکنه. بر اساس چی؟! بر اساس چیزی که بهش میدیم. مثلا در کد زیر بر اساس space رشته رو جدا میکنه:

let items = "a b c d" const chars = items.split(' ');

حالا در مثال زیر میخایم کلمات یک جمله رو در قالب یک آرایه ذخیره کنیم:

let sentence = 'My name is Bizhan.'; const words = sentence.split(' ');

یا مثلا در مثال زیر مقادیر جدا شده توسط comma رو میخایم به آرایه تبدیل کنیم:

let digits = '1,2,3,4,5,6,7'; const numbers = digits.split(',');

startsWith

این متد بررسی میکنه که آیا رشته ما با مقدار خاصی شروع میشه یا خیر. برای مثال:

let companies = "Apple, Microsoft, Samsung" console.log(companies.startsWith("Apple")); // true console.log(companies.startsWith("apple")); // false

همون طوری که تو مثال بالا باید متوجه شده باشی متد startsWith به Capital و‌ Small بودن حساسه برای همینه که خط سوم false شد. مشابه همین متد endsWith رو هم داریم که این یکی بررسی میکنه آیا رشته ما با مقدار خاصی تموم میشه یا نه.

trim

این متد اضافاتی مثل space و line break رو از ابتدا و انتهای رشته ما پاک میکنه. این بحث به خصوص زمانی مهمه که میخایم داده ها رو از سمت کاربر دریافت کنیم و نیازی به اضافات نداریم.

let name = ' bizhan '; let trimmed = name.trim(); console.log(trimmed); // 'bizhan'

نتیجه گیری

مانور دادن روی رشته ها یک مهارت مهمه. برای مثال یک توسعه دهنده وب که اطلاعات رو به صورت رشته از سمت کاربر دریافت میکنه باید بتونه که بررسی کنه آیا این اطلاعات به فرمت صحیح، به صورت ایمن و بدون هیچ گونه عبارت های خرابکارانه، با حجم مناسب و ... اومدن یا نه. همین طور خیلی وقتا لازمه ظاهر نمایش رشته رو عوض کنیم. مثلا ممکنه توی Database برای کاهش حجم به صورت UpperCase ذخیره کنیم ولی به کاربر به صورت lower case نشون بدیم. من در این مقاله اصلی ترین متد های رشته ها در jS رو گفتم و هنوزم متد هایی هستن (که به نظرم اون قدر ها پر کاربرد نبودن) که میتونی از رفرنس ها مطالعه کنی. امیدوارم از مقاله خوشت اومده باشه و در نهایت این که ممنون میشم اگه من رو به یک کامنت مهمون کنی.


javascriptjsبرنامه نویسیتوسعه وبweb development
۴
۰
بیژن حجازی
بیژن حجازی
سلام! نوشتن به منزله مطالعه «خود» هست. من بیشتر تو زمینه برنامه نویسی و روان شناسی مطلب میذارم. خوشحال میشم نظرات تون رو باهام در میون بذارین.
شاید از این پست‌ها خوشتان بیاید