🚀 מבוא וחיבור לדף
JavaScript (בקיצור JS) היא שפת התכנות שמאפשרת להוסיף אינטראקטיביות, לוגיקה ודינמיות לדפי אינטרנט. בעוד HTML הוא השלד ו-CSS הוא העיצוב, JS הוא המוח.
איך מוסיפים JS לדף HTML?
יוצרים קובץ נפרד (למשל script.js) ומקשרים אליו מה-HTML, רצוי לפני תג סגירת
ה-</body>.
<body>
<!-- ... כל תוכן ה-HTML ... -->
<script src="script.js" defer></script>
</body>
המאפיין defer גורם לסקריפט להיטען במקביל ל-HTML ולהידחות הרצתו עד שה-HTML
נטען
במלואו, וזה מומלץ לביצועים.
ניתן לכתוב JS ישירות בתוך תג <script>, גם כן רצוי בסוף
ה-<body>.
<body>
<!-- ... כל תוכן ה-HTML ... -->
<script>
console.log('שלום עולם!');
</script>
</body>
הכירו את ה"קונסול החי"
ברוב הדוגמאות הבאות, החלון הימני אינו מציג דף אינטרנט, אלא מדמה את ה-**Console** של הדפדפן. כל פקודת
console.log() שתכתבו בקוד תודפס שם, וכן שגיאות שיתרחשו.
📦 יסודות: משתנים וטיפוסים
בניגוד ל-Java, ג'אווהסקריפט היא שפת **טיפוסים דינמית** (Dynamically Typed). אין צורך להכריז על `int` או `String`. המנוע מבין את הטיפוס בזמן ריצה.
let, const, ו-var
const: הדרך המועדפת. מגדיר קבוע (constant) שלא ניתן להקצות מחדש (re-assign). זהו **Block Scoped**. (הערה: אם הקבוע הוא אובייקט או מערך, *ניתן* לשנות את תוכנם הפנימי).let: להגדרת משתנה שערכו עשוי להשתנות. גם הוא **Block Scoped**.var: הדרך הישנה. **Function Scoped**. מומלץ להימנע משימוש בה בקוד מודרני בגלל התנהגות מבלבלת עם Hoisting.
טיפוסים פרימיטיביים
| טיפוס | דוגמה | הערה (מול Java) |
|---|---|---|
Number |
10, 3.14 |
אין הפרדה בין int, double, float. הכל
Number.
|
String |
"שלום", 'עולם', `כאן ${name}` |
מחרוזת. ניתן להשתמש ב-` (Backticks) להטמעת משתנים. |
Boolean |
true, false |
זהה ל-Java. |
null |
null |
ערך "ריק" מכוון. (מעניין: typeof null מחזיר 'object', באג היסטורי). |
undefined |
undefined |
טיפוס של משתנה שטרם הוקצה לו ערך. (ייחודי ל-JS) |
Symbol |
Symbol('id') |
מזהה ייחודי ובלתי ניתן לשינוי (פחות נפוץ). |
BigInt |
100n |
למספרים שלמים גדולים מאוד (מסתיים ב-n). |
קונסול חי: משתנים וטיפוסים
נסו לשנות את הערך של age ולראות את הפלט משתנה. נסו לשנות את name (שהוא
const) ולראות את השגיאה בקונסול.
⚙️ אופרטורים
אופרטורים מאפשרים לבצע פעולות, השוואות והקצאות. רובם דומים ל-Java, אך יש כמה תוספות חשובות.
סוגי אופרטורים
| סוג | אופרטורים | תיאור |
|---|---|---|
| חשבון | +, -, *, /, % (מודולו),
** (חזקה)
|
פעולות מתמטיות. |
| הקצאה | =, +=, -=, *=, /= |
הקצאת ערכים למשתנים. |
| השוואה | ==, !=, ===, !==, >,
<,
>=, <=
|
השוואת ערכים. מומלץ תמיד להשתמש ב-=== (השוואה קפדנית)
שבודק גם טיפוס וגם
ערך, ולא ב-== (השוואה רפויה). |
| לוגיים | && (וגם), || (או), ! (לא) |
צירוף תנאים בוליאניים. |
| טרנרי | condition ? val1 : val2 |
קיצור של if...else. |
| Nullish Coalescing | ?? |
מחזיר את הערך הימני *רק* אם הערך השמאלי הוא null או undefined.
(שימושי לערכי
0 או false שצריך לשמר). |
| Optional Chaining | ?. |
מאפשר לגשת למאפיינים מקוננים בבטחה. אם חוליה בשרשרת היא null או
undefined,
הביטוי מחזיר undefined במקום לזרוק שגיאה.
|
קונסול חי: אופרטורים מודרניים
🚦 בקרת זרימה
הלוגיקה הבסיסית של תנאים ולולאות. החלק הזה מאוד דומה ל-Java, עם תוספות כמו `for...of` ו-`for...in`.
קונסול חי: תנאים, Switch ולולאות
פונקציות
פונקציות הן אבני הבניין של הלוגיקה ב-JS. ניתן להגדיר אותן בכמה דרכים, והן יכולות לקבל פונקציות אחרות כארגומנטים (Higher-Order Functions).
קונסול חי: הגדרת פונקציות, פרמטרים ופונקציות מסדר גבוה
🔬 Scope & Closures
סקופ קובע את הנראות (visibility) של משתנים. Closure (סגור) הוא פונקציה ש"זוכרת" את הסביבה הלוקאלית שבה היא נוצרה, גם לאחר שהפונקציה החיצונית סיימה לרוץ.
סוגי סקופ
- Global Scope: משתנה שמוגדר מחוץ לכל פונקציה. זמין בכל מקום.
- Function Scope: משתנה שמוגדר עם `var` זמין *בכל* מקום בתוך הפונקציה שבה הוגדר.
- Block Scope: משתנה שמוגדר עם `let` או `const` זמין *רק* בתוך הבלוק (`{...}`) שבו הוגדר (למשל, בתוך `if` או `for`).
קונסול חי: סקופ ו-Closure
מערכים ומתודות
מערכים ב-JS הם סופר-גמישים (בניגוד ל-Java). הם דינמיים ובעלי מתודות שימושיות רבות.
קונסול חי: מתודות מערכים
אלו המתודות הנפוצות ביותר לעבודה פונקציונלית עם מערכים.
אובייקטים ומתודות
אובייקטים ב-JS הם אוספים דינמיים של מפתח-ערך. הצורה הנפוצה היא Object Literal (סוגריים מסולסלים).
קונסול חי: אובייקטים, Destructuring ומתודות
מתודות מובנות (String, Number, Math)
לטיפוסים פרימיטיביים יש מתודות עזר שימושיות.
קונסול חי: מתודות שימושיות
מבני נתונים (Set, Map)
מבני נתונים מודרניים שנוספו ב-ES6 ופותרים בעיות נפוצות.
- Set: אוסף של ערכים ייחודיים (Unique). מצוין להסרת כפילויות ממערך.
- Map: אוסף של מפתח-ערך. בניגוד לאובייקט רגיל, המפתחות יכולים להיות *כל* טיפוס (כולל אובייקטים או פונקציות), לא רק מחרוזות.
קונסול חי: Set ו-Map
🏛️ Classes ו-Prototype (תכנות מונחה עצמים)
בניגוד ל-Java שהיא Class-Based, ג'אווהסקריפט היא Prototypal. אובייקטים יורשים ישירות מאובייקטים אחרים. התחביר של `class` (מ-ES6) הוא "סוכר תחבירי" (Syntactic Sugar) מעל מנגנון הפרוטוטייפ.
1. הדרך הישנה: פונקציית בנאי (Constructor Function) ו-Prototype
כך בנו אובייקטים לפני ES6. כל פונקציה יכולה לשמש כבנאי עם `new`. מתודות משותפות מוסיפים ל-`prototype` כדי לחסוך בזיכרון.
// 1. פונקציית הבנאי
function Person(name, age) {
this.name = name;
this.age = age;
}
// 2. הוספת מתודה ל-prototype המשותף
Person.prototype.greet = function() {
console.log(`שלום, אני ${this.name} ואני בן ${this.age}.`);
};
const person1 = new Person("משה", 50);
person1.greet(); // "שלום, אני משה ואני בן 50."
2. הדרך המודרנית: `class` (ES6)
תחביר נקי ומוכר יותר (במיוחד למי שבא מ-Java), שעושה את אותו הדבר מאחורי הקלעים.
קונסול חי: `class`, `extends`, `super`
הקונספט 'this'
אחד הנושאים המבלבלים ב-JS. הערך של `this` נקבע *בזמן הריצה* (דינמית), בהתאם ל*איך הפונקציה נקראה*.
- Default (Global): אם פונקציה נקראת רגיל (לא כמתודה, לא עם `new`, לא עם `bind`), `this`
יצביע על
האובייקט הגלובלי (
windowבדפדפן, אוundefinedב-Strict Mode). - Implicit (Method): אם פונקציה נקראת כמתודה של אובייקט (
obj.myMethod()), `this` יצביע על האובייקט ש*משמאל לנקודה* (obj). - New (Constructor): אם פונקציה נקראת עם `new` (
new Person()), `this` יצביע על האובייקט החדש שנוצר. - Explicit (Bind, Call, Apply): ניתן *לכפות* את הערך של `this` באמצעות
.call(),.apply(), או.bind().
חריג: פונקציות חץ (Arrow Functions)
לפונקציות חץ *אין `this` משלהן*. הן יורשות
את
`this` באופן לקסיקלי מה-Scope שבו הן הוגדרו. הן מתעלמות מ-4 הכללים.
קונסול חי: הדגמת `this`
🌳 מניפולציית DOM ואירועים (Events)
ה-DOM (Document Object Model) הוא ה-API שמאפשר ל-JS לתקשר עם ה-HTML. אירועים (Events) הם הדרך להגיב לפעולות משתמש.
שיטות נפוצות
| שיטה | תיאור |
|---|---|
document.getElementById(id) |
מוצא אלמנט לפי ה-ID הייחודי שלו. |
document.querySelector(selector) |
מוצא את האלמנט *הראשון* שתואם לסלקטור CSS. |
document.querySelectorAll(selector) |
מוצא את *כל* האלמנטים שתואמים לסלקטור CSS. |
element.textContent |
קורא או משנה את הטקסט הפנימי (בטוח). |
element.innerHTML |
קורא או משנה את ה-HTML הפנימי (פחות בטוח). |
element.style.color = 'red' |
משנה מאפיין CSS. |
element.classList.add('new') |
מוסיף קלאס CSS. |
element.addEventListener(event, func) |
מאזין לאירוע (כמו 'click') ומפעיל פונקציה. |
document.createElement('div') |
יוצר אלמנט חדש. |
parent.append(child) |
מוסיף אלמנט ילד בסוף ההורה. |
מעבדת DOM אינטראקטיבית
זוהי מעבדה מיוחדת. יש לכם עורך HTML ועורך JS. נסו לכתוב JS שמשנה את ה-HTML ולראות את התוצאה בחלון התצוגה המקדימה.
⚡ אסינכרוניות (Async)
הנושא החשוב ביותר ב-JS מודרני. JS פועלת ב-**Single Thread** עם **Event Loop**. היא לא "נתקעת" ומחכה לפעולות ארוכות (כמו קריאה לשרת), אלא ממשיכה הלאה ומטפלת בתשובה כשתגיע.
- Call Stack (מחסנית קריאות): קוד סינכרוני נכנס לכאן ומבוצע (LIFO - אחרון נכנס, ראשון יוצא).
- Web APIs (דפדפן): פעולות ארוכות (
setTimeout,fetch, אירועי DOM) נשלחות לכאן. הדפדפן מטפל בהן "בצד". - Callback Queue (תור): כשפעולת Web API מסתיימת, ה-Callback שלה נשלח לתור (FIFO).
- Event Loop: הלולאה שבודקת כל הזמן: "האם ה-Call Stack ריק?". אם כן, היא לוקחת את המשימה הראשונה מה-Callback Queue ודוחפת אותה ל-Call Stack כדי שתרוץ.
Microtask Queue: תור נוסף עם עדיפות גבוהה יותר (למשל, .then() של
Promises).
ה-Event Loop ירוקן *תמיד* את התור הזה לפני שהוא לוקח משהו מה-Callback Queue הרגיל.
קונסול חי: setTimeout, Promise, ו-fetch
שימו לב לסדר שבו ההודעות מופיעות בקונסול! "סוף" מופיע לפני שהתשובות האסינכרוניות חוזרות.
Async/Await (הדרך הנקייה ביותר)
תחביר מודרני (ES2017) שמאפשר לכתוב קוד אסינכרוני שנראה סינכרוני. זו פשוט "עטיפה" יפה סביב Promises.
קונסול חי: Async/Await
טיפול בשגיאות
קוד מקצועי חייב לדעת לטפל בשגיאות בחן, באמצעות try...catch...finally.
קונסול חי: try...catch
JSON (JavaScript Object Notation)
פורמט טקסטואלי סטנדרטי להעברת נתונים. קל מאוד ל-JS לקרוא ולכתוב אותו.
קונסול חי: JSON.stringify ו-JSON.parse
LocalStorage
מנגנון אחסון פשוט בדפדפן ששומר נתונים (כמחרוזות) באופן קבוע, גם לאחר סגירת הלשונית.
הערה: הדוגמה הזו תכתוב ל-LocalStorage האמיתי של הדפדפן שלכם. תוכלו לראות את התוצאות בלחיצה על F12 -> Application -> Local Storage.
קונסול חי: setItem, getItem
📦 מודולים (Modules)
הדרך המודרנית (ES6) לארגן קוד בקבצים נפרדים. קובץ אחד מייצא (export) פונקציות/משתנים, וקובץ
אחר
מייבא (import) אותם.
הערה: לא ניתן להדגים `import/export` בעורך החי הפשוט הזה, כיוון שהם דורשים מערכת קבצים אמיתית ושרת. זוהי דוגמה תיאורטית.
math.js (ייצוא)// ייצוא מוגדר (Named Export)
export const PI = 3.14;
export function add(a, b) {
return a + b;
}
// ייצוא ברירת מחדל (Default Export)
export default function multiply(a, b) {
return a * b;
}
main.js (ייבוא)// ייבוא ברירת מחדל וייבוא מוגדר
import multiply, { add, PI } from './math.js';
console.log(PI); // 3.14
console.log(add(2, 3)); // 5
console.log(multiply(2, 3)); // 6
// כדי שזה יעבוד ב-HTML:
// <script type="module" src="main.js"></script>
ביטויים רגולריים (Regex)
תחביר מיוחד לחיפוש והחלפת תבניות בתוך מחרוזות. כלי חזק מאוד (ולעיתים מורכב).
קונסול חי: test ו-match
🌐 Single Page Applications (SPA)
אפליקציית עמוד-יחיד (SPA) היא יישום ווב שטוען דף HTML יחיד וכל התוכן העתידי נטען באופן דינמי, ללא טעינה מחדש של הדף. זה יוצר חווית משתמש מהירה וזורמת, בדומה לאפליקציית דסקטופ.
איך זה עובד?
במקום לבקש דף HTML חדש מהשרת בכל ניווט, ה-SPA משתמש ב-JavaScript כדי לשנות את תוכן ה-DOM הנוכחי. בדרך כלל, השרת מספק רק את המידע (Data) בפורמט JSON, והלקוח (הדפדפן) אחראי על הרינדור (הצגת המידע).
יתרונות
- מהירות: אחרי הטעינה הראשונית, המעברים בין "עמודים" הם כמעט מיידיים.
- חווית משתמש: חוויה רציפה וזורמת ללא הבהובים של טעינת דפים.
- הפחתת עומס על השרת: השרת שולח פחות מידע (רק נתונים, לא HTML מלא).
חסרונות
- טעינה ראשונית איטית: צריך לטעון את כל ה-framework והקוד של האפליקציה בהתחלה.
- אתגרי SEO: קשה יותר למנועי חיפוש לאנדקס תוכן שנטען דינמית (אם כי יש פתרונות).
- תלות ב-JavaScript: אם JS מושבת בדפדפן, האתר לא יעבוד כלל.
פריימוורקים פופולריים
רוב ה-SPAs נבנים באמצעות ספריות ופריימוורקים מודרניים:
- React: ספרייה פופולרית מבית פייסבוק לבניית ממשקי משתמש.
- Angular: פריימוורק מקיף מבית גוגל לבניית אפליקציות גדולות.
- Vue.js: פריימוורק מתקדם וגמיש שקל יחסית ללמוד.
מעבדת DOM: דוגמת SPA בסיסית
זוהי דוגמה פשוטה המדגימה את העיקרון הבסיסי. שימו לב שלחיצה על הקישורים משנה את התוכן, אך הדפדפן לא מרענן את הדף.