کلمه کلیدی this
به مقدار شیئی اشاره دارد که در زمان فراخوانی تابع به تابع متصل است، به این معنی که مقدار آن بسته به اینکه یک تابع به عنوان یک متد، یک تابع مستقل یا به عنوان سازنده فراخوانی شود، متفاوت است.
هنگامی که یک تابع فراخوانی می شود، نمونه ای از کلمه کلیدی this
در پشت صحنه به عنوان ارجاع به شی حاوی آن تابع ایجاد می کند و به ویژگی ها و روش های تعریف شده در کنار آن از محدوده خود دسترسی می دهد. کار با this
از جهاتی شبیه کار با متغیری است که با const
اعلام شده است. مانند یک ثابت، نمیتوان this
حذف کرد و مقدار آن را نمیتوان دوباره اختصاص داد، اما روشها و ویژگیهای شیء موجود در this
کلمه کلیدی را میتوان تغییر داد.
الزام آور جهانی
در خارج از یک تابع یا زمینه یک شی، this
به ویژگی globalThis
اشاره دارد که در اکثر محیط های جاوا اسکریپت به شی جهانی اشاره می کند. در زمینه یک اسکریپت در حال اجرا در یک مرورگر وب، شی سراسری شی 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
اشاره می کند، پس از اینکه تابع arrow را تعریف کردید، this
در داخل تابع arrow نیز به myObject
اشاره می کند:
let myObject = {
myMethod() { console.log( this ); },
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myEnclosingMethod();
myObject.myArrowFunction();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
الزام آور صریح
Binding ضمنی اکثر موارد استفاده را برای کار با this
کنترل می کند. با این حال، ممکن است گاهی اوقات به ارزش this
برای نشان دادن یک زمینه اجرایی خاص ، به جای زمینه فرضی نیاز داشته باشید. یک مثال گویا، اگر کمی قدیمی باشد، با this
در تابع callback یک setTimeout
کار می کند، زیرا این callback زمینه اجرای منحصر به فرد دارد:
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
myObject.myMethod();
> "This is my string."
setTimeout( myObject.myMethod, 100 );
> undefined
this
این کاستی خاص setTimeout
از آن زمان توسط ویژگی های دیگر برطرف شده است، مسائل مشابه مربوط به "از دست دادن" قبلاً با ایجاد یک اشاره صریح به ارزش 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
هنگامی که یک کلاس به عنوان سازنده با استفاده از کلمه کلیدی 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()
برای ارجاع به تابع callback شنونده رویداد استفاده می کنید، 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