تشير الكلمة الرئيسية this
إلى قيمة الكائن المرتبط بالدالة في وقت استدعائها، ما يعني أن قيمتها تختلف بناءً على ما إذا كان يتم استدعاء الدالة كطريقة أو كدالة مستقلة أو دالة إنشائية.
عند استدعاء دالة، يتم إنشاء مثيل للكلمة الرئيسية this
في الخلفية كمرجع للعنصر الذي يحتوي على هذه الدالة، ما يتيح الوصول إلى الخصائص والطرق المحددة إلى جانبها ضمن نطاقها.
يشبه استخدام this
في بعض النواحي العمل مع متغيّر تم تعريفه باستخدام const
. لا يمكن إزالة this
، تمامًا مثل الثابت، ولا يمكن إعادة تحديد قيمته، لكن يمكن تغيير طرق وخصائص العنصر الذي تحتوي عليه الكلمة الرئيسية this
.
الربط العالمي
خارج دالة أو سياق كائن، تشير السمة this
إلى السمة globalThis
، وهي مرجع إلى الكائن العمومي في معظم بيئات JavaScript. في سياق نص برمجي يتم تشغيله في متصفح ويب، يكون الكائن العمومي هو window
:
this;
> Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, ...}
في Node.js، يكون globalThis
هو كائن global
:
$ node
Welcome to Node.js v20.10.0.
Type ".help" for more information.
> this
<ref *1> Object [global] {
...
}
خارج الوضع المتشدد، تشير this
أيضًا إلى الكائن العمومي داخل دالة مستقلة، لأن العنصر الرئيسي Window
هو الكائن الذي "يمتلك" تلك الدوال بشكل فعّال.
function myFunction() {
console.log( this );
}
myFunction();
> Window {...}
(function() {
console.log( this );
}());
> Window {...}
عند استخدام الوضع المتشدد، تكون قيمة this
هي undefined
داخل دالة مستقلة:
(function() {
"use strict";
console.log( this );
}());
> undefined
قبل طرح الوضع المتشدد، سيتم استبدال القيمة null
أو undefined
الخاصة بـ this
بإشارة إلى الكائن العمومي. قد ترى أحيانًا أنّ عملية الربط العالمي يُشار إليها باسم "الربط التلقائي" بسبب هذا السلوك القديم.
الربط الضمني
عند استدعاء دالة كطريقة لكائن، يشير مثيل this
ضمن هذه الطريقة إلى الكائن الذي يحتوي على الطريقة، ما يمنح إمكانية الوصول إلى الطرق والخصائص التي توجد بجانبها:
let myObject = {
myValue: "This is my string.",
myMethod() {
console.log( this.myValue );
}
};
myObject.myMethod();
> "This is my string."
قد يبدو أنّ قيمة this
تعتمد على كيفية تعريف الدالة وكائن تضمينها. بدلاً من ذلك، يكون سياق قيمة this
هو
سياق التنفيذ الحالي. في هذه الحالة، سياق التنفيذ هو أنّ الكائن myObject
يستدعي طريقة myMethod
، وبالتالي أنّ myObject
هي قيمة this
. قد يبدو لك أنّ هذه السمة تقنية في سياق الأمثلة السابقة، ولكن بالنسبة إلى الاستخدامات الأكثر تقدّمًا للسمة this
، إنّها نقطة فارقة أساسية يجب أخذها في الاعتبار.
بشكل عام، يمكنك استخدام this
بطرق لا تتوقع أن يكون الرمز البرمجي المحيط بها
أي بنية معيّنة. ويُستثنى من هذه القاعدة دوال الأسهم في ES5.
this
في الدوال السهمية
في دوال الأسهم،
تتحوّل السمة this
إلى ارتباط في
بيئة تضمين أسلوب تضمين. وهذا يعني أنّ
this
في الدالة السهمية يشير إلى قيمة this
في أقرب سياق تضمين لهذه الدالة:
let myObject = {
myMethod() { console.log( this ); },
myArrowFunction: () => console.log( this ),
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myMethod();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
myObject.myArrowFunction();
> Window {...}
في المثال السابق، يسجّل myObject.myMethod()
myObject
باعتباره الكائن الذي "يملك" هذه الطريقة، ولكن myObject.myArrowFunction()
تعرض globalThis
(أو undefined
)، لأن مثيل this
داخل دالة السهم يشير بدلاً من ذلك إلى أعلى نطاق تضمين.
في المثال التالي، تنشئ myEnclosingMethod
دالة سهم على
الكائن الذي يحتوي عليها عند تنفيذها. يشير مثيل this
داخل دالة السهم الآن إلى قيمة this
في بيئة التغليف، وهي الطريقة التي تحتوي على دالة السهم هذه. بما أنّ قيمة this
داخل myEnclosingMethod
تشير إلى myObject
، بعد تعريف دالة السهم، يشير this
داخل دالة السهم أيضًا إلى myObject
:
let myObject = {
myMethod() { console.log( this ); },
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myEnclosingMethod();
myObject.myArrowFunction();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
ربط صريح
تتعامل عملية الربط الضمني مع معظم حالات الاستخدام عند استخدام "this
". ومع ذلك، قد تحتاج أحيانًا إلى قيمة this
لتمثيل سياق تنفيذ محدّد، بدلاً من السياق المفترض. مثال توضيحي، إذا كان قديمًا بعض الشيء،
يعمل مع this
ضمن وظيفة معاودة الاتصال في setTimeout
،
لأن لمعاودة الاتصال هذه سياق تنفيذ فريد:
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
myObject.myMethod();
> "This is my string."
setTimeout( myObject.myMethod, 100 );
> undefined
على الرغم من أنّه تم حلّ هذا القصور المحدّد في setTimeout
من خلال ميزات أخرى، تم سابقًا حلّ المشاكل المشابهة المتعلقة بـ "فقدان" السمة this
، وذلك من خلال إنشاء إشارة واضحة إلى قيمة السمة this
ضمن نطاق السياق المقصود. قد تظهر لك أحيانًا أمثلة this
يتم تعيينها إلى متغيّر باستخدام معرّفات مثل that
أو self
أو _this
في قواعد الرموز القديمة. هذه هي اصطلاحات المعرّفات الشائعة للمتغيّرات التي تحتوي على قيمة this
تم تجاوزها.
عند استدعاء دالة باستخدام الطرق call()
أو bind()
أو apply()
،
يشير this
بشكل صريح إلى الكائن الذي يتم استدعاؤه:
let myFunction = function() {
console.log( this.myValue );
}
let myObject = {
"myValue" : "This is my string."
};
myFunction.call( myObject );
> "This is my string."
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
setTimeout( myObject.myMethod.bind( myObject ), 100 );
> "This is my string."
تلغي الربط الصريح قيمة this
التي توفرها الربط الضمني.
let myObject = {
"myValue" : "This string sits alongside myMethod.",
myMethod() {
console.log( this.myValue );
}
};
let myOtherObject = {
"myValue" : "This is a string in another object entirely.",
};
myObject.myMethod.call( myOtherObject );
> "This is a string in another object entirely."
إذا تم استدعاء دالة بطريقة تضبط قيمة this
على undefined
أو null
، يتم استبدال هذه القيمة بـ globalThis
خارج الوضع المتشدد:
let myFunction = function() {
console.log( this );
}
myFunction.call( null );
> Window {...}
وبالمثل، إذا تم استدعاء دالة بطريقة قد تعطي this
قيمة أولية، يتم استبدال هذه القيمة بكائن برنامج تضمين القيمة الأولية
خارج الوضع المتشدد:
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> Number { 10 }
في الوضع المتشدد، لا يتم فرض ظهور قيمة this
التي تم تمريرها على كائن بأي شكل من الأشكال، حتى ولو كانت قيمة أساسية أو قيمة null
أو undefined
:
"use strict";
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> 10
myFunction.call( null );
> null
ربط new
عند استخدام class كدالة إنشائية باستخدام الكلمة الرئيسية new
، تشير this
إلى المثيل الذي تم إنشاؤه حديثًا:
class MyClass {
myString;
constructor() {
this.myString = "My string.";
}
logThis() {
console.log( this );
}
}
const thisClass = new MyClass();
thisClass.logThis();
> Object { myString: "My string." }
وبالمثل، تشير قيمة this
داخل دالة إنشائية تسمى استخدام new
إلى الكائن الذي يتم إنشاؤه:
function MyFunction() {
this.myString = "My string.";
this.logThis = function() {
console.log( this );
}
}
const myObject = new MyFunction();
myObject.logThis();
> Object { myString: "My string.", logThis: logThis() }
ربط معالج الأحداث
في سياق معالِجات الأحداث، تشير قيمة this
إلى العنصر الذي يستدعيها. داخل دالة معاودة الاتصال في معالج الأحداث، يعني هذا أن this
يشير إلى العنصر المرتبط بالمعالج:
let button = document.querySelector( "button" );
button.addEventListener( "click", function( event ) { console.log( this ); } );
عندما يتفاعل مستخدم مع button
في المقتطف السابق، تكون النتيجة
هي كائن العنصر الذي يحتوي على <button>
نفسه:
> Button {}
عند استخدام دالة سهم كاستدعاء أداة معالجة الحدث، يتم توفير قيمة
this
مرة أخرى من خلال أقرب سياق تنفيذ تضمين. وهذا يعني في أعلى مستوى أنّ this
داخل دالة معاودة الاتصال في معالج الأحداث هو globalThis
(أو undefined
في الوضع المتشدد):
let button = document.querySelector( "button" );
button.addEventListener( "click", ( event ) => { console.log( this ); } );
> undefined
كما هو الحال مع أي كائن آخر، عند استخدام الطرق call()
أو bind()
أو apply()
للإشارة إلى وظيفة معاودة الاتصال لأداة معالجة الحدث، تشير this
إلى الكائن صراحةً:
let button = document.querySelector( "button" );
let myObject = {
"myValue" : true
};
function handleClick() {
console.log( this );
}
button.addEventListener( "click", handleClick.bind( myObject ) );
> Object { myValue: true }
التحقق من فهمك
بالنسبة إلى نص برمجي يتم تشغيله في متصفح ويب، ما هو الكائن العام
الذي يشير إليه this
عند استخدامه خارج دالة أو سياق
كائن؟
window
browser
undefined