מדוע this של אוביקט הבן לא מחזיר מאפיין של אוביקט האב
-
מצורף קוד של יצירת אוביקט מפונקציה ע"י new, ובמאפיין שלו נשמר אוביקט נוסף עם מתודה שמבקש מאפיין שנמצא רק באביקט האב, אבל הוא לא מחזיר אותו על אף שאין מאפיין כזה באוביקט "הבן".
מדוע
myClass.o.get3()לא מחזיר את
myClass.aהלא אחד התכונות פונקצית החץ שהוא תמיד מחפש באביקט הראשון?!function Fun1 () { this.a=9; this.get1 = _=> this.a; this.get2 = _=> this.b; } function Fun2 () { this.b=9 this.get3 = _=> this.a; this.get4 = _=> this.b; } var myClass = new Fun1() myClass.o = new Fun2(); console.log(myClass.get1(), myClass.get2(), myClass.o.get3(), myClass.o.get4() ) //9 undefined undefined 9 -
מצורף קוד של יצירת אוביקט מפונקציה ע"י new, ובמאפיין שלו נשמר אוביקט נוסף עם מתודה שמבקש מאפיין שנמצא רק באביקט האב, אבל הוא לא מחזיר אותו על אף שאין מאפיין כזה באוביקט "הבן".
מדוע
myClass.o.get3()לא מחזיר את
myClass.aהלא אחד התכונות פונקצית החץ שהוא תמיד מחפש באביקט הראשון?!function Fun1 () { this.a=9; this.get1 = _=> this.a; this.get2 = _=> this.b; } function Fun2 () { this.b=9 this.get3 = _=> this.a; this.get4 = _=> this.b; } var myClass = new Fun1() myClass.o = new Fun2(); console.log(myClass.get1(), myClass.get2(), myClass.o.get3(), myClass.o.get4() ) //9 undefined undefined 9@אהרן אמר במדוע this של אוביקט הבן לא מחזיר מאפיין של אוביקט האב:
הלא אחד התכונות פונקצית החץ שהוא תמיד מחפש באביקט הראשון?!
ברשות בעה"ב מרנן ורבנן וכו' אנסה לענות.
הכלל הוא ש
(this של פונקציית חץ) === (this של יוצר הפונקציה).
פונקציית חץ אין לוthisמשל עצמו.
ולכן, במקרה של()get3שיוצר הפונקציה הואFun2, לכן ה-thisשלו מאוגד באופן קבוע ל-thisשלFun2.אם היית כותב כך:
Fun1 = { a:9, get1: function(){return this.a}, get2: function(){return this.b} } Fun2 = { b:9, get3: _=> this.a, get4: _=> this.b } var myClass = Fun1; myClass.o = Fun2; console.log(myClass.get1(), myClass.get2(), myClass.o.get3(), myClass.o.get4() ) // 9 undefined undefined undefinedמכיון שעכשיו אתה מייצר את פונקציית החץ לא בתוך פונקציה אלא ב-scope הגלובלי, אז ה-
thisשלו הוא ה-thisהגלובלי שהואWindow(בדפדפן), ואין לו מאפיין בשםaאוb.ובקיצור, ה-
thisשל פונקציית חץ לא קשור בכלל ל-thisשל אובייקט האבא אלא ל-thisשל יוצר הפונקציה.מקורות
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#Arrow_functions
הערות
אני תמיד לוקח שאלות כאלו כהזדמנות ללימוד, לכן הגם שעד לפני כמה דקות לא היה לי חצי מושג איך לענות, אבל נ"ל שמצאתי את התשובה. אם טעיתי, חזקה על חברים דפה שיתקנו...
גם אני מחכה לשמוע עוד הבהרות מאחרים. -
לא בטוח שהבנתי את הצורך שלך, אבל לכאורה לזה בדיוק נכתבה פרשת ירושה, משהו כזה:
class Fun1{ a=9; get1 = _=> this.a; get2 = _=> this.b; } class Fun2 extends Fun1 { b=9 get3 = _=> this.a; get4 = _=> this.b; } var myClass = new Fun2() console.log(myClass.get1(), myClass.get2(), myClass.get3(), myClass.get4() ) -
function Fun1 () { this.o = new Fun2() this.o.parent = this; this.a=9; this.get1 = _=> this.a; this.get2 = _=> this.b; } function Fun2 () { this.b=9 this.get3 = _=> this.parent.a; this.get4 = _=> this.b; } var myClass = new Fun1() console.log(myClass.get1(), myClass.get2(), myClass.o.get3(), myClass.o.get4() ) -
לשם השלמת נושא "
thisבתוך פונקציית חץ" -לְמַה ולָמָה המציאו פונקצייות חץ
א. זה לא רק "סוכר תחבירי" להקל על יצירת פונקציות אנונימיים (יכול להיות שזה גם נכון, אבל אם זו היתה הסיבה היחידה, לא היו עושים הבדלים בינו לבין פונקצייה רגילה.)
ב. אז מה כן? פונקציית חץ הוא טוב עבור callback. למה? כי בפונקצייה רגילה כאשר מעבירים מתודה של אובייקט לתוך callback ורוצים לפעול על האובייקט בעל המתודה, א"א להתייחס לאובייקט האבא ע"י מילת המפתח
this, כיthisמאוגד לאובייקט האבא רק כאשר קורים את הפונקציה מתוך האבאאובייקט.מתודה()אבל אם נאמרvar מתודה2 = אבא.פונקציה; מתודה2();אז ה-thisשל הפונקצייה מאוגד ל-window(בדפדפן). והרי זה מה שקורה כאשר ה-callback נקרא.
אז פעם בימי החושך היו צריכים לאגד בפירוש כל פונקצייה שמעבירים לתוך callback לאובייקט. אבל היום אפשר לכתוב פונקציית חץ ואז ה-thisמאוגד אוטומטי ל-thisשל האובייקט שהפונקציה שייך לו.דוגמא:
function Obj(id) { this.id = id; this.logme = function() {console.log(`id:${this.id}`)} } myobj = new Obj(22); myobj.logme(); //"id:22" setTimeout(myobj.logme, 1000); //"id:undefined" //פעם היו עושים כך: setTimeout(myobj.logme.bind(myobj), 1000); //או שהיו מגדירים את האובייקט כך: function Obj(id) { self = this this.id = id; this.logme = function() {console.log(`id:${self.id}`)} } //והיום אפשר כך: function Obj(id) { this.id = id; this.logme = () => console.log(`id:${this.id}`); }