WTF در جاوا اسکریپت “این” است

ارزش this
تعیین می شود که چگونه یک عملکرد نامیده می شود ، نه در جایی که تعریف شده است. این همان چیزی است که مشخصات ECMAScript آن را “اتصال زمان” می نامد. به آن فکر کنید مانند یک بازی سیب زمینی داغ هرکسی که سیب زمینی را نگه می دارد (فراخوانی عملکرد) چه چیزی را تعیین می کند this
می شود
در اینجا یک مثال پیچیده است که اغلب توسعه دهندگان ایالات متحده را گیج می کند.
const user = {
name: "John",
greet() {
const sayHi = () => {
console.log(`Hi, ${this.name}!`);
};
setTimeout(sayHi, 1000);
},
};
user.greet(); // After 1 second: "Hi, John!"
در این حالت ، عملکرد فلش sayHi
تله this
از دامنه اطراف آن اگر به جای آن از یک عملکرد معمولی استفاده کرده بودیم ، this
می توانست یک شیء جهانی (یا در حالت سخت تعریف نشده) ، و this.name
تعریف نشده بود ایه چیز دیگری که باید هنگام استفاده به دنبال آن باشید this
، به JS خوش آمدید!
توابع فلش و “این”
توابع فلش خاص است. برخلاف کارکردهای منظم ، آنها خودشان را ندارند this
بشر در عوض ، آنها به ارث می برند this
از دامنه والدین آنها. مثل این است که آنها می گویند “هر آنچه this
به معنای جایی است که من ایجاد شده ام ، این همان چیزی است که من استفاده خواهم کرد. “
در اینجا چیزی است که ممکن است شما را غافلگیر کند.
const obj = {
value: 42,
getValue: () => {
console.log(this.value);
},
};
obj.getValue(); // undefined
حتی getValue
روشی است obj
، عملکرد فلش دریافت نمی کند this
از شی در عوض ، آن را به ارث می برد this
از جایی که عملکرد فلش ایجاد شده است (احتمالاً دامنه جهانی یا دامنه ماژول) ، Againg به JS خوش آمدید!
مشخصات می گوید …
با توجه به مشخصات ECMAScript ، هنگامی که یک تابع نامیده می شود ، زمینه اعدام ایجاد می شود. این زمینه شامل یک است ThisBinding
مؤلفه ای که تعیین می کند چه چیزی this
در داخل عملکرد خواهد بود قوانین تنظیم ThisBinding
کاملاً خاص هستند:
- برای توابع سازنده (نامیده می شود
new
)this
آیا شیء تازه ایجاد شده است - برای روش ها ،
this
شیء است که صاحب روش است - برای توابع فلش ،
this
از دامنه محصور به ارث رسیده است - برای تماس های عملکرد ساده ،
this
یا شیء جهانی است یا تعریف نشده (در حالت سخت)
درک این قوانین به شما کمک می کند تا پیش بینی کنید this
در هر شرایطی خواهد بود
یک مثال دنیای واقعی … فکر می کنم
در اینجا الگویی است که ممکن است در کد واقعی مشاهده کنید:
class EventEmitter {
constructor() {
this.events = {};
// Using an arrow function to preserve 'this'
this.emit = (event, ...args) => {
const handlers = this.events[event] || [];
handlers.forEach((handler) => handler.apply(this, args));
};
}
on(event, handler) {
this.events[event] = this.events[event] || [];
this.events[event].push(handler);
}
}
const emitter = new EventEmitter();
emitter.on("test", function () {
console.log(this === emitter); // true
});
emitter.emit("test");
در این مثال ، ما از هر دو توابع فلش و کارکردهای منظم به صورت استراتژیک استفاده می کنیم. عملکرد فلش برای emit
تضمین کردن this
همیشه به نمونه EventEmitter اشاره دارد ، در حالی که عملکرد کنترل کننده آن را بدست می آورد this
از طریق امیتر apply
بشر
به یاد داشته باشید ، this
جادویی نیست بلکه فقط پارامتر است که JavaScript به روشی خاص به عملکردهای خود منتقل می شود.