در حال بارگذاری...

کلمهٔ this

یک تابعِ برچسب می‌تواند یک بار اسم لیوان را بگوید، بار بعد کالا را گم کند، و بار سوم اسم فنجان را نشان دهد. آکولادها سر جایشان مانده‌اند. چیزی که عوض شده، شکلِ صدا زدن است. JavaScript مقدار this را موقع صدا زدن انتخاب می‌کند، نه موقعی که تابع را تایپ می‌کنید.

بعد از فراخوانی سادهٔ متد

درس متدها تابع را روی آبجکت گذاشت و با product.tag() اجرا کرد. در آن شکل، this همان آبجکتِ قبل از نقطه بود. همان‌جا توقف کرد. اینجا تابع سر جایش می‌ماند و صدا زدن عوض می‌شود: از روی آبجکت برداشته می‌شود، با call به جای دیگری نشانه می‌رود، با bind قفل می‌شود، یا به‌صورت پیکان نوشته می‌شود.

پنج شکل که this را تعیین می‌کنند

📊 متد، جدا، call، bind، پیکان

شکل نمونه this کجا می‌نشیند
متد product.tag() آبجکتِ قبل از نقطه
جدا let show = product.tag; show() آن آبجکت نیست (undefined در حالت سخت‌گیرانه)
call product.tag.call(cup) آبجکتی که به call می‌دهید، فقط برای همین اجرا
bind product.tag.bind(product) روی همان آبجکت برای صدا زدن‌های بعدی قفل است
پیکان () => this.name داخل تابع دیگر this تابع بیرونی، نه آبجکتِ قبل از نقطه

قبل از خواندن this، شکل صدا زدن را نام ببرید. نشستن تابع روی آبجکت، this را منجمد نمی‌کند. خودِ صدا زدن تصمیم می‌گیرد. bind تصمیم را برای یک صدای بعدی از پیش می‌گیرد. پیکان صدا زدن را نادیده می‌گیرد و به تابعی نگاه می‌کند که دورش نوشته شده.

فراخوانی متد — this آبجکتِ قبل از نقطه است

javascript
"use strict";
let product = {
name: "Mug",
tag() {
return this.name;
}
};
console.log(product.tag());

نقطه هنوز اسم آبجکت را می‌گوید

product.tag() تابع tag را اجرا می‌کند و this را روی product می‌گذارد. کنسول Mug را چاپ می‌کند. این همان قاعدهٔ درس متدهاست و اینجا فقط برای مقایسه مانده. چهار صدای بعدی عمداً از همین قاعده جدا می‌شوند.

صدای جدا — آبجکت دیگر همراه نیست

javascript
"use strict";
let product = {
name: "Mug",
tag() {
if (this == null) {
return "missing";
}
return this.name;
}
};
let show = product.tag;
console.log(show());

تابع را که از آبجکت جدا کنید، لیوان با نقطه می‌رود

show و product.tag یک تابع‌اند. show() قبل از نقطه آبجکتی ندارد، پس در حالت سخت‌گیرانه this برابر undefined است. نگهبان missing را برمی‌گرداند. نگهبان را بردارید تا this.name خطا بدهد. این صفحه با حالت سخت‌گیرانه جلو می‌رود تا نتیجه قابل پیش‌بینی بماند. اسکریپتِ بدون این حالت می‌تواند صدای جدا را به آبجکت سراسری نشانه ببرد.

با call مقدار this را روی آبجکت دیگری بگذارید

javascript
"use strict";
let product = {
name: "Mug",
tag() {
return this.name;
}
};
let cup = { name: "Cup" };
console.log(product.tag.call(cup));

call تابع را برای یک آبجکت قرض می‌گیرد

product.tag.call(cup) هنوز tag لیوان را اجرا می‌کند، ولی this فقط برای همین اجرا cup است. کنسول Cup را چاپ می‌کند. product.name همان Mug می‌ماند. call تابع را روی cup کپی نمی‌کند. apply همین کار را می‌کند وقتی آرگومان‌های اضافه داخل آرایه باشند — این برچسب به آن‌ها نیاز ندارد.

قفل کردن آبجکت با bind

javascript
"use strict";
let product = {
name: "Mug",
tag() {
return this.name;
}
};
let show = product.tag.bind(product);
console.log(show());

bind آبجکت را برای صدای جدای بعدی نگه می‌دارد

bind تابع تازه‌ای برمی‌گرداند. داخل آن، this همان product می‌ماند حتی اگر show() نقطه نداشته باشد. کنسول Mug را چاپ می‌کند. خودِ tag اصلی دست نمی‌خورد. وقتی دکمه، تایمر، یا تابع دیگری قرار است متد را بدون آبجکتِ جلویش صدا بزند، از bind استفاده کنید.

پیکان this را از تابع بیرونی می‌گیرد

javascript
"use strict";
let shelf = {
name: "Shelf",
make() {
let product = {
name: "Mug",
tag: () => this.name
};
return product.tag();
}
};
console.log(shelf.make());

پیکان this را از نقطه نمی‌گیرد

product.tag() شکلِ فراخوانی متد را دارد، ولی tag پیکان است. پیکان this مخصوص خودش ندارد. this را از make می‌گیرد و make به‌صورت shelf.make() اجرا شده، پس this همان shelf است. کنسول Shelf را چاپ می‌کند، نه Mug. اگر روی product متد معمولی بود، Mug را می‌دیدید. پیکان در درس قبلی آمده بود؛ این صفحه فقط اثرش را روی this نشان می‌دهد.

صدا زدن را با کار جور کنید

آبجکت قبل از نقطه نشسته؟ this را همان آبجکت بخوانید. تابع را جدا کرده‌اید و bind نکرده‌اید؟ منتظر آن آبجکت نمانید. یک آبجکت دیگر، فقط برای یک اجرا؟ call را به کار ببرید. صدای بعدی بدون نقطه باید هنوز لیوان را ببیند؟ اول bind. پیکان نوشته‌اید؟ به تابعِ دوروبر نگاه کنید، نه به آبجکتِ قبل از نقطه. سازنده و کلاس هم this را تنظیم می‌کنند و برای صفحهٔ بعدی‌تر مانده‌اند. درس بعد JSON است: متنی که داده را توصیف می‌کند، نه قاعدهٔ تازه‌ای برای this.

برچسب قفل‌شده را روی صفحه بگذارید

tag را با bind به لیوان قفل کنید، بعد همان تابع تازه را بدون نقطه صدا بزنید. نتیجه را داخل یک پاراگراف بنویسید.

دموی صفحه — برچسب قفل‌شده

html
<!DOCTYPE html>
<html>
<head>
<title>this-keyword — page</title>
</head>
<body>
<p id="line">…</p>
<script>
"use strict";
let product = {
name: "Mug",
tag() {
return this.name;
}
};
let show = product.tag.bind(product);
let box = document.getElementById("line");
box.textContent = show();
</script>
</body>
</html>

پاراگراف Mug را نشان می‌دهد. show() قبل از نقطه آبجکتی ندارد، ولی خط هنوز اسم لیوان را می‌گوید چون bind مقدار this را قفل کرده. فقط product.name را عوض کنید، صفحه را تازه کنید، و پاراگراف دنبال همان اسم می‌رود. درس بعد: کار با JSON — متنی که داده را توصیف می‌کند، نه قانون تازه‌ای برای this.

گام‌های تمرین

  1. product.tag() را صدا بزنید و Mug را بخوانید.
  2. تابع را در show بگذارید، show() را در حالت سخت‌گیرانه صدا بزنید، و missing را بخوانید.
  3. product.tag.call(cup) را صدا بزنید و Cup را بخوانید.
  4. tag را به product قفل کنید، تابع تازه را بدون نقطه صدا بزنید، و Mug را بخوانید.
  5. shelf.make() را اجرا کنید و Shelf را بخوانید، نه Mug.
  6. در دموی HTML فقط product.name را عوض کنید، تازه کنید، و پاراگراف را بخوانید.

لغزش‌های رایج

  • خیال کنید چون تابع روی آبجکت نشسته، this منجمد است
  • show() را در حالت سخت‌گیرانه صدا بزنید و هنوز منتظر Mug بمانید
  • فکر کنید call تابع tag را روی cup کپی می‌کند
  • انتظار داشته باشید bind خودِ tag اصلی را بازنویسی کند، نه اینکه تابع تازه بدهد
  • پیکان را جای متد بگذارید و منتظر آبجکتِ قبل از نقطه بمانید
  • درس بعد را قاعدهٔ دیگری برای this حساب کنید — JSON قالب متنی برای داده است

جمع‌بندی

  • this را شکل صدا زدن انتخاب می‌کند، نه آکولادها
  • object.method() مقدار this را روی آبجکتِ قبل از نقطه می‌گذارد
  • صدای جدا در حالت سخت‌گیرانه this را به آن آبجکت نشانه نمی‌برد
  • call برای همان یک اجرا، this را روی آبجکتی می‌گذارد که داده‌اید
  • bind تابعی برمی‌گرداند که this در آن قفل مانده
  • پیکان this را از تابع دوروبرش می‌گیرد
  • صدای قفل‌شده می‌تواند یک خط از صفحه را پر کند
  • بعدی: کار با JSON، متنی که داده را توصیف می‌کند

🧠 دانش خود را بیازمایید

آماده شروع

دانش خود را بیازمایید

خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کرده‌اید

❓
8
سوالات
🎯
70%
برای قبولی
♾️
∞
زمان
🔄
∞
تلاش‌ها

📝 دستورالعمل‌ها

  • هر سوال را با دقت بخوانید
  • بهترین پاسخ را برای هر سوال انتخاب کنید
  • می‌توانید آزمون را هر چند بار که می‌خواهید تکرار کنید
  • پیشرفت شما در بالا نمایش داده می‌شود