מערך הוא רשימה מסודרת
מערכים ב-JavaScript מחזיקים רצף מסודר של ערכים. הערכים יכולים להיות מכל טיפוס, מספרים, מחרוזות, אובייקטים ואפילו מערכים אחרים, והם לא חייבים להיות כולם מאותו טיפוס. יוצרים מערך עם סוגריים מרובעים:
בתחביר הליטרלי הזה תיצרו מערכים ב-99% מהמקרים. קיים גם new Array(...), אבל יש לו קצה חד: new Array(3) יוצר מערך באורך 3 בלי שום איברים בפועל, ולא [3]. היצמדו ל-[].
האינדקס מתחיל מאפס
ניגשים לאיברים לפי מיקום, החל מ-0:
שני דברים לשים לב אליהם. ראשית, גישה לאינדקס מעבר לסוף המערך לא זורקת שגיאה: היא מחזירה undefined. זה מקור נפוץ לבאגים מסוג "למה זה undefined?". שנית, אפשר להציב ערך בכל אינדקס, כולל אחרי הסוף, ו-JavaScript תרחיב את המערך בשמחה:
המיקומים 3 ו-4 הופכים ל"משבצות ריקות" (חורים דלילים). האורך קופץ ל-6. כמעט אף פעם לא רוצים את זה: זו תופעת לוואי של הגמישות של מערכים, לא תכונה שכדאי להסתמך עליה.
length מתעדכן בזמן אמת
array.length תמיד גדול באחד מהאינדקס הגבוה ביותר. הוא מתעדכן אוטומטית כשמוסיפים או מסירים איברים:
את הטריק האחרון כדאי לזכור: הצבה ל-length חותכת את המערך. nums.length = 0 היא דרך מהירה לרוקן אותו במקום.
push, pop, shift, unshift
ארבע מתודות להוספה ולהסרה בקצוות:
push(x)מוסיפה לסוף ומחזירה את האורך החדש.pop()מסירה מהסוף ומחזירה את האיבר שהוסר.unshift(x)מוסיפה להתחלה.shift()מסירה מההתחלה.
push/pop מהירות. shift/unshift צריכות לעדכן את האינדקס של כל שאר האיברים, ולכן הן איטיות יותר במערכים גדולים: בסדר גמור לגדלים יומיומיים, ושווה לדעת את זה אם אתם עובדים עם מיליוני פריטים.
slice מול splice
לשתיים האלה שמות דומים והתנהגות שונה לגמרי. אם תבחינו ביניהן היטב, תחסכו לעצמכם הרבה גירוד בראש.
slice(start, end) מחזירה עותק של חלק מהמערך. המקור לא נפגע. end לא נכלל:
splice(start, deleteCount, ...items) משנה את המערך. היא יכולה למחוק, להכניס או גם וגם, ומחזירה את מה שהסירה:
כלל אצבע: אם המילה מזכירה לכם לפרוס פרוסה מכיכר לחם, זו slice. אם היא מזכירה לכם הדבקה של סרט צילום (חיתוך והכנסה), זו splice.
חיפוש: indexOf, includes, find
שלוש דרכים לחפש משהו, למצבים שונים:
indexOf(x)נותנת את המיקום, או-1אם לא נמצא. שימושית כשצריך את האינדקס.includes(x)נותנת ערך בוליאני. נקייה יותר כשרק רוצים לדעת "האם זה נמצא כאן?". היא גם מטפלת נכון ב-NaN, מה ש-indexOfלא עושה.find(predicate)מריצה פונקציה על כל איבר ומחזירה את הראשון שמתאים. זו המתודה למערכים של אובייקטים, שבהםindexOfו-includesבודקות רק שוויון מחמיר.
מעבר על מערך בלולאה
כמה דרכים טובות, כל אחת מתאימה למצב אחר:
for...of היא בחירת ברירת המחדל: קריאה, עובדת עם כל iterable ונותנת את הערך ישירות. forEach בסדר כשצריך גם את האינדקס ולא יוצאים מהלולאה מוקדם (אי אפשר לעשות break מתוך forEach). לולאת for הקלאסית עם אינדקס ארוכה יותר, אבל נותנת שליטה מלאה: השתמשו בה כשצריך לדלג על איברים, לעבור מהסוף להתחלה, או גם וגם.
לולאה אחת שכדאי להימנע ממנה: for...in. היא עוברת על מפתחות וכוללת מאפיינים שעברו בירושה. היא מיועדת לאובייקטים, לא למערכים.
העתקה ושילוב
מערכים הם ערכי הפניה. הצבה של מערך למשתנה אחר לא מעתיקה אותו: היא יוצרת שני שמות לאותו מערך:
כדי להעתיק באמת, השתמשו באופרטור הפיזור או ב-slice():
שתי הדרכים נותנות עותק רדוד: המערך החיצוני חדש, אבל אם האיברים הם אובייקטים, האובייקטים האלה עדיין משותפים. פיזור הוא גם הדרך הנקייה ביותר לשלב מערכים:
מערכים של אובייקטים
בקוד אמיתי, רוב המערכים מחזיקים אובייקטים. אותן מתודות עובדות, אבל ההתאמה נעשית מעניינת יותר:
filter מחזירה מערך חדש של האיברים שמתאימים לפרדיקט. map מחזירה מערך חדש שבו כל איבר עבר שינוי. השרשור שלהן הוא הלחם והחמאה של עבודה עם מערכים של אובייקטים, ועמוד התיעוד הבא מעמיק במשפחת המתודות הזו.
מערכים מול אובייקטים
מודל מחשבתי מהיר: השתמשו במערך כשהסדר חשוב ואתם עובדים עם רשימה של דברים מאותו סוג. השתמשו באובייקט (או ב-Map) כשאתם ממפתחים דברים לפי שם. "ראשון, שני, שלישי" זה תחום של מערך. "חפש את המשתמש עם id 42" זה תחום של אובייקט או Map.
אפשר לשלב ביניהם, מערכים של אובייקטים נמצאים בכל מקום, אבל אל תשתמשו במערך כמילון עם מפתחות, ואל תשתמשו באובייקט כרשימה מסודרת. כל אחד מהם עושה עבודה אחת היטב.
הבא בתור: Destructuring
שליפת ערכים ממערכים לפי אינדקס (ומאפיינים מאובייקטים לפי שם) חוזרת מספיק פעמים כדי של-JavaScript יהיה תחביר ייעודי לזה. זה destructuring, והוא הבא בתור.
שאלות נפוצות
איך יוצרים מערך ב-JavaScript?
משתמשים בתחביר הליטרלי עם סוגריים מרובעים: const fruits = ['apple', 'banana']. זו הדרך המקובלת. הבנאי Array (new Array(3)) קיים, אבל כמעט אף פעם לא זה מה שרוצים: new Array(3) יוצר מערך באורך 3 בלי איברים בפועל, וזה מפתיע אנשים.
איך מסירים פריט ממערך ב-JavaScript?
מהסוף, השתמשו ב-pop(). מההתחלה, ב-shift(). מכל מקום באמצע, ב-splice(index, 1) כדי לשנות במקום, או ב-filter(...) כדי לקבל מערך חדש בלי הפריט. splice משנה את המקור; filter לא.
מה ההבדל בין slice ל-splice?
slice(start, end) מחזירה עותק רדוד של חלק מהמערך ומשאירה את המקור כמו שהוא. splice(start, deleteCount, ...items) משנה את המקור: היא מסירה איברים, יכולה להכניס חדשים, ומחזירה את אלה שהוסרו. אות אחת, התנהגות שונה לגמרי.
איך בודקים אם ערך נמצא במערך ב-JavaScript?
השתמשו ב-array.includes(value): הוא מחזיר true או false ומטפל נכון ב-NaN. indexOf(value) מחזיר את המיקום, או -1 אם הערך לא נמצא, וזה שימושי כשצריך גם את האינדקס. להתאמות מורכבות, השתמשו ב-some(predicate) או ב-find(predicate).