this

This translation is incomplete. Please help translate this article from English

{{jsSidebar ("عوامل التشغيل")}}

A الدالة thisالكلمة تتصرف بشكل مختلف قليلا في جافا سكريبت بالمقارنة مع اللغات الأخرى. كما أن لديها بعض الاختلافات بين الوضع الصارم والوضع غير الصارم.

في معظم الحالات ، thisيتم تحديد القيمة من خلال كيفية استدعاء دالة (ربط وقت التشغيل). لا يمكن تعيينه عن طريق التعيين أثناء التنفيذ ، وقد يكون مختلفًا في كل مرة يتم استدعاء الوظيفة. قدم ES5 طريقة {{jsxref ("Function.prototype.bind ()"، "bind ()")}} إلى {{jsxref ('Operators / this'، ") تعيين قيمة الوظيفة thisبغض النظر عن كيفية تسميتها" قدم كل من "The_bind_method" و 1)}} و ES2015 دالات الأسهم التي لا توفر ربطًا خاصًا بها this(فهي تحتفظ thisبقيمة السياق المعجم المرفق).

{{EmbedInteractiveExample ("pages / js / expressions-this.html")}}

بناء الجملة

هذه

القيمة

خاصية سياق التنفيذ (عام ، أو وظيفة ، أو تقييم) التي ، في الوضع غير الصارم ، تكون دائمًا مرجعًا إلى كائن وفي الوضع الصارم يمكن أن تكون أي قيمة.

السياق العالمي

في سياق التنفيذ العام (خارج أي وظيفة) ، thisيشير إلى الكائن العام سواء في الوضع الصارم أم لا.

// في متصفحات الويب ، يكون كائن النافذة أيضًا هو الكائن العام:
console.log (هذه النافذة ===) ؛ // صحيح

أ = 37 ؛
console.log (window.a) ؛ // 37

this.b = "MDN" ؛
console.log (window.b) // "MDN"
console.log (ب) // "MDN"

ملاحظة: يمكنك دائمًا الحصول بسهولة على الكائن العام باستخدام خاصية {{jsxref ("globalThis")}} العمومية ، بغض النظر عن السياق الحالي الذي تعمل فيه التعليمات البرمجية الخاصة بك.

سياق الوظيفة

داخل الدالة ، thisتعتمد القيمة على كيفية استدعاء الوظيفة.

مكالمة بسيطة

نظرًا لأن الشفرة التالية ليست في وضع صارم ، ولأن القيمة thisلم يتم تعيينها بواسطة المكالمة ، thisفسيتم تعيينها افتراضيًا على الكائن العام ، وهو {{domxref ("Window"، "window")}} في المتصفح.

الدالة f1 () {
  أعد هذا ؛
}}

// في متصفح:
f1 () === نافذة ؛ // صحيح

// في العقدة:
f1 () === عام ؛ // صحيح

ومع ذلك ، في الوضع الصارم ، إذا thisلم يتم تعيين القيمة عند إدخال سياق التنفيذ ، فإنها تظل كما undefinedهو موضح في المثال التالي:

الدالة f2 () {
  "استخدام صارم" ؛ // انظر الوضع الصارم
  أعد هذا ؛
}}

f2 () === غير معرّف ؛ // صحيح
في المثال الثاني ، thisيجب أن يكون {{jsxref ("undefined")}} ، لأنه f2تم استدعاؤه مباشرةً وليس كطريقة أو خاصية لكائن (مثل window.f2()). لم يتم تنفيذ هذه الميزة في بعض المتصفحات عندما بدأوا في دعم الوضع الصارم لأول مرة . ونتيجة لذلك ، أعادوا windowالكائن بشكل غير صحيح .

لتعيين قيمة thisإلى قيمة معينة عند استدعاء دالة ، استخدم {{jsxref ("Function.prototype.call ()" أو "call ()")}} أو {{jsxref ("Function.prototype.apply ( ) "،" Apply () ")}} كما في الأمثلة التالية.

مثال 1

// يمكن تمرير كائن باعتباره الوسيطة الأولى للاتصال أو التطبيق وهذا سوف يرتبط به.
var obj = {a: 'Custom'} ؛

// تم تعيين هذه الخاصية على الكائن العام
var a = 'Global'؛

الدالة whatsThis () {
  أعد هذا. // تعتمد قيمة هذا على كيفية استدعاء الوظيفة
}}

ما هذا()؛ // "عالمي"
whatsThis.call (obj) ؛ // 'مخصص'
whatsThis.apply (obj) ؛ // 'مخصص'

مثال 2

إضافة دالة (ج ، د) {
  إرجاع هذا. a + this.b + c + d ؛
}}

var o = {a: 1، b: 3} ؛

// المعلمة الأولى هي الكائن المطلوب استخدامه كـ
// 'this' ، يتم تمرير المعلمات اللاحقة كـ 
// الوسيطات في استدعاء الوظيفة
add.call (س ، 5 ، 7) ؛ // 16

// المعلمة الأولى هي الكائن المطلوب استخدامه كـ
// 'this' ، والثاني عبارة عن مصفوفة
يتم استخدام // members كوسيطة في استدعاء دالة
add.apply (س ، [10 ، 20]) ؛ // 34

علما بأن في الوضع غير صارمة، مع callو apply، إذا كانت القيمة التي تم تمريرها كما thisليست كائن، سيتم إجراء محاولة لتحويله إلى كائن باستخدام الداخلية ToObjectالعملية. لذا ، إذا كانت القيمة التي تم تمريرها بدائية مثل 7أو 'foo'، سيتم تحويلها إلى كائن باستخدام المُنشئ ذي الصلة ، لذلك 7يتم تحويل الرقم البدائي إلى كائن كما لو كان بواسطة new Number(7)والسلسلة 'foo'إلى كائن كما لو كان new String('foo')، على سبيل المثال

شريط الوظائف () {
  console.log (Object.prototype.toString.call (this)) ؛
}}

bar.call (7) ؛ // [رقم الكائن]
bar.call ('foo') ؛ // [سلسلة الكائن]

على bindطريقة

قدم ECMAScript 5 {{jsxref ("Function.prototype.bind ()")}}}. f.bind(someObject)يؤدي الاستدعاء إلى إنشاء وظيفة جديدة بنفس الجسم والنطاق f، ولكن thisفي حالة حدوثها في الوظيفة الأصلية ، في الوظيفة الجديدة ، يتم ربطها بشكل دائم بالحجة الأولى bind، بغض النظر عن كيفية استخدام الوظيفة.

دالة f () {
  أعد هذا.
}}

var g = f.bind ({a: 'azerty'}) ؛
console.log (g ()) ؛ // azerty

var h = g.bind ({a: 'yoo'}) ؛ // bind يعمل مرة واحدة فقط!
console.log (h ()) ؛ // azerty

var o = {a: 37، f: f، g: g، h: h} ؛
console.log (oa، of ()، og ()، oh ())؛ // 37،37، azerty، azerty

وظائف السهم

في دوال السهم ، thisيحتفظ بقيمة السياق المعجم المتضمن this. في الكود العام ، سيتم تعيينه على الكائن العام:

var globalObject = هذا ؛
var foo = (() => this) ؛
console.log (foo () === globalObject) ؛ // صحيح

ملاحظة: إذا thisتم تمرير الوسيطة إلى call، bindأو applyعند استدعاء وظيفة السهم ، فسيتم تجاهلها. لا يزال بإمكانك إضافة وسيطات إلى المكالمة ، ولكن thisArgيجب ضبط الوسيطة الأولى ( ) على null.

// Call كطريقة لكائن
var obj = {func: foo} ؛
console.log (obj.func () === globalObject) ؛ // صحيح

// محاولة تعيين هذا باستخدام المكالمة
console.log (foo.call (obj) === globalObject) ؛ // صحيح

// جرت محاولة ضبط ذلك باستخدام الربط
foo = foo.bind (obj) ؛
console.log (foo () === globalObject) ؛ // صحيح

مهما كانت، fooالصورة thisيتم تعيين إلى ما كانت عليه عندما تم إنشاؤه (في المثال أعلاه، الكائن العالمي). وينطبق الشيء نفسه على دالات الأسهم التي تم إنشاؤها داخل دوال أخرى: thisبقايا تلك السياق المعجمية المرفقة.

// إنشاء كائن بشريط أسلوب يقوم بإرجاع دالة
// يعيد هذا. يتم إنشاء الدالة التي تم إرجاعها كـ
// دالة سهم ، لذا فهي مرتبطة بشكل دائم بـ
// هذه الدالة المرفقة. يمكن تعيين قيمة الشريط
// في المكالمة ، والتي تحدد بدورها قيمة 
// عادت الدالة.
var obj = {
  شريط: الوظيفة () {
    var x = (() => this) ؛
    العودة س ؛
  }}
} ؛

// Call bar كطريقة للهدف ، وضبط هذا الأمر على obj
// تعيين مرجع للدالة التي تم إرجاعها إلى fn
var fn = obj.bar () ،

// Call fn دون تعيين هذا ، سيكون الوضع الافتراضي عادةً
// إلى الكائن العام أو غير محدد في الوضع الصارم
console.log (fn () === obj) ؛ // صحيح

// لكن احذر إذا رجعت إلى طريقة الكائن بدون تسميتها
var fn2 = obj.bar ،
// استدعاء وظيفة السهم هذا من داخل طريقة الشريط ()
// سيعود الآن النافذة ، لأنه يتبع هذا من fn2.
console.log (fn2 () () == window) ؛ // صحيح

في أعلاه ، تم تعيين الوظيفة (يطلق عليها الوظيفة المجهولة أ) obj.barلإرجاع وظيفة أخرى (يطلق عليها الوظيفة المجهولة ب) التي تم إنشاؤها كدالة سهم. ونتيجة لذلك، وظيفة B في thisتعيين دائم لل thisمن obj.bar(وظيفة A) عندما دعا. عندما يتم استدعاء الدالة التي تم إرجاعها (الوظيفة B) ، thisستكون دائمًا ما تم تعيينها عليه في البداية. في المثال رمز أعلاه، وظيفة باء thisمن المقرر أن وظيفة A و thisالذي هو obj، لذلك لا يزال المقرر أن objحتى عندما دعا بطريقة من شأنها أن تحدد عادة في thisل undefinedأو الكائن العالمي (أو أي طريقة أخرى كما في المثال السابق في عالمي سياق التنفيذ).

كطريقة كائن

عندما يتم استدعاء دالة كطريقة لكائن ما ، thisيتم تعيينها على الكائن الذي يتم استدعاء الطريقة.

في المثال التالي ، عندما o.f()يتم استدعاء ، داخل الوظيفة thisمنضمة إلى oالكائن.

var o = {
  الدعامة: 37 ،
  و: الوظيفة () {
    أعد هذا. prop؛
  }}
} ؛

console.log (من ()) ؛ // 37

لاحظ أن هذا السلوك لا يتأثر على الإطلاق بكيفية أو مكان تعريف الوظيفة. في المثال السابق ، قمنا بتعريف الوظيفة المضمنة fكعضو أثناء تعريف o. ومع ذلك ، كان بإمكاننا تحديد الوظيفة بسهولة ثم إرفاقها بها لاحقًا o.f. يؤدي القيام بذلك إلى نفس السلوك:

var o = {prop: 37} ؛

وظيفة مستقلة () {
  أعد هذا. prop؛
}}

of = مستقل ؛

console.log (من ()) ؛ // 37

يوضح هذا أنه من المهم فقط أن يتم استدعاء الوظيفة من fعضو o.

وبالمثل ، thisلا يتأثر الربط إلا بمرجع العضو المباشر. في المثال التالي ، عندما نستدعي الوظيفة ، نسميها كطريقة gللكائن o.b. هذه المرة أثناء التنفيذ ، thisسيتم الرجوع إلى داخل الوظيفة o.b. حقيقة أن الكائن هو نفسه عضو oليس له أي عواقب ؛ المرجع الأكثر فورية هو كل ما يهم.

ob = {g: Independent، prop: 42} ؛
console.log (obg ()) ؛ // 42

this في سلسلة النموذج الأولي للكائن

ينطبق نفس المفهوم على الأساليب المحددة في مكان ما على سلسلة النموذج الأولي للكائن. إذا كانت الطريقة موجودة في سلسلة نموذجية للكائن ، thisفيشير إلى الكائن الذي تم استدعاء الطريقة ، كما لو كانت الطريقة موجودة على الكائن.

var o = {f: function () {return this.a + this.b؛ }} ؛
var p = Object.create (o) ؛
السلطة الفلسطينية = 1 ؛
pb = 4 ؛

console.log (pf ()) ؛ // 5

في هذا المثال ، الكائن الذي تم تعيينه للمتغير pليس له fخاصية خاصة به ، بل يرثه من النموذج الأولي الخاص به. ولكن لا يهم أن fيجد البحث في النهاية عضوًا يحمل هذا الاسم o؛ بدأ البحث كمرجع إلى p.f، لذا thisداخل الوظيفة تأخذ قيمة الكائن المشار إليه باسم p. هذا ، حيث fيطلق عليه أسلوبًا p، thisيشير إليه p. هذه ميزة مثيرة للاهتمام في وراثة النموذج الأولي لجافا سكريبت.

this مع مُدرب أو مُدرب

مرة أخرى ، نفس الفكرة صحيحة عندما يتم استدعاء دالة من getter أو setter. this ترتبط الوظيفة المستخدمة كجلب أو أداة ضبط بالكائن الذي يتم تعيين الخاصية أو الحصول عليها منه.

الدالة () {
  إرجاع this.a + this.b + this.c ؛
}}

var o = {
  أ: 1 ،
  ب: 2 ،
  ج: 3 ،
  الحصول على المتوسط ​​() {
    العودة (this.a + this.b + this.c) / 3 ؛
  }}
} ؛

Object.defineProperty (o، 'sum'، {
    get: sum، enumerable: true، configurable: true})؛

console.log (o. avage، o.sum) ؛ // 2 ، 6

كمنشئ

عند استخدام دالة كمنشئ (باستخدام الكلمة الرئيسية {{jsxref ("Operators / new"، "new")}}) ، thisفإنها مرتبطة بالعنصر الجديد الذي يتم إنشاؤه.

على الرغم من أن الإعداد الافتراضي للمنشئ هو إرجاع الكائن المشار إليه this، فإنه يمكنه بدلاً من ذلك إرجاع كائن آخر (إذا لم تكن القيمة المرجعة كائنًا ، فسيتم thisإرجاع الكائن).

/ *
 * يعمل المنشئ على النحو التالي:
 *
 * وظيفة MyConstructor () {
 * // كود الجسم للوظيفة الفعلية يظهر هنا.  
 * // إنشاء خصائص على | هذا | مثل
 * // مرغوب من خلال التنازل عنها. على سبيل المثال ،
 * this.fum = "nom" ؛
 * // إلى آخره...
 *
 * // إذا كانت الوظيفة تحتوي على بيان إرجاع ذلك
 * // يقوم بإرجاع كائن ، سيكون هذا الكائن هو
 * // نتيجة | جديد | التعبير. غير ذلك،
 * // نتيجة التعبير هي الكائن
 * // مرتبط حاليًا بـ | this |
 * // (أي الحالة الشائعة التي تُرى عادةً).
 *}
 * /

الدالة C () {
  this.a = 37 ؛
}}

var o = new C () ،
Console.log (oa) ؛ // 37


الدالة C2 () {
  this.a = 37 ؛
  العودة {أ: 38} ؛
}}

o = C2 () جديد ؛
Console.log (oa) ؛ // 38

في المثال الأخير ( C2) ، لأنه تم إرجاع كائن أثناء البناء ، thisيتم التخلص من الكائن الجديد الذي كان مرتبطًا به ببساطة. (هذا يجعل العبارة " this.a = 37;" رمزًا ميتًا بشكل أساسي . ليس ميتًا تمامًا لأنه يتم تنفيذه ، ولكن يمكن إزالته بدون أي تأثيرات خارجية.)

كمعالج حدث DOM

عند استخدام دالة كمعالج للأحداث ، thisيتم تعيينها على العنصر الذي يتم وضع المستمع عليه (بعض المتصفحات لا تتبع هذا الاصطلاح للمستمعين المضافين ديناميكيًا بأساليب أخرى غير {{domxref ("EventTarget / addEventListener"، "addEventListener" () ")}}).

// عند الاتصال كمستمع ، يحول العنصر ذي الصلة إلى اللون الأزرق
دالة bluify (e) {
  // دائما صحيح او صادق
  console.log (هذا === e.currentTarget) ؛
  // true عندما يكون currentTarget والهدف هما نفس الكائن
  console.log (هذا === e.target) ؛
  this.style.backgroundColor = '# A5D9F3' ؛
}}

// احصل على قائمة بكل عنصر في المستند
var Elements = document.getElementsByTagName ('*') ؛

// أضف bluify كمستمع فوق حتى عندما
تم النقر على عنصر // ، ويتحول إلى اللون الأزرق
for (var i = 0؛ i <element.length؛ i ++) {
  العناصر [i] .addEventListener ('click'، bluify، false) ؛
}}

في معالج حدث مضمن

عندما يتم استدعاء الرمز من معالج مضمّن في الحدث ، thisيتم تعيينه على عنصر DOM الذي يتم وضع المستمع عليه:

<button onclick = "alert (this.tagName.toLowerCase ())؛">
  تظهر هذه
</button>

يظهر التنبيه أعلاه button. لاحظ أن الكود الخارجي فقط هو الذي تم thisضبطه بهذه الطريقة:

<button onclick = "alert ((function () {return this؛}) ())؛">
  أظهر هذا الداخلية
</button>

في هذه الحالة ، thisلم يتم تعيين الوظيفة الداخلية ، لذا فإنها تُرجع الكائن العام / النافذة (أي الكائن الافتراضي في الوضع غير الصارم حيث thisلا يتم تعيينه بواسطة المكالمة).

مواصفات

تخصيص
{{SpecName ('ESDraft'، '# sec-this-keyword'، 'The this keyword')}}

التوافق المتصفح

{{Compat ("javascript.operators.this")}}

أنظر أيضا