אינטרנט ישראל
  • ראשי
  • אודות רן בר-זיק ואינטרנט ישראל
  • ערוץ טלגרם
  • מסטודון
  • התחברו אלי בטוויטר
  • התחברו אלי בלינקדאין
  • ספר ג'אווהסקריפט
  • ראשי
  • אודות רן בר-זיק ואינטרנט ישראל
  • ערוץ טלגרם
  • מסטודון
  • התחברו אלי בטוויטר
  • התחברו אלי בלינקדאין
  • ספר ג'אווהסקריפט
ראשי » פיתוח אינטרנט » יסודות בתכנות » Monkey patching

Monkey patching

רן בר-זיק ינואר 12, 2020 7:07 am 8 תגובות

טכניקה פשוטה (ומסוכנת) להוספת תכונות לאובייקטים קיימים בג'אווהסקריפט שכדאי להכיר

כדאי תמיד להשאר מעודכנים! אם יש לכם טלגרם, בדקו את ערוץ הטלגרם של האתר שבו אני מעדכן על פוסטים חדשים 🙂 אם אתם רוצים ללמוד תכנות באופן מקיף ומסודר, הצטרפו לאלפי הלומדים בפרויקט "ללמוד ג'אווהסקריפט בעברית" שמלמד לתכנת בג'אווהסקריפט, ב-Node.js ובריאקט וגם מלמד על תרומה לקוד פתוח. גם ספרים דיגיטליים וגם ספרים מודפסים. בשיתוף הקריה האקדמית אונו ובתמיכת חברות מובילות כגון Wix, Outbrain, Elementor, Iron Source, Chegg, Really Good ועוד.

במאמר הזה אני מסביר על Monkey patching, שם פופולרי לטכניקה בסיסית אך מסוכנת לשימוש. בשימוש נבון וזהיר היא יכולה להיות שימושית ובכל מקרה, כדאי מאוד להכיר את הטכניקה ואת המונח.

לא מעט מתכנתים מחפשים תכונה מסוימת בשפה, בפריימוורק או בספריה ומתאכזבים לגלות שהיא לא נמצאת. לא חסרים מקרים כאלו. כמו למשל, לגלות שבמערך אין לי מתודת endsWith. משהו בסגנון הזה:

const myArray = ['avi', 'itzik', 'yaki'];

console.log(myArray.endsWith('yaki')); // true

console.log(myArray.endsWith('sarah')); // false

אם תריצו את הקוד הזה, תקבלו שגיאה מסוג:
Uncaught TypeError: myArray.endsWith is not a function

מסיבה מאוד פשוטה, המתודה endsWith קיימת בג'אווהסקריפט רק בסוג המידע הפרימיטיבי מחרוזת טקסט, לא במערך. אבל אם אני כן רוצה שזה יהיה? מתכנת אחראי יצור איזושהי ספרית utils בסגנון הזה:

const Utils = {
  endsWith: (arr, arg) => arr[arr.length - 1] === arg ? true : false,
}

const myArray = ['avi', 'itzik', 'yaki'];

console.log(Utils.endsWith(myArray, 'yaki')); // true;

אבל זה עלול להיות מעיק ובעייתי. צריך לזכור שיש את ה-Utils וכל מי שכתב קוד מורכב יודע שספריות העזר האלו נוטות להתנפח. זה הדבר הכדאי לעשות בסופו של דבר, אבל יש דרך נוספת שנקראת Monkey Patching – לשנות את הקוד בזמן הריצה או יותר נכון, בג'אווהסקריפט, לשנות את הפרוטוטייפ של האובייקט בזמן אמת. בג'אווהסקריפט יש לנו את prototype, שמהווה את הבסיס של השפה. לכל אובייקט ואובייקט אפשר לגשת ולשנות את המתודות שלו באמצעות prototype. אני יכול להעניק לסוג המידע הפרימיטיבי Array את המתודה endsWith כך שתהיה זמינה במערך.

Array.prototype.endsWith = function(arg) {
  return this[this.length - 1] === arg ? true : false;
}

const myArray = ['avi', 'itzik', 'yaki'];

console.log(myArray.endsWith('yaki')); // true

console.log(myArray.endsWith('sarah')); // false

See the Pen monkey patching JavaScript array by Ran Bar-Zik (@barzik-the-vuer) on CodePen.

בעצם מהרגע שהוספתי ל-Array.prototype את התכונה endsWith, היא תהיה זמינה לכל מערך ומערך בקוד שלי – גם לקוד חיצוני.

אני יכול לשנות גם תכונה קיימת כמובן. גם עם פרוטוטייפ אבל גם לשנות דברים בסקופ הגלובלי (פעם היינו משתמשים ב-window, היום ב-globalThis) למשל, אם אני רוצה שכל console.log יודפס דווקא כ-console.error, אני יכול לעשות משהו כזה:

globalThis.console.log = (arg) => globalThis.console.error(arg);

למה זה מסוכן ולא מומלץ? ובכן, אני חושב שזה די ברור מאליו. להוסיף תכונה מסוימת למשתנה זה עוד איכשהו עובר, אבל אם נשנה תכונה קיימת, זה עלול לשבור ספריות ושימושים קיימים בקוד. זה גם עלול ליצור לנו תלויות לא מבוקרות. כך למשל, אם במעמקי הקוד אני סומך על כך שיש לי Array.endsWith, אני עלול לשכוח שזה תלוי בקוד שרץ קודם לכן וכך ליצור מורכבות לא נדרשת בקוד.

אם יש צורך בתוספות כאלו, אפשר להשתמש בדקורטורים. ועל כך, אולי, במאמר הבא 🙂

מצד שני, יש שימוש אחראי ב-Monkey patching. בדרך כלל אם אנו רוצים לכבות שגיאות או התראות ב-console ולפתוח אותם רק למתכנתים שמדבגים את הסביבה. בנוסף, כאשר אנו יוצרים פוליפילים כדי לתמוך בדפדפנים ישנים, זו הדרך היחידה שלנו לעשות את זה.

אם אתם בוחרים ב-monkey patching למרות האזהרות, כדאי מאוד להקיף את השימוש במתודה הנוספת בבדיקה שהיא קיימת. באופן אישי? למעט דיבאגינג או שינוי ה-console.log, אני נמנע מכך. אבל חשוב להכיר את המונח.

כדאי תמיד להשאר מעודכנים! אם יש לכם טלגרם, בדקו את ערוץ הטלגרם של האתר שבו אני מעדכן על פוסטים חדשים 🙂 אם אתם רוצים ללמוד תכנות באופן מקיף ומסודר, הצטרפו לאלפי הלומדים בפרויקט "ללמוד ג'אווהסקריפט בעברית" שמלמד לתכנת בג'אווהסקריפט, ב-Node.js ובריאקט וגם מלמד על תרומה לקוד פתוח. גם ספרים דיגיטליים וגם ספרים מודפסים. בשיתוף הקריה האקדמית אונו ובתמיכת חברות מובילות כגון Wix, Outbrain, Elementor, Iron Source, Chegg, Really Good ועוד.
ג'אווה סקריפט ו-jQuery באתרי אינטרנט

8 תגובות

  1. משתמש אנונימי (לא מזוהה) הגב ינואר 12, 2020 בשעה 9:06 am

    תודה. איך בודקים שהמתודה קיימת?

    • Royi Namir הגב ינואר 12, 2020 בשעה 9:23 am

      you don't

    • שחר הגב ינואר 12, 2020 בשעה 11:21 am

      אפשר לבדוק כך:
      if (arr.endsWith) {
      // it's true so do you stuff
      }

  2. Royi Namir הגב ינואר 12, 2020 בשעה 9:21 am

    That's why you shouldn't use monkey patcking and use the symbol which is exactly what it was invented for .
    This way , you don't touch any other proto methods.

    see here :

    https://jsbin.com/sovusecixe/1/edit?html,js,console

    const symbol = Symbol('endsWith');

    Array.prototype[symbol] = function(arg) {
    return this[this.length – 1] === arg ? true : false;
    }

    const myArray = ['avi', 'itzik', 'yaki'];

    console.log(myArray[symbol]('yaki')); // true

    console.log(myArray[symbol]('sarah')); // false

  3. Royi Namir הגב ינואר 12, 2020 בשעה 9:22 am

    Sorry this is the right jsbin

    https://jsbin.com/sovusecixe/2/edit?html,js,console

  4. יותם הגב ינואר 12, 2020 בשעה 3:00 pm

    למה בדוגמת הקוד יש גם === וגם לאחר מכן ?true:flase? הערך שמחזיר === הוא בעצמו בוליאני

  5. חיים ארוכים הגב ינואר 12, 2020 בשעה 5:34 pm

    חסר הסבר למה לעזאזל זה נקרא monkey patching ולא cute cat patching.

  6. עובד סוציאלי הגב ינואר 19, 2020 בשעה 1:48 am

    רן, תסתכל בבקשה במייל שלך המקושר לאתר. תודה.

השארת תגובה

ביטול

ללמוד ג'אווהסקריפט בעברית

ללמוד לתכנת ג'אווהסקריפט בעברית שגייס יותר משלוש מאות אלף שקל ולמעלה מ-2000 תומכים - בואו ללמוד עכשיו איך לתכנת.

רשימת הנושאים
  • מדריכים
    • ריאקט
    • טייפסקריפט
    • ECMAScript 6
    • ES20XX
    • Node.js
    • Express
    • רספברי פיי
    • Babel
    • docker
    • MongoDB
    • Git
    • לימוד MySQL
    • SASS
    • jQuery
    • CSS3
    • HTML 5
    • SVN
    • LESS
  • פיתוח אינטרנט
    • פתרונות ומאמרים על פיתוח אינטרנט
    • jQuery Scripts
    • jQuery למתקדמים
    • יסודות בתכנות
    • נגישות אינטרנט
  • חדשות אינטרנט
  • מידע כללי על אינטרנט
    • רשת האינטרנט
    • בניית אתרי אינטרנט
  • rss logo

    לכל המאמרים

    לכל המאמרים שפורסמו באינטרנט ישראל משנת 2008 ועד עכשיו.
  • rss logo

    RSS Feed

    משתמשים בקורא RSS? אם כן, עקבו אחרי אינטרנט ישראל באמצעות פיד ה-RSS!
    מה זה RSS?
  • Twitter logo

    עקבו אחרי בטוויטר

    בחשבון הטוויטר שלי אני מפרסם עדכונים מהירים על חדשות בתחום התכנות והיזמות, התרעות על מצבי חירום ורכילות בוערת על תחום הווב.
    מה זה טוויטר?
  • facebook like image

    ערוץ הטלגרם של אינטרנט ישראל

    בערוץ הטלגרם של אינטרנט ישראל אני מפרסם את הפוסטים של באתר וכן עדכונים טכנולוגיים נוספים.
    מה זה טלגרם?
  • github logo

    הפרויקטים שלי בגיטהאב

    הפרויקטים שאני כותב ושוחררו לציבור ברישיון קוד פתוח נמצאים ברובם בגיטהאב.
חיפוש

כל הזכויות שמורות לרן בר-זיק ולאינטרנט ישראל | מדיניות הפרטיות של אתר אינטרנט ישראל | אתר אינטרנט ישראל נגיש לפי תקן WCAG 2.0 AA | הצהרת הנגישות של האתר | אבטחת מידע ודיווח על בעיית אבטחת מידע

גלילה לראש העמוד