JavaScript’s This – למפתחי ג’אווה ו #C מנוסים

“מפתח JavaScript הופך ממתכנת ממוצע למתכנת מקצועי ביום שהוא מבין את המילה השמורה this.כמפתחי ג’אווה או #C אתם אמורים להישאר כרגע פעורי פה: האם ייתכן ש”מתכנתי ג’אווהסקריפט” לא מבינים דבר בסיסי כמו המילה השמורה this?!
אבל בג’אווהסקריפט, כמו בג’אווהסקריפט – יש הפתעות במקומות הלא צפויים, ו this איננה יוצאת דופן.

חלק גדול ממפתחי הג’אווהסקריפט הם מפתחי צד שרת (Java, Ruby, #C) אשר משתמשים בה “לכתוב קצת UI”, סוג של “מפתחים מזדמנים”.
אתם לא באמת צריכים להבין את כל הפינות של ג’אווהסקריפט על מנת לפתח בווב. עבור רוב עבודות הג’אווהסקריפט, תוכלו להסתדר עם “להבין מספיק”.
אם אתם עושים עושים בג’אווהסקריפט קצת מעבר – להבין את this בהחלט יכול לעזור.

שייך לסדרה מבוא מואץ ל JavaScript ו jQuery

תשכחו את מה שידעתם בג’אווה / #C…

Scope בג’אווה כפי שאתם מכירים אותו. פשוט וברור.

בג’אווה, להבין את ה scope זה דיי פשוט: scope נוצר ע”י סוגריים מסולסלים.
אם אני רוצה לדעת מיהו המשתנה n – פשוט אטייל בעין, scope אחר scope עד שאמצא היכן הוא הוגדר.
אם אני רוצה לדעת מיהו this – פשוט אטייל בעין, scope אחר scope עד למחלקה הראשונה שאני רואה. כמעט תמיד תהיה רק מחלקה יחידה (קינון מחלקות הוא דיי נדיר בג’אווה).

בג’אווהסקריפט פיצלו את ה scope, כפי שקיים בג’אווה, לשניים:

  • Scope להגדרת משתנים, המוגדר ע”י פונקציה (ולא סוגריים מסולסלים! [א])
  • Context[ב] להגדרת this, המוגדר ע”י שייכות קונקרטית לאובייקט – בזמן ריצה. הסבר בהמשך.
הכללים לקביעת ה-context הם שונים מהכללים לקביעת ה scope. עצם ההבנה שהחוקים למציאת ה scope הם לא דומים לחוקים למציאת ה context – היא מחצית הדרך להבנה של this.

כיצד נוצר Context?

כלל #1: כאשר פונקציה (function) שאינה משויכת ישירות לאובייקט נקראתה context יהיה האובייקט הגלובלי. כלומר this יצביע לאובייקט הגלובלי. האובייקט הגלובלי הוא האובייקט עליו נרשמו כל המשתנים / פונקציות שהוגדרו ללא var או ללא שייכות לאובייקט כלשהו. בדפדפנים, האובייקט window (שמתאר Tab של דפדפן) נבחר לייצג את האובייקט הגלובלי. כל השמה “גלובלית” תתווסף עליו.

כלל #2: כאשר פונקציה המשויכת ישירות לאובייקט (מתודה method) נקראת – ה context שלה יהיה האובייקט אליו היא שויכה. כלומר, this יצביע לאובייקט שעליה היא הוגדרה, או ששויכה במהלך הריצה (דוגמאות בהמשך).

זהו זמן טוב לדוגמה.

השמשתי בצילומי מסך מה IDE האהוב עלי לכתיבת JavaScript, הרי הוא WebStorm. העטיפה “it” ומשפטי ה expect נובעים מכך שזו בדיקת-יחידה, הנעזרים בספרייה בשם Jasmine.
כל הבדיקות בפוסט זה עוברות, ולכם אתם יכולים להניח שהחלק שבתוך ה expect שווה לערך בתוך ה toBe.

ב1 אנחנו רואים שהפונקציה מחזירה את השם של האובייקט הגלובלי. בגלל שאני מריץ את הקוד בתוך “מריץ הבדיקות” השם שם האובייקט הגלובלי במקרה זה הוא “runner”.

ב2 הגדרנו אותה פונקציה על אובייקט – והנה this התייחס לאובייקט עליה הוגדרה – הרי הוא A.

ב3 השמנו את הפונקציה הקיימת function1 לאובייקט B. זה לא משנה איפה הקוד של הפונקציה נכתב – מה שחשוב היא ההשמה. מאותה הרגע getMe היא הצבעה לפונקציה function1 ב context של אובייקט B.
כאשר אנו מנסים לזהות את ה context של הריצה, תהיה זו טעות להתבונן רק על הפונקציה function1 (שהוגדרה במרחב הגלובלי). חשוב למצוא את הנקודה בה היא נקראה (שורה 3) ולראות שהיא נקראה מתוך אובייקט B.

המילה השמורה new, ומה שהיא עושה ל this…
בנאי (constructor) בשפת ג’אווהסקריפט היא פונקציה רגילה לכל דבר. הקונבנציה המקובלת היא לקרוא לבנאי בשם עם אות ראשונה גדולה (capital letter). שאר הקסם קורא בעת הפעלת הפונקציה עם המילה השמורה new.

שימוש במילה השמורה new גורם לשלושה דברים:

  • נוצר אובייקט חדש ריק – השקול לכתיבת “{ }”.
  • האובייקט החדש מועבר לבנאי, כפרמטר בשם this. הדברים האלו קורים מאחורי הקלעים – בקוד עצמו לא יהיה זכר ל this בחתימת הפונקציה.
  • במידה והבנאי לא סיפק ערך החזרה return (עדיף שלא יספק) – ג’אווהסקריפט מוסיפה return this ביציאה מהפונקציה.

הנה דוגמה:

במקרה זה, השתמשנו ב new על מנת לייצר אובייקט חדש.
למרות שהפונקציה ConstructorA (=בנאי) לא מוגדרת בתוך אובייקט, בזמן ההרצה this דווקא כן מתייחס לאובייקט.
מסקנה: אין לחפש את האובייקט במבנה הקוד, אלא לחפש את נקודת הקריאה (invocation) של הפונקציה ומאיזה context היא התבצעה.

הנה דוגמה בעייתית:

הבעיות הקשות לרוב לא צצות בפונקציות בנות 5 שורות – הן קורות באובייקטים בני עשרות או מאות שורות. הנה סימולציה לבעיה שיכולה להתרחש.
שימו לב למקרא הצבעים (יכול לעזור לעקוב):

  • משתנה / פונקציה מקומית = טורקיז.
  • משתנה / פונקציה של אובייקט = חום-צהוב.
  • (משתנה / פונקציה גלובליים = סגול)

ב1 קורה בדיוק מה שאנחנו מצפים – אנחנו מקבלים את A. זה שכפול של הדוגמה הקודמת.
ב2 הדברים משתבשים. אפשר בטעות לחשוב, שכל שימוש ב this בתוך הבנאי יתייחס לאובייקט החדש. זה לא המצב. במקרה זה הגענו לאובייקט הגלובלי.

הבעיה נובעת מכך שהפונקציה sayMyName איננה משויכת לאובייקט שנוצר – כי אם “נתלית” על ה scope של הפונקציה ConstructorA. הנה שמה צבוע בטורקיז = משתנה לוקאלי. אם אתם זוכרים את כלל #1 – פונקציה שלא קושרה לאובייקט משויכת ל context של האובייקט הגלובלי.
בגלל שמדובר ב closure [ג] היא תישאר “בחיים” ויהיה ניתן להשתמש בה גם לאחר שהפונקציה ConstructorA סיימה לרוץ.

Webstorm מזהה את הבעיה ואכן מציג אזהרה על ה this (מת עליו). כלי ניתוח ססטי כמו JSLint/JSHint – לא מזהים את המצב הזה. כנ”ל IDEs רבים אחרים.

למי שרוצה לחפור קצת יותר: ניתן לומר ש sayMyName דומה מאוד למתודה סטטית (static) בג’אווה: היא קיימת על המחלקה ולא מכירה את האובייקט – ולכן לא ניתן לגשת ממנה אל האובייקט. בעוד בג’אווה this בתוך מתודה סטטית היה מצביע על המחלקה – בג’אווהסקריפט הוא “הולך לאיבוד” ומצביע על האובייקט הגלובלי (בשל כלל #1).

הנה הפתרון המקובל לבעיה זו:

צרו משתנה (“that”) ב closure שיצביע על ה context הרצוי – ואז השתמשו בו.

השילוב של ג’אווהסקריפט ו this יכול לבלבל… 

הנה דוגמה שאני נתקלתי בה ולקח לי זמן לא מועט לאתר את הבעיה. התייחסו אליה כתזכורת כללית:

הקריאה ל ()objectD.objectF.getThatName זורקת שגיאה (error), בעוד רצינו שתחזיר “E”.

מה שקצת מבלבל הוא ההנחה שהקריאה this.objectE תגיע ל objectE – שהוא אובייקט אח ולא אובייקט בן.
ג’אווהסקריפט מצידה לא מודיע על בעיה: השימוש ב this.objectE מוסיף ל objectF משתנה חדש בשם objectE, שערכו undefined, ומיד אחר כך צועק על כך של undefined אין מתודה בשם getMyName. בעסה.

בקוד הקצר הזה – הבעיה קלה למדי לאיתור. בקוד “אמיתי”, בו יש אובייקטים ופונקציות רבים, אחד על גבי השני – קל לפספס.

אני חושב שמקור הבלבול הוא שאנו, בג’אווה, לא התעסקנו כמעט באובייקטים פנימיים. גם הפתרון לבעיה, להחליף את השורה ל:

    getThatName: function(){ return objectD.objectE.getName(); }

קצת מציק לי. שימוש רב במשתנים גלובליים והסתמכות על שם המשתנה אליו אנו משימים את האובייקט.

הנה תקלה נפוצה אחרת:

מה יותר טבעי למפתח ג’אווה מנוסה, מאשר לבצע introduce variable לצורך שיפור קריאות הקוד?
זהו, אני לא רוצה שתכנסו לפחד ותאמרו לעצמכם: “עם ג’אווהסקריפט לא מתעסקים. עדיף שהכל יהיה גלובלי ובלי שום ‘refactoring'”. בואו נבין מה קרה פה.

ההשמה של הפונקציה, התלויה על האובייקט, למשתנה שאינו תלוי על אובייקט (זכרו : טורקיז) – גרם לאיבוד ה context. ממש בקלות. חבל מאוד שאין כלים שעוזרים לאתר שגיאות שכאלו.

ספריית jQuery מציע utility function שיכולה לעזור, proxy.$ (לחצו על התמונה על מנת להגדיל):

proxy.$ מקבלת פונקציה ואובייקט (= context) ויוצרת פונקציה חדשה הקושרת “לעד” את ההרצה של הפונקציה ל context שנבחר.

אם אתם עובדים עם דפדפנים חדשים בלבד (+IE9), אתם יכולים להשתמש בפקודת bind של שפת ג’אווהסקריפט – שעושה בדיוק את אותו הדבר. proxy$ / bind שימושית במיוחד לצורך רישום אירועים:

השוו דוגמה זו לדוגמה הקודמת – הרעיון דומה.
ב1, לחיצה על הכפתור תפעיל את draw ב context של אובייקט ה button$[ד] – שאין לו מתודה בשם draw = תקלת זמן ריצה.
ב2, לחיצה על הכפתור תפעיל את draw ב context של האובייקט objectA – היכן שהמתודה אכן נמצאת.

Call ו Apply
כלי אחרון שאני רוצה להזכיר הוא המתודות Apply ו Call, המאפשרות להריץ מתודה מסוימת ב context שנקבע באותו הרגע.

כפי שאתם רואים call מאפשר להריץ מתודה (במקרה זה – של אובייקט A) על אובייקט (במקרה זה – D), כלומר – כך ש this יתייחס לאובייקט D.
כמובן שפונקציה לעתים דורשת ארגומנטים, call מאפשרת להוסיף אותם בסדר הנכון אחרי ה context שהועבר.
ההבדל בין call ו apply הוא רק בדרך בה מעבירים ארגומנטים לפונקציה – רשימת ארגומנטים או מערך. לא משהו גדול.

בפועל השימוש ב call יכול להיות מהיר עד פי כפליים מ apply – שוני שמשמעותי רק כאשר אתם עושים מאות או אלפי הפעלות של הפונקציה.

שיהיה בהצלחה!

——

[א] אתם יכולים לקרוא עוד קצת על הנושא בפוסט מבוא מואץ ל JavaScript עבור מפתחי Java / #C מנוסים – חלק 1, בערך באמצע.

[ב] רשמית נקרא Function Context, אבל יותר מדויק יהיה לקרוא לו Invocation Context.

[ג] ניתן לקרוא על Closure בסוף הפוסט מבוא מואץ ל JavaScript עבור מפתחי Java / #C מנוסים – חלק 1.

[ד] הכוונה ל wrapper של jQuery שעוטף את אלמנט הכפתור, אותו יצרנו בעזרת השאילתה (‘.button’)$.

מבוא מואץ לjQuery עבור מפתחי #C ו Java מנוסים

jQuery היא כל כך נפוצה בקרב מפתחי ווב, שניתן להתייחס אליה כחלק משפת JavaScript לדפדפן. קחו את jQuery מהעולם – ותמצאו מליון נשמות אבודות, שלא יודעות כיצד להמשיך ולכתוב אפליקציות ווב.הבהרה: jQuery היא ספרייה ל JavaScript – לא הרחבה לשפה. היא פשוט מסייעת במידה כ”כ רבה עד שהפכה אצל מפתחים רבים לחלק בלתי נפרד מכתיבת קוד ב JavaScript. כאשר דפדפן אינו מעורב (לדוגמה node.js) – אין לה שום משמעות.

מה יש בה ב jQuery שהיא כ”כ מצליחה, ורבים כ”כ תלויים בה?
בפוסט זה אנסה לענות על השאלה.

שייך לסדרה מבוא מואץ ל JavaScript ו jQuery

 

לא מזמן שאלה אותי מישהי כיצד אני בוחר את רמת העומק / הפרטים של הפוסטים? מדוע הם יחסית high level ולא בפרטים? לא ידעתי בעצמי מה לענות.
“כי זו הרמה הקריטית יותר להצלחת הפיתוח” – עניתי, אבל לא שכנעתי את עצמי.
“אולי בגלל שאני ארכיטקט וזו רמת הפרטים שאני רגיל לה?” – ניסיתי שוב. לא ממש ידעתי.
ישנתי על זה לילה. אני חושב ששתי הסיבות הן:

  • להגיע לקהל יעד רחב
  • לכסות נישות שלא מכוסות היטב – כלומר Value Proposition ייחודי.

הקדמה
על jQuery יש טונות של חומרים. רוצים לדעת מה ההבדל בין live ל bind? עשרות מקורות טובים ישמחו להסביר. עם מעט חיפוש, גוגל יפנה אתכם לתשובה בודדת ב StackOverflow שעונה בדיוק, אבל בדיוק, על המקרה שאתם מתמודדים איתו. אבל יש משהו שנראה לי ייחודי ושקשה למצוא – מבט גבוה קצת מהפרטים, מפוכח ובעברית – על מה שקורה שם.
לפני כתיבת פוסט זה חיפשתי בגוגל “jQuery Crash Course” או “jQuery introduction”. יש הרבה – אבל הם מספקים hands-on בכדי להתחיל להשתמש ב jQuery. הם לא מספקים הקדמה נאותה שתכין אתכם ללמידת jQuery או בכלל תעזור לכם להבין אם זה מה שאתם מחפשים. כשאני התחלתי ללמוד jQuery (לא כ”כ מזמן) – רציתי למצוא מישהו שיספר לי “מה העוקץ ב jQuery” – אך לא מצאתי. הנה זה לפניכם.

עלייתה של jQuery
תחילתה של jQuery היא בימי הביניים (של הדפדפנים – כמובן), ימים אפלים שהאנושות מנסה לשכוח.
בעוד JavaScript הייתה סטנדרטית (נניח…), ה APIs של הדפדפן לייצוג דף הHTML, מה שנקרא (Document Object Model (DOM, היה שונה למדי בין דפדפן לדפדפן. אמנם היו פונקציות עם שמות זהים (כמו getElementsByTagName) – אבל ההתנהגויות היו שונות. לעתים הן החזירו מבנים שונים, לפעמים הם קראו לאירועים (events) בסדר שונה. ובד”כ הן עשו את זה לאט ובצורה לא יעילה, תחת ההנחה ששינויים דינמיים ב DOM הם מעטים למדי. בקיצור: כל מה שלא הייתם רוצים מ API.
הכתיבה של קוד ווב Cross-Browser הייתה סיוט, ואכן רק אנשים מעטים הסכימו לעסוק במלאכה הבזויה[א]. ספריה שתספק API אחיד, אמין ומהיר עתידה להפוך לדבר שהמפתחים יהיו תלויים בו ולא יוכלו עוד בלעדיו.
כעשור מאוחר יותר, הדפדפנים מהירים יותר ואחידים יותר במבנה ה DOM APIs שלהם.
“מדוע מפתחים עדיין ‘תלויים’ ב jQuery?” – אפשר לשאול. ובכן, לשימוש ב jQuery יש הרבה תיעוד ודוגמאות – הרבה יותר מאשר שימוש ישיר ב DOM. בנוסף, בעוד ה API של ה DOM התפתח בקצב איטי ונשאר דומה למדי לתכנון בן 13+ שנים, jQuery יכלה להרשות לעצמה שינויים יותר דרמטיים שמשקפים יותר טוב את צורכי התקופה.

אז מה jQuery מספקת?
אמירה מקובלת היא ש “jQuery היא רק ספריה ל Selection” – אבל זה לא מדויק. jQuery מכסה מספר נושאים:

  • ביצוע שינויים ב DOM – קריאה וכתיבה.
  • מודל פשוט ואחיד יותר של אירועים (DOM events).
  • שיפורי ביצועים עבור טיפול בהרבה אירועים.
  • אנימציות – שיכולות להיות מופעלות על כל אלמנט ב DOM כמו Image, או Div שמאגד אלמנטים רבים.
  • הפשטה של XMLHttpRequest – מה שקרוי Ajax.
  • Utilities שונים לשימוש בג’אווהסקריפט, כגון each.$ או proxy.$

כפי שניתן לראות jQuery הוא דיי רוחבית. חוץ מהאנימציות שהן קצת “אקסטרה” – ספריה זו מספקת עטיפה ל DOM שמאפשרת לנו לעבוד איתו ברמת הפשטה קצת יותר גבוהה.

אלטרנטיבות
Prototype ו MooTools הן ספריות בעלות יכולות מקבילות, פחות או יותר. jQuery נצחה אותן בזכות קהילה, תיעוד טוב יותר או אולי אמינות גבוהה יותר.
Dojo, YUI או ExtJS/Sencha הן ספריות שמספקות רמת הפשטה גבוהה בהרבה ובעצם מנתקות אתכם מה DOM. הן נותנות למפתח לעבוד ברמה קרובה הרבה יותר ל Windows Forms או AWT ובעצם מייצרות מודל חדש אלטרנטיבי ל DOM שהמפתח עובד מולו.

יש המון כוח ויופי בכך ש jQuery לא מתארת מודל חדש, אלא רק מודל משופר של ה DOM. המפתח נותר עם קשר והבנה טובה בהרבה למה שקורה בפועל בתוך הדפדפן, ו jQuery יכולה להתחבר בקלות להמון ספריות שנכתבו בחשיבה על ה DOM. מי שרוצה ליצור ספרייה מעל YUI צריך לעבוד ע”פ המודל של YUI שעשוי בהחלט לא להתאים ל Dojo או ל ExtJS.

טעימה מיכולותיה של jQuery
לא אנסה להרשים אתכם בתצוגות-תכלית מגניבות. ה Adoption של jQuery הוא כבר מעבר לזה. אנסה לתת, בקצרה, טעימה מהיכולות העיקריות והסגנון של jQuery.

DOM Manipulation
בדומה לSQL בה יש משפטי SELECT…FROM…WHERE עם פורמט ידוע, גם ב jQuery יש דרך פעולה שחוזרת על עצמה. משפטי jQuery הם בעלי המבנה הבא:

$(‘selection’).();
בחר שורה של אלמנטים – ובצע עליהם משהו: שינוי של HTML, CSS, רישום לאירועים ועוד.
חלק גדול מהיופי של jQuery היא הדרך בה היא משתלבת בטבעיות בנוף של HTML, JavaScript ו CSS. שפת CSS עושה פעולה דומה: בוחרת אלמנטים ב DOM (כלומר ב HTML) ומחילה (כלומר apply) עליהם עיצוב.
jQuery משתמשת בתחביר של javaScript לתאר את אותה התבנית. הנה דוגמה:
$(‘.banner’).css(‘background-color’, ‘red’);
שהיא המקבילה לכתיבת ה CSS הבא:
.banner {
  background-color : red;
}

מפתח שחדש ל jQuery אך בקיא ב CSS יוכל ללא קושי להגדיר שאילתות דיי מורכבות.
jQuery לא אמורה להיות תחליף ל CSS – לצורך זה היא תהיה משמעותית פחות יעילה, אבל היא מאפשרת באותה דרך חשיבה לבצע שינויים מרחיקי לכת בעזרת שורות בודדות של קוד.
התחביר של jQuery, בדומה ל javaScript, תומך בשרשור (chaining). פעולת ה Select מחזירה רשימה (באורך 0, 1 או יותר) של אלמנטים ב DOM. כל אחת מפעולות ה execute מחזירה את אותה הרשימה של אובייקטים עליה נקראה, כך שיהיה ניתן לשרשר עליה עוד ועוד פעולות:

$(‘div > p’).show().css(‘color’, ‘blue’).removeClass(‘selection’);

קריאה זו תבחר את אלמנטי ה p (פסקה ב HTML) שנמצאים ישירות בתוך div, תציג אותם, תחיל על הטקסט צבע כחול ותסיר class בשם selection – אם קיים.
אם ננסה לתאר בצורה יותר כללית את תבנית כתיבת הביטויים ב jQuery – אפשר לתאר אותם כך:

$(‘selection’).().().().execute();

פעולת הפילטר היא פעולה שמצמצמת את רשימת האובייקטים. “צמצום” יכול להיות גם פעולת בחירה במקרה זה, כאשר find בוחרת את אלמנטי ה strong הבנים לאלמנטי ה div שבחרנו:

$(‘div’).css(‘border’, ‘1px solid blue’).fadeTo(‘slow’, 0.5).find(‘strong’).css(‘color’, ‘red’);

הנה דוגמת ההרצה של קוד זה. אין מניעה שיהיו יותר אלמנטים של strong מאלמנטים div-אבות כמובן, כך שהשם “צמצום” (filter) הוא שם בהחלט לא מדויק. וריאציה אחרת של צמצום נקראת “טיול” או traversal. בעזרת פקודות כגון ()parent או ()siblings אפשר “לטייל” על ה DOM מהנקודה בה אתם נמצאים.

יש מספר רב של פעולות execute, traversal ו filter אפשריות – אני בטוח שגוגל יוכל לעזור לכם למצוא מידע רב על כולן.

טיפול באירועים (events)
jQuery מספקת רמת הפשטה נוחה יותר לאירועים ב DOM. לדוגמה, עבור hover סביר שמפתח יבחר להירשם לאירועים של ה DOM בשם mouseOver ו mouseOut, אבל היכרות אינטימית תלמד שברוב הדפדפנים שימוש ב mouseEnter ו mouseLeave הוא עדיף. jQuery חוסכת לכם ללמוד פרטים כאלו ומספקת אירוע hover (שדורש 2 פונקציות: כניסה ויציאה) שידע לעשות את הדבר הנכון עבור כל דפדפן.
עוד צרה קשה היא רישום מופעים רבים של אירוע.
נאמר שיש לכם גלריה עם 100 תמונות על המסך, שבפעולת Hover אתם רוצים להדגיש את התמונה (אחת מ 100) שכרגע העכבר מצביע עליה. הדרך הנאיבית היא לרשום את אירוע ה hover והטיפול בו 100 פעם, פעם עבור כל תמונה בגלריה. מחיר הביצועים עלול להיות הרסני.
עדיף בהרבה לרשום את אירוע ה hover פעם אחת על כל הגלריה, לאתר את התמונה הרלוונטית לאירוע ואז להפעיל את קוד הטיפול באירוע בעזרת ההקשר הנכון.
שיפור הביצועים הוא משמעותי מאוד, אבל לדפדפנים שונים יש חוקים שונים כיצד לעשות זאת. jQuery מספקת הפשטה טובה לסיבוכיות זו ונותנת לכם לרשום אירועים על “קבוצה של אלמנטים” בקלות רבה.

כיצד jQuery עובדת? (בקצרה)
jQuery היא ספריית JavaScript לכל דבר. מוסיפים אותה ל HTML Header ואז ניתן להשתמש בה.
jQuery רושמת אובייקט גלובלי בשם $ (שם חוקי ב javaScript) שהוא משמש כמפתח לפעולות שונות של הספריה.
כאשר מבצעים Selection (כלומר “בחירה”) – לא מקבלים רשימה של האובייקטים האמיתיים ב DOM, כי אם wrappers של jQuery שמספקים API בטוח, cross-browser, ופשוט יותר.
ל jQuery יש אלגוריתם יעיל לביצוע selection ב DOM. הוא נקרא Sizzle וניתן למצוא אותו כספריית javaScript עצמאית. ספרייה זו באמת “רק עושה selection”. הנה כמה כללים איך להשתמש ב jQuery בצורה יעילה.
יש שמועות על כך ש jQuery מבצעת caching לאלמנטים ב DOM. שמעתי אותן לא פעם. לא נתקלתי מעולם בזכר להתנהגות שנראתה כמו caching עבור פעולות DOM. בעיקרון, גישה ישירה ל DOM אמורה להיות תמיד מהירה יותר משימוש ב jQuery.

Plug-ins

ניתן לכתוב plugins ל jQuery. בפועל plugin הוא פונקציה שנרשמת על ה namespace של jQuery (כלומר, סימן ה $) ויכולה להשתלב בתבנית ה Select-execute.
לדוגמה, אני יכול לכתוב פונקציה שהופכת אלמנטים להציג מימין לשמאל, ע”י שינוי כל פרטמר אפשרי לתמוך בהתנהגות זו. במקום לקבל רשימה של wrappers ולעבור עליהם בלולאה, יהיה הרבה יותר אלגנטי להשתמש בפונקציה שלי בצורה הבאה:

$(‘.text .localizable’).toRTL();

יש כמה כללים (המנעות מהתנגשויות על הסימן $, אתחול, …) שכדאי להקפיד עליהם בעת כתיבת jQuery Plugin – יש מדריכים רבים באינטרנט שישמחו לספר ולהדגים זאת.
סה”כ ראיתי כמה jQuery Plugins שלא הייתה להם הצדקה אמיתית להיכתב כ Plugin. אני מנחש שאם jQuery הייתה קוראת ל Plugins בשם פחות מרשים (כמו jQuery Chained Function) – היו נכתבים הרבה פחות Plugins של jQuery.


[א] הפוסט מופנה למפתחי Server בשפות מודרניות, שם ה APIs המקובלים טובים בהרבה.