مقدمة
هناك الكثير من المعلومات على الإنترنت حول كيفية عمل ذلك ، لكن طوال الوقت لم يكن لدي ما يكفي حرفيًا لفهمها تمامًا.
في الآونة الأخيرة ، ما زلت ، كما يبدو لي ، قد فعلت ذلك وأود أن أشارككم.
بدون كلمات كثيرة
سنغطي الأمثلة البسيطة والمعقدة - لذلك سيكون الجميع مهتمًا.
هناك نقطتان رئيسيتان سننظر فيهما:
(1) بالنسبة للوظائف المعلنة عبر الوظيفة () {} ، يتم حساب ذلك في وقت الاستدعاء.
(2) بالنسبة لوظائف الأسهم ، يتم تحديد ذلك عند إنشاء الوظيفة.
لنبدأ ببعض الأمثلة البسيطة.
function globalFunc() {
console.log(this);
}
const globalArrowFunc = () => {
// , this - window/undefined
// , use strict this === undefined
console.log(this);
}
globalFunc(); // undefined
globalArrowFunc(); // undefined
ماذا لو أضفنا هذه الوظائف إلى الكائن:
const cat = {
name: 'Pirate',
globalFunc,
globalArrowFunc
};
cat.globalFunc(); // { name: 'Pirate', ... }
cat.globalArrowFunc(); // undefined
دعونا نفهم ذلك.
أعاد لنا استدعاء cat.globalFunc () كائن قطة. لتسهيل الفهم ، يمكنك التفكير في الأمر على النحو التالي "هذا ، عند استدعاء الدوال المعلنة عبر الوظيفة () {} ، ستكون مساوية للكائن قبل النقطة".
إذن لماذا عاد cat.globalArrowFunc () غير محدد بالنسبة لنا؟ الحقيقة هي أن هذه القيمة لوظيفة السهم يتم تحديدها في وقت إنشائها ، وعندما أنشأناها ، كانت هذه القيمة غير محددة.
لنقم الآن بإنشاء كائن بطريقتين:
const dog = {
name: 'Viking',
//
//
localFunc: function() {
console.log(this);
},
localArrowFunc: () => {
console.log(this);
}
};
dog.localFunc(); // { name: 'Viking', ... }
dog.localArrowFunc(); // undefind
لماذا هذا؟
dog.localFunc () - لأن الكائن قبل نقطة الكلب.
dog.localArrowFunc () - لأنه داخل الكائن يكون هذا أيضًا كائنًا عالميًا ، مما يعني أننا نحصل على غير معرف.
دعونا نعقد مثالنا قليلاً.
const dog = {
name: 'Viking',
localFunc: function() {
const arrowFuncInLocalFunc = () => {
console.log(this);
};
function funcInLocalFunc() {
console.log(this);
};
arrowFuncInLocalFunc(); // 1
funcInLocalFunc(); // 2
},
localArrowFunc: () => {
const arrowFuncInLocalArrowFunc = () => {
console.log(this);
};
function funcInLocalArrowFunc() {
console.log(this);
};
arrowFuncInLocalArrowFunc(); // 3
funcInLocalArrowFunc(); // 4
}
};
dog.localFunc();
// 1 - { name: 'Viking', ... }
// 2 - undefind
dog.localArrowFunc();
// 3 - undefind
// 4 - undefind
دعنا نفهم ذلك!
(1) arrowFuncInLocalFunc () // {name: 'Viking'،…}
لماذا يحدث هذا؟
لأننا عندما أنشأنا الكائن ، كتبناه دالة localFunc. وكما نتذكر من الأمثلة السابقة ، فإن هذا بالنسبة لها هو الشيء قبل النقطة ، أي {الاسم: "فايكنغ" ، ...}. الآن دعنا نتحدث عن وظيفة arrowFuncInLocalFunc نفسها - يتم إنشاؤها على الفور عندما يتم استدعاء localFunc وتتذكر هذه القيمة التي كانت في مكان إنشائها. لذلك نحصل على هذا arrowFuncInLocalFunc الذي يعيد لنا {name: 'Viking'،…}.
(2) funcInLocalFunc () // undefind
لماذا يحدث هذا؟
كما قلنا سابقًا ، بالنسبة للوظائف المعلنة عبر الوظيفة () {} ، يتم تحديد هذه القيمة في وقت الاستدعاء وتساوي الكائن قبل النقطة. في هذه الحالة ، ليس لدينا كائن أمام النقطة ، مما يعني أن هذا كائن عالمي أو ، في حالتنا ، غير محدد.
(3) arrowFuncInLocalArrowFunc () // undefined
لماذا يحدث هذا؟
هذا المثال مشابه جدًا لـ (1) ، يتم إنشاء وظيفة arrowFuncInLocalArrowFunc الخاصة بنا فقط داخل وظيفة السهم نفسها. نتذكر أيضًا أن وظائف السهم في وقت إعلانها تكتب هذه القيمة من بيئتها. ومع ذلك ، تم إنشاء وظيفتنا داخل localArrowFunc ، والتي لم يتم تعريفها. هذا يعني أنه بالنسبة لـ arrowFuncInLocalArrowFunc سيكون هذا غير محدد.
(4) funcInLocalArrowFunc () // undefined
لماذا يحدث هذا؟
بالضبط نفس السبب كما في (2) لـ funcInLocalFunc
دعونا نلقي نظرة على مثال آخر:
const cat = {
name: 'Tom',
getFuncWithTomName: function() {
return () => {
console.log(this.name);
}
}
};
const mouse = {
name: 'Jerry',
logName: cat.getFuncWithTomName()
};
mouse.logName(); // Tom o_O !?
هذا لأن getFuncWithTomName يقوم بإنشاء دالة سهم وإرجاعها ، وعندما يتم إنشاء وظيفة السهم ، يكون هذا هو نفسه getFuncWithTomName. وبالنسبة لـ getFuncWithTomName ، هذا هو الكائن قبل النقطة (cat).
مجموع
يتم تحديد سياق وظائف السهم عند إنشائها.
يتم تعريف سياق الوظيفة () {} عندما يتم استدعاؤها ويكون مساويًا للكائن قبل النقطة.