این کلمه کلیدی

کلمه کلیدی 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

اگرچه این کاستی خاص 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

هنگامی که یک کلاس به عنوان سازنده با استفاده از کلمه کلیدی 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