[עמוד ראשי]   [נושא קודם]
ביטויים / הצהרות ולולאות


תכנית JS היא בעצם אוסף של ביטויים והצהרות.
ביטויים, משפטים בדרך כלל מסתיימים בסימן נקודה פסיק (;)
1. ביטויים הצהרתיים
א. ביטויי השמה
s = "Hello " + name;             
ב. האופרטורים ++ ו - -
counter ++;            
ג. קריאות לפונקציות
window.close();                       
2. ביטויים מורכבים
ישנה דרך לשלב בין מספר ביטויים /הצהרות ולאחדם לביטוי אחד, על ידי בלוק (statement block).
נבצע זאת על ידי צירוף של מספר ביטויים בתוך סוגריים מסולסלים, כך השורות הבאות נחשבות לביטוי אחד :
{
  x = Math.PI;
  cx = Math.cos(x);
  alert("cos(" + x + ") = " + cx);
}
3. לולאות
לולאת if
לולאה זו היא ביטוי הבקרה הבסיסי המאפשר ל- JS להחליט החלטות, או ליתר דיוק לבצע ביטויים באופן מותנה.
ביטוי זה הוא בעל שתי צורות , הראשונה :
if (expression)
    statement;
בצורה זו הביטוי מוערך, אם התוצאה היא ערך "אמת" או ניתן להמירה לכזאת, ההצהרה/ משפט מתבצע ולהיפך,דוגמא :
if (username == null)
   username = "Jo Smith";
ניתן אף להחליף את ההצהרה (statement) בבלוק.
הצורה השנייה של לולאה זאת, כוללת גם פיסקה/ סעיף של “else”, משמע, אחרת, המתבצע כאשר הביטוי הוא בעל ערך "שקר".
if (expression)
   statement1;
else
     statement2;
דוגמא :
if(username != null)
   alert("Hello " + username);
else
{
   username = prompt("Welcome !\n What is your name ?");
   alert("Hello " + username);
}
כאשר יש לולאות if מקוננות, בעלות תוספת של “else”, מעט זהירות נדרשת להבטיח כי פיסת ה-"else" תשתייך ל-"if" המתאים,
דוגמא :
i = j =1;
k = 2;
if(i == j)
   if(j == k)
        document.write(" i doesn’t equal k");
else
        document.write(" i doesn’t equal j");
בדוגמא זו ה-if הפנימי הוא מצורה 1 ,המתאפשר במידה והביטוי של ה-if החיצוני הוא "אמת".
למרבה הצער, זה לא כה ברור איזה if הולך עם ה-else. ובדוגמא זו המפענח של JS מפענח זאת בצורה כזו :
if(i == j)
{
   if(j == k)  
        document.write(" i doesn’t equal k");
   else    
        document.write(" i doesn’t equal j");
}
החוק הוא שפיסקת else שייכת ל-if הקרוב אליה. על מנת להפוך דוגמא זו לפחות מעורפלת ולקריאה יותר ומובנת, ניתנת לתחזוק וללא באגים, כדאי שנשתמש בסוגריים מסולסלים כך :
if(i == j)
{
   if(j == k)
   {  
     document.write(" i doesn’t equal k");
   } 
} 
else
{ 
  document.write(" i doesn’t equal j");    
}
לולאת if else
כאשר נרצה לבצע פיסקה אחת של קוד כבחירה מותנית מתוך כמה פסקות נשתמש בלולאה זו :
if( n == 1){
     //execute code block #1
}
if( n == 2){
     //execute code block #2
}
if( n == 3){
     //execute code block #3
}
 else{
     //if all other has failed, execute bloch #4
}
סדרה של ביטויי if , כאשר if הוא חלק מפסקת ה-else של ביטוי ה-if הקודם.
לולאת switch
על מנת לא לבדוק את ערכו של אותו משתנה מספר רב וחוזר של פעמים, נשתמש בלולאה זו:
switch(expression)
{
   statements;
}
נבדוק את ערכו של המשתנה פעם אחת , ואחר כך נחפש להתאים לו את המקרה עבור הערך הספציפי, לדוגמא :
switch(n)
{
   case 1:                    // start here if n == 1
          // execute code block #1
          break;
   case 2:                    // start here if n == 2

          // execute code block #2 
          break;
   case 3:                    // start here if n == 3    

         // execute code block #3
         break;
   default :
         // execute code block #4
         break;
}
קיים שימוש במילת המפתח “break” בסיום כל מקרה-"case" ,פעולה זו גורמת ליציאה מהלולאה במידה ומצאנו את המקרה המתאים, ואין טעם להמשיך ולבצע את הלולאה.
· הביטוי הנבדק יכול להיות מסוג מחרוזת, מספר (שלם ועשרוני) וערכים בוליאניים.
· הערכים המקושרים למקרים השונים, אינם חייבים להיות קבועים, ניתן להשתמש במקרים כגון :
case 0:
case 60*06*24 :
case "hello" :
case "Hello " + "world" :
לולאת while
לולאה זו מאפשרת לבצע פעולות חוזרות :
while(expression)
   statement;
בשלב ראשון מחושב ערך הביטוי, אם ערכו "שקר", ממשיכים הלאה בתוכנית, אם ערכו "אמת", מתבצעת ההצהרה בגוף הלולאה ואז הביטוי מחושב פעם נוספת, וחוזר חלילה.
לולאה אינסופית ניתן ליצור באמצעות התחביר :
while(true);
בדרך כלל איננו מעוניינים בביצוע אותה הפעולה פעמים רבות, ברוב המקרים בלולאות, ערכו של אחד או יותר מהמשתנים משתנה בכל איטרציה/ חזרה על הלולאה.
יתר על כן, אם הערכים שמשתנים מעורבים בביטוי המוערך, ערכו של הביטוי יכול להשתנות בכל פעם,
דוגמא :
count = 0;
while(count < 10)
{
   document.write("count + "<br>");
   count++;
}
כפי הנראה, המשתנה count מאותחל ב - 0, אך בכל איטרציה נוסף לערכו 1.
לאחר שהלולאה תתבצע 10 פעמים ברציפות, התנאי בביטוי לא יתקיים יותר, ועל כן ההצהרה בבלוק לא תתבצע יותר, ונעבור לביצוע המשך התכנית.
לולאת do/ while (מגרסא 1.2 ומעלה)
דומה מאוד ללולאת while, מלבד העובדה כי ההצהרה/ המשפט של הלולאה מתבצע בסיומה ולא בתחילתה, משמע, כי גוף הלולאה מתבצע תמיד לפחות פעם אחת, תחביר:
do
  statement;
while(expression);
דוגמא :
var i = 0;
do
   document.write( i + "<br>");
while( ++i < 3);
לולאת for
שלוש הפעולות שמתבצעות כחלק מכריע בלולאות, אתחול משתנים(initialize), בדיקת ערך(test) ועדכון(update), הם חלק ברור וידוע בתחביר לולאה מסוג זו, תחביר :
for( initialize ; test ; update)
   statement;
בדומה ללולאת while :
initialize ;
while(test)
{
   statement;
   update;
}
דוגמא המבצעת את מה שביצענו בסעיף הקודם באמצעות לולאת while :
for(count = 0; count <10; count++)
   document.write(count + <br>");
כל המידע החשוב ללולאה ממוקם בשורה אחת, ההופכת את הללולאה ואת דרך פעילותה למובנת יותר. לולאות יכולות להפוך למורכבות יותר, ולפעמים בעלות מספר משתנים, אשר ערכם משתנה בכל איטרציה
דוגמא :
for(i = 0, j = 10; i < 10; i++, j --)
   sum += i * j;
הצהרת for/ in
בנוסף ללולאת ה-for ב-JS , קיימת ההצהרה בעלת התחביר הבא :
for (אובייקט  in   משתנה) 
      הצהרה ;  
משתנה צריך להיות שם של משתנה, איבר במערך או תכונה של אובייקט. אובייקט הוא שם של אובייקט או של ביטוי השווה לאובייקט.
כאן ישנה לולאה עבור תכונות של אובייקט ספציפי. גוף הלולאה מתבצע פעם אחת עבור כל אחת מתכונות האובייקט.
שם של אחת מתכונות האובייקט "מושם" לתוך הערך "משתנה" כמחרוזת. בתוך גוף הלולאה, ניתן להשתמש במשתנה זה על מנת לקבל את הערך עבור תכונה זו על ידי האופרטור [ ].
לדוגמא, הלולאה הבאה יוצרת הדפסה של השם והערך עבור כל אחת מתכונותיו של אובייקט :
for(  prop in my_object )
{
   document.write("name: " + prop + "; value: " + my_object[prop], "<br>");
}
לולאה זו אינה מפרטת את הסדר בו כל אחת מתכונות האובייקט מושמות למשתנה. לא ניתן לדעת מראש, וההתנהגות יכולה להשתנות בין יישומים שונים או גרסאות שונות.

ישנן תכונות מסויימות של אובייקט, המוגדרות כבלתי ניתנות לספירה/ מנייה.
תכונות אלו אינן משתתפות בתהליך של לולאה זו, כך גם תכונות/ מתודות שנחשבות כ- build-in , אינן חלק מן התהליך.
4. תוויות
לפני כל ביטוי/ הצהרה ניתן לשים תווית, באמצעות שם מזהה והסימן נקודותיים(:) לפני הביטוי/ הצהרה.
תחביר - ביטוי : הצהרה
המזהה יכול להיות כל מזהה חוקי ב-JS שאינו מילה שמורה. תוויות מובחנות ממשתנים ופונקציות, לכן, אין מה לדאוג לגבי התנגשויות במתן שם זהה לתווית כשמם של משתנה או פונקציה אחרים.
כאשר אנו נותנים תווית להצהרה, נותנים לה שם שנוכל אחר כך להשתמש בו, על מנת להתייחס אליה במקום אחר בתוכנית.
ניתן לתת תווית עבור כל ביטוי/ הצהרה, אך הביטויים שהם בדרך כלל בעלי תווית הן הלולאות.
טיפ :
JS שומרת את מילת המפתח goto , למרות שכרגע היא אינה בשימוש.
אם מתישהו תיישם את ביטוי ה-goto בסגנון C (מה שלא סביר שיקרה), ביטוי זה גם כן יסתמך על תוויות על מנת לאפשר "קפיצות" בקוד לביטויים בעלי שם שרירותי.
5. break
ביטוי זה גורם ליציאה מיידית מתוך הבלוק הפנימי ביותר של לולאה או של ביטוי switch. בגירסא 1.2 מילת המפתח break יכולה להיות מלווה בשם של תווית,
לדוגמא :
break  labelname;
ראינו דוגמא של הביטוי break בתוך לולאת switch.
בדוגמא הבאה, נראה חיפוש של איבר במערך בעל ערך ספציפי. הלולאה מסתיימת, באופן טבעי, כאשר סיימנו לעבור על כל איברי המערך (על פי תכונת אורכו).
הלולאה מסתיימת על ידי הביטוי break , במידה ונמצא את האיבר אותו מחפשים במערך :
for ( i = 0; i < a.length; i++)
{
   if (a[i] == target)
    break;
}
continue
ביטוי זה בניגוד ל- break , בו יוצאים מהלולאה לגמרי, כאן אנו מתחילים באיטרציה חדשה עבור הלולאה.
גם ביטוי זה יכול להיות מלווה בתווית :
continue  labelname; 

ביטוי זה ניתן לשימוש אך ורק בתוך גוף הלולאות for,while או for/ in. שימוש במקרה אחר מלבד אלה גורר שגיאת תחביר.
כאשר נגיע לביטוי continue, האיטרציה הנוכחית של הבלוק הנוכחי מסתיימת והאיטרציה הבאה מתחילה. נשים לב להבדלים בהתנהגות של הביטוי continue עבור הלולאות while ו- for.
בלולאת while נחזור ישירות לתנאי ונבדוק אם הוא מתקיים.
בלולאת for, קודם נבצע את השינוי במשתנה ואחר כך נבדוק את התנאי. דוגמא לשימוש בביטוי continue, נשתמש בו על מנת לצאת מהאיטרציה הנוכחית ולעבור לבאה במקרה של שגיאה :
for( i = 0; i < data.length; i++)
{
  if(data[i] == null)
      continue;
 total += data[i];
}
לא ניתן להשתמש בביטויים continue/ break כאשר שורה רווח מפרידה בינם לבין התווית, כיוון שבדרך זו צפויה שגיאה.
return
ביטוי זה נועד על מנת לתאר/לציין את הערך המוחזר על ידי פונקציה מסויימת, תחביר : ;[ ביטוי] return
כאשר הצהרה זו מתבצעת, הביטוי מוערך ומוחזר כערך של הפונקציה.
פעולת ביצוע גוף הפונקציה נעצרת כאשר הצהרת ה-return מתבצעת, אפילו אם קיימות הצהרות נוספות בגוף הפונקציה לאחר מכן,
לדוגמא :
function square(x) 
{ return x*x; }
ניתן להשתמש ב-return גם ללא ביטוי לאחר מכן על מנת לסיים פעולת ביצוע הפונקציה ללא החזרת כל ערך,
לדוגמא :
function display_object(obj) 
{
   if (obj == null) return;
}
בשלב ראשון ישנה בדיקה שהארגומנט הוא בעל ערך, במידה ולא- לא מתבצע שאר קוד הפונקציה.
with
בהמשך לחוקי טווח ההכרה ב-JS, נשתמש במילת המפתח with , על מנת לשנות באופן זמני את טווח הכרה השרשרתי. התחביר :
with(אובייקט)
  ביטוי/הצהרה;

בצורה זו, נוסיף ביעילות, אובייקט לתחילת השרשרת, נבצע ביטוי/ הצהרה מסויימים ונחזור חזרה למצב המקורי.

טיפ :
בצד ה"לקוח" ב-JS, לדוגמא, עבודה עם אובייקטים מקוננים בעלי היררכיה גדולה, שכיחה מאוד, למשל, נצטרך להשתמש בביטויים כאלה על מנת לגשת לאיבר ב-form של html כך :

אם נצטרך לגשת ל-form זה מספר פעמים, נוכל להשתמש בביטוי with על מנת להוסיף ה-form לשרשרת :
with(frames[1].document.forms[0]) 
{
   name.value = "";
   address.value = "";
}
למרות העובדה כי לפעמים זה נוח, השימוש ב-with אינו מומלץ , מכוון שקשה לבצע עבורו אופטימיזציה, וכתוצאה מכך, הביצוע יהיה איטי יותר מקוד שכתוב ללא with בעל אותה המשמעות.
6. ההצהרה הריקה
אחת מההצהרות החוקיות ב-JS היא ההצהרה הריקה שנראית כך : ;
ביצוע של הצהרה זו, באופן ברור, בעלת שום אפקט ולא מתבצעת אף פעולה.
למרות שלא נראה כך לעין, יוצא שהצהרה זו יעילה לפעמים, כאשר נרצה ליצור לולאה בעלת גוף ריק,
לדוגמא :
for(i=0; i < a.length; a[i++]);
נשים לב כי ההכללה המקרית / לא צפויה של ההצהרה הריקה מיד לאחר הסוגר הימני של לולאה, יכול ליצור באג מתסכל, הקשה לגילוי.
לדוגמא,
הקוד הבא ודאי לא מייצג את כוונתו של המחבר :
for( (a == 0) || (b == 0) );
     o = null;
טיפ :
כאשר אנו בכוונה משתמשים בהצהרה הריקה, זהו רעיון טוב לכתוב הערה בקוד, על מנת שיהיה ברור כי השתמשנו בה בכוונה,
לדוגמא :
for( i = 0; i < a.length; a[i++] = 0) /*empty */