ערכתי לאחרונה בתאריך 12.09.12 בשעה 10:44 בברכה, יוחאי
קודם כל המדריך מיועד גם למי שפחות חזק בשפה, אם לא הבנתם משהו תשאלו, ואני אסביר, או לפחות אנסה להסביר!1.כיצד לייצר מופע יחיד לאובייקט בJS הידוע בכינוי Singleton:
מה זה Singleton - הרבה אנשים היום מפתחים מול תשתיות שמבוססות MVC, הרבה גם לא יודעים שSingleton הוא חלק הכרחי בMVC(לפחות לפי הסטנדרט), נניח ויש לנו מספר מחלקות ששייכות ממש לליבת המערכת נקרא להן בשמות:
core1
core2
core3
אנחנו לא מעוניינים לייצר להם יותר ממופע אחד, מה זאת אומרת מבחינת הקוד?
הדוגמא הבאה יוצרת אובייקט בדרך שכן מאפשרת לנו ליצור יותר ממופע אחד:
var core1 = function () { };core1.prototype.setSomething = function () { }; var x = new core1(); var y = new core1();
|
מה שבעצם אנחנו רואים כאן שיצרנו אובייקט בתוך core1, כל אובייקט מעצם היותו אובייקט מכיל בתוכו prototype property כאן יש לנו את האופציה לייצר בעצם את כל הפונקציות/ערכים שיוחצנו מחוץ לאובייקט, זאת אומרת יהיו public אפשר לעשות את זה גם דרך הprototype וגם דרך הconstructor (ולהשתמש בthis), עכשיו זאת אחלה דרך לייצר אובייקטים אם המטרה שלנו היא אובייקט שאנחנו נשתמש בו יותר מפעם אחת, נניח אתר שמכיל אוסף של מכוניות כל מכונית יש לה קלאס עם מידע שונה, אז צריך לקחת את אותו class ולעשות לו new כל פעם מחדש עם המידע הנכון (זאת דוגמא נורא נורא מופשטת).
זה בעצם ההסבר למה שאנחנו כרגע לא רוצים לעשות, מה שכן ככה ייראה הקוד שלנו אם נרצה לייצר מופע בודד:
var core1 = (function () { //define here private variables and functions return { setItem: function () { } } })();
|
אנחנו משתמשים פה בכלי מאוד מאוד חזק בjavascript שנהוג לקרוא לו self invoke, מה שבעצם אנחנו אומרים לparser לעשות זה דבר די פשוט, ברגע שהוא רואה את המבנה של הפונקציה שמריצה את עצמה, הוא פשוט מריץ אותה, ובתוך core1 אנחנו נקבל את הערכים שהיא מחזירה (במקרה שלנו אם זה class אז פונקציות וproperties).
דרך אגב החלק הנחמד עם self invoke הוא שאנחנו נמנעים מלהסתבך מול הscope הגלובאלי, מה שגורם לקוד שלנו להיות חסין מהשפעות מבחוץ, דוגמא נחמדה יכולה להיות היא אם למשל יש לנו בתור הפונקציה הזאת משתנה בשם $ ואנחנו רוצים להעביר את jQuery אז זה די פשוט:
var core1 = (function (jQuery_Instance) { //define here private variables and functions var getElements = jQuery_Instance.find('#edit-link'); return { setItem: function () { } } })($);
|
נחמד אה?
החלק הבא הוא שימוש בnamespaces, מה זה בדיוק אומר:
רוב הזמן אנחנו לא מודעים לכך, אבל משתנים שאנחנו יוצרים בscope הגלובאלי, יושבים לנו בתור האובייקט window שזה הגיוני זאת הרמה הראשונה מבחינת העמוד, עכשיו הרבה פעמים יכול להווצר מצב שאנחנו נתנגש עם האובייקט, במיוחד אם אנחנו עובדים עם המון קוד, והמון שמות משתנים, לכן תמיד עדיף ליצור תחת window איזה שהוא אובייקט שתחתיו נכניס ככול העולה על רוחנו.
סדר בקוד: javascript היא שפה מאוד נוחה, היא לא תכעס עליכם אם לא תייצרו את כל המשתנים למעלה במקום אחד, אבל בשביל הסדר הטוב, מומלץ לסדר את המשתנים בצורה כזאת שלא תצטרכו להתאמץ יותר מדי כדי לדבג את הקוד, וגם לא להשתמש בהצהרה אחת של המילה var על 10 משתנים, קודם כל תחשבו על זה שאם שכחתם פסיק קטן בהוספה של משתנה, זה טיפה מעצבן, מה שגם מי שעובד עם כלים של debugging יודע שאין כמו לעבור שורה שורה משתנה משתנה ולהסתכל על התכולה שלו, מה שלא מאופשר עם הצהרה של var יחיד.
משתנים - תמיד מתחילים באות קטנה אם יותר ממילה אחת מחוברת אז פשוט עושים לכל מילה אחרי המילה הראשונה upper case לאות הראשונה.
קבועים - בJS אין באמת קבועים, מה שכן עדיף להיות חכם ופשוט לייצר משתנים שאנחנו בוודאות יודעים שאנחנו לא נוגעים בהם, והם יהיו הקבועים שלנו, קבועים תמיד באותיות גדולות,
חלוקה של רכיב אחד לתתי רכיבים:
טוב זה נושא קצת מורכב, ולא פשוט להסביר את כוונת המשורר, אבל נתחיל מהעקרון הפשוט פונקציה שמכילה יותר מ20 שורות, שמבצעות יותר מתפקיד אחד בתוך הפונקציה, זאת לא פונקציה שכתובה טוב והינה דוגמא:
var NotGoodCode = (function () { return { calculate: function () { var result = 0; for (var i = 0; i < arguments.length; i) { result = arguments[i]; } result = (Math.PI * 3000); $("#result").html(result); } } })();
|
הפונקציה תעבוד מצויין, הבעיה היחידה איתה היא מצב שבו יש באג, כרגע מדובר בפונקציה של כמה שורות בודדות, אז אנחנו נוכל לדבג את זה די בקלות ולפתור, אבל תדמיינו 500 שורות קוד, שמתעסקות עם HTML ועם חישובים, ובקשות לשרת, ומיליון דברים אחרים, קשה מאוד מאוד למי שאין ניסיון לדבג את זה, לכן יהיה נוח יותר לחלק את הפונקציה לפונקציות קטנות, ולטפל בחריגים בתוך כל פונקציה למשל: