تشير الكلمة الرئيسية 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
عند استخدامها خارج الدالة أو
سياق الكائن؟
browser
undefined
window