Menu

מערכים ב-JavaScript: יצירה, גישה, שינוי ומעבר

איך מערכים עובדים ב-JavaScript: יצירה, אינדקסים, length, push/pop, ההבדל בין slice ל-splice, והלולאות שנקראות הכי טוב.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

מערך הוא רשימה מסודרת

מערכים ב-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).

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל