שיטות עבודה מומלצות
אוסף של טיפים וכללים לכתיבת קוד JavaScript נקי, קריא ותחזיקתי.
מוסכמות שמות (Naming Conventions)
משתנים ופונקציות - camelCase
// ✅ טוב
let userName = "דן";
let totalAmount = 100;
function calculateTotal() { }
function getUserData() { }
// ❌ לא מומלץ
let user_name = "דן";
let TOTALAMOUNT = 100;
קבועים - SCREAMING_SNAKE_CASE
const MAX_USERS = 100;
const API_BASE_URL = "https://api.example.com";
const DEFAULT_TIMEOUT = 5000;
Classes ו-Constructors - PascalCase
class UserProfile { }
class ShoppingCart { }
function Person(name) {
this.name = name;
}
Boolean - שאלות
// ✅ ברור שזה boolean
let isActive = true;
let hasPermission = false;
let canEdit = true;
let shouldUpdate = false;
// ❌ לא ברור
let active = true;
let permission = false;
כתיבת פונקציות
פונקציה צריכה לעשות דבר אחד
// ❌ פונקציה שעושה יותר מדי
function processUser(user) {
// אימות
// עדכון DB
// שליחת אימייל
// עדכון לוג
}
// ✅ פונקציות קטנות וממוקדות
function validateUser(user) { }
function saveUser(user) { }
function sendWelcomeEmail(user) { }
function logUserCreation(user) { }
שמות תיאוריים
// ❌ לא ברור
function process(d) { }
function doStuff(x, y) { }
// ✅ ברור מה הפונקציה עושה
function calculateTotalPrice(items) { }
function formatDateForDisplay(date) { }
function validateEmailAddress(email) { }
ערכי ברירת מחדל
// ✅ ברירות מחדל מונעות undefined
function createUser(name, role = "user", active = true) {
return { name, role, active };
}
// ✅ עם destructuring
function greet({ name = "אורח", greeting = "שלום" } = {}) {
return `${greeting} ${name}!`;
}
עבודה עם משתנים
const כברירת מחדל
// ✅ השתמשו ב-const אם הערך לא משתנה
const API_URL = "https://api.example.com";
const config = { debug: true };
// השתמשו ב-let רק כשצריך לשנות
let count = 0;
count++;
הימנעו מ-var
// ❌ var - בעיות scope
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// ידפיס: 3, 3, 3
// ✅ let - מתנהג כמצופה
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// ידפיס: 0, 1, 2
Destructuring
// ❌ ארוך
const name = user.name;
const age = user.age;
const city = user.address.city;
// ✅ קצר וקריא
const { name, age, address: { city } } = user;
// עם מערכים
const [first, second, ...rest] = items;
השוואות ותנאים
השתמשו ב-=== ו-!==
// ❌ השוואה רופפת
if (value == "5") { }
// ✅ השוואה מדויקת
if (value === "5") { }
if (value === 5) { }
התנאים הקצרים
// ❌ מסורבל
if (array.length > 0) {
return true;
} else {
return false;
}
// ✅ פשוט
return array.length > 0;
// Optional chaining
const city = user?.address?.city;
// Nullish coalescing
const name = user.name ?? "אנונימי";
Early Return
// ❌ קשה לקריאה
function processUser(user) {
if (user) {
if (user.active) {
if (user.role === "admin") {
// הרבה קוד
}
}
}
}
// ✅ קל לקריאה
function processUser(user) {
if (!user) return;
if (!user.active) return;
if (user.role !== "admin") return;
// הקוד הראשי
}
עבודה עם מערכים
שימוש במתודות פונקציונליות
// ❌ לולאה מסורבלת
const doubled = [];
for (let i = 0; i < numbers.length; i++) {
doubled.push(numbers[i] * 2);
}
// ✅ קצר וקריא
const doubled = numbers.map(n => n * 2);
// סינון
const adults = users.filter(u => u.age >= 18);
// מציאה
const admin = users.find(u => u.role === "admin");
// בדיקה
const hasAdmin = users.some(u => u.role === "admin");
Spread ו-Destructuring
// ✅ העתקה
const copy = [...originalArray];
const merged = [...array1, ...array2];
// הוספה לתחילה/סוף
const withFirst = [newItem, ...array];
const withLast = [...array, newItem];
עבודה עם אובייקטים
Spread לעדכון
// ✅ עדכון אימטבילי
const updatedUser = {
...user,
name: "שם חדש",
age: user.age + 1
};
// מיזוג
const merged = { ...defaults, ...userSettings };
Shorthand Properties
const name = "דן";
const age = 25;
// ❌ חזרה
const user = { name: name, age: age };
// ✅ קיצור
const user = { name, age };
טיפול בשגיאות
תמיד תפסו שגיאות בקוד אסינכרוני
// ✅ try/catch עם async
async function fetchData() {
try {
const response = await fetch("/api/data");
return await response.json();
} catch (error) {
console.error("שגיאה:", error);
return null;
}
}
// ✅ .catch עם promises
fetch("/api/data")
.then(res => res.json())
.catch(error => {
console.error("שגיאה:", error);
});
שגיאות ספציפיות
// ✅ מידע ברור בשגיאה
throw new Error(`משתמש ${userId} לא נמצא`);
// ✅ בדיקות מפורטות
if (!response.ok) {
if (response.status === 404) {
throw new Error("לא נמצא");
} else if (response.status === 401) {
throw new Error("לא מורשה");
}
throw new Error(`שגיאה: ${response.status}`);
}
הערות ותיעוד
הערות שמסבירות למה, לא מה
// ❌ מה - מובן מהקוד
// מגדיל את count ב-1
count++;
// ✅ למה - לא מובן מהקוד
// מוסיף 1 כי ה-API מחזיר 0-indexed
displayedPage = apiPage + 1;
// ✅ הסבר של לוגיקה מורכבת
// משתמשים ב-debounce כי ה-API מגביל ל-100 בקשות בדקה
const debouncedSearch = debounce(search, 300);
JSDoc לפונקציות מורכבות
/**
* מחשב את המחיר הכולל כולל הנחה
* @param {number} price - מחיר הבסיס
* @param {number} quantity - כמות
* @param {number} [discount=0] - אחוז הנחה (אופציונלי)
* @returns {number} המחיר הסופי
*/
function calculateTotal(price, quantity, discount = 0) {
const subtotal = price * quantity;
return subtotal - (subtotal * discount / 100);
}
Debugging
console מתקדם
// טבלה
console.table([{ name: "דן", age: 25 }, { name: "דנה", age: 30 }]);
// קיבוץ
console.group("פרטי משתמש");
console.log("שם:", user.name);
console.log("גיל:", user.age);
console.groupEnd();
// זמן ביצוע
console.time("פעולה");
// ... קוד ...
console.timeEnd("פעולה");
// תנאי
console.assert(value > 0, "הערך חייב להיות חיובי");
Breakpoints
// עצירה בקוד
debugger;
// או בDevTools - לחיצה על מספר השורה
ביצועים
הימנעו מפעולות DOM מיותרות
// ❌ עדכון DOM בכל איטרציה
for (let item of items) {
container.innerHTML += `<div>${item}</div>`;
}
// ✅ בניית HTML ועדכון אחד
const html = items.map(item => `<div>${item}</div>`).join("");
container.innerHTML = html;
Debounce ו-Throttle
// Debounce - ממתין שהמשתמש יפסיק להקליד
const debouncedSearch = debounce(search, 300);
input.addEventListener("input", debouncedSearch);
// Throttle - מבצע מקסימום פעם ב-X זמן
const throttledScroll = throttle(handleScroll, 100);
window.addEventListener("scroll", throttledScroll);
אבטחה
הימנעו מ-innerHTML עם קלט משתמש
// ❌ מסוכן - XSS
element.innerHTML = userInput;
// ✅ בטוח
element.textContent = userInput;
// ✅ אם חייבים HTML - נקו קודם
element.innerHTML = DOMPurify.sanitize(userInput);
אל תשמרו מידע רגיש ב-Client
// ❌ לעולם לא!
const PRIVATE_KEY = "secret123";
localStorage.setItem("password", password);
// ✅ רק בשרת
// הטוקנים נשמרים בצורה מאובטחת (httpOnly cookies)
סיכום
| נושא | כלל |
|---|---|
| משתנים | const כברירת מחדל |
| השוואות | תמיד === |
| פונקציות | קטנות וממוקדות |
| שגיאות | תמיד try/catch באסינכרוני |
| מערכים | map, filter, find |
| DOM | מינימום עדכונים |
| אבטחה | textContent ולא innerHTML |
עקרונות כלליים: - קוד קריא עדיף על קוד "חכם" - DRY - Don't Repeat Yourself - KISS - Keep It Simple, Stupid - עדכנו קוד ישן כשנוגעים בו - כתבו קוד שאתם תרצו לתחזק בעוד שנה
לחזרה ותרגול חי: הנושא הזה מופיע גם
במדריך האינטראקטיבי ל-JavaScript, עם עורך קוד שמראה את התוצאה מיד.
בדקו את עצמכם
נסו לענות לבד לפני שאתם פותחים את התשובה.
-
מה עדיף לרוב הערכים?
הצגת התשובה
תשובה ד. const מונע השמה בטעות, ו-let רק כשבאמת צריך לשנות.
-
למה להימנע ממשתנים גלובליים?
הצגת התשובה
תשובה ג. מודולים ופונקציות עם scope מקומי שומרים על קוד צפוי.