المقدمة
في هذه المقالة سنتكلم عن This keyword في JavaScript وهي تعتبر واحدة من أكثر المفاهيم اللى بتلخبط المبرمجين ودا لأن قيمتها تتغير على حسب السياق اللي الكود بيتنفذ فيه وازاي تم كتابة الـ function الموجودة فيها.
دور This
تحمل This قيمة ال object المسئول عن تنفيذ الكود أو الذي قام باستدعاء الدالة.
Global Context (window)
أولاً استخدام this في ال global context = window هنلاقي في المثال الأول تم تنفيذ الكود في الـ global لذلك هتكون قيمة this بتساوي ال window object
//example 1
console.log(this); //{window: Window, self: Window, document: document, name: '', location: Location, ...}
window.x = "x";
console.log(this.x); // "x"
Method
أما استخدام this في سياق الـ Functions هنلاقي قيمتها بتتغير على حسب كيفية استدعاء الـ Function.
// example 2
const obj = {
a: "a",
method: function () {
console.log(this);
},
};
obj.method(); // output=> {a: 'a', method: ƒ}
هنلاقي في المثال ده اللي عمل استدعاء للـ Function هو obj هتكون قيمة this هي ال obj.
ملحوظة مهمة: قيمة this بتتحدد عند استدعاء الـ Function. كما موضح في المثال الثالث
//
example 3
const obj1 = {
a: "one",
method: function () {
console.log(this);
},
};
const obj2 = {
a: "two",
};
obj2.method = obj1.method;
obj1.method(); // output=> {a: 'one', method: ƒ}
obj2.method(); // output=> {a: 'two', method: ƒ
هنلاقي هنا this قيمتها اتغيرت على حسب مين عمل استدعاء لها.
Regular Function
عند استخدام This في regular function هنلاقي إن دائما قيمتها بتكون الـ window object بغض النظر عن السياق اللي تم تنفيذ الكود فيه كما في المثال الرابع
//
example 4
"use strict";
const regularFunc = function () {
console.log(this);
};
regularFunc(); // output=> Window {window: Window, self: Window, document: document, name: '', location: Location, …}
هنلاقي قيمة this وده لأنه يعتبر اللي استدعى الدالة هو الـ window object.
و زي ماقولنا إن قيمتها بتكون window object بغض النظر عن السياق في المثال الخامس هنوضح الكلام ده.
// example 5
const obj = {
a: "one",
method: function () {
console.log(this);
return function () {
console.log(this);
};
},
};
obj.method(); // output=> {a: 'one', method: ƒ}
obj.method()(); // output=> Window {window: Window, self: Window, document: document, name: '', location: Location
هنلاقي قيمة this الأولي بتشير لـ obj لانها اللي استدعت ال method ولكن الثانية تم تنفيذها بداخل regular function لذلك هتكون قيمتها window obj بغض النظر عن مين استدعاها.
example 6
"use strict";
const regularFunc = function () {
console.log(this);
};
regularFunc(); // output => undefined
const obj = {
a: "one",
method: function () {
console.log(this); // output => {a: 'one', method: ƒ}
return function () {
console.log(this); // output => undefined
};
},
};
obj.method(); // output=> {a: 'one', method: ƒ}
obj.method()(); // undefined
لو فكرنا هنا هنلاقي إن أي this كانت قيمتها window في ال strict mode هتكون قيمتها undefined وده منطقي لان القاعدة بتقول إن this بتشيل قيمة ال object اللي عملها call هنلاقي في المثال السادس إن ()regularFunc مفيش obj عملتلها call.
Arrow Function
مفهوم this في ال Arrow function مختلف شوية في الدالة العادية قيمة this بتتحدد وقت استدعاء الدالة وبتعتمد مين اللي عملها استدعاء لكن في ال Arrow function ملهاش قيمة لذلك هي بتاخد قيمة الـ parent scope اللي تم تعريفها فيه كما في المثال السابع
//example 7
const a = {
a: "a",
arrFunc: () => {
console.log(this);
},
};
a.arrFunc(); // output=> Window {window: Window, self: Window, document: document, name: '', location: Location, …}
نلاقي قيمة this هي الـ parent scope وفي هذه الحالة هو الـ window object.
ملحوظة : ممكن تفكر إن {...}=const a لها ال scope الخاص بها ولكن هذا غير صحيح لأنه object literal وليس code block أي إنه مجرد طريقة لتعريف الـ object a لذلك ال parent scope لــ ()arrFunc هو الـ window
و لتوضيح المعلومة أكثر هنشوف المثال الثامن
example 8
const obj = {
a: "a",
method: function () {
const innerFunc = () => console.log(this);
innerFunc();
},
};
obj.method(); // output=>{a: 'a', method: ƒ
هنلاقي هنا this أخذت قيمتها من الـ parent scope اللي تم تعريفها فيه واللي في هذه الحالة هو ال method function لذلك قيمتها هتبقي ال obj اللي تم استدعاؤها فيه.
في الختام
استخدام This ككلمة مفتاحية أثناء كتابتنا للكود باستخدام JS لا غنى عنه ووضحنا في هذا المقال كل الطرق اللي نقدر نستخدمها بيها وقيمتها في كل حالة, إلى اللقاء في مقال قادم 👋
Discussion