تماس با ما

this، call، apply، bind

this یعنی «شیئی که الان تابع روش صدا زده شده». مقدارش موقع فراخوانی تعیین می‌شه (به‌جز arrow function).

this یعنی «شیئی که الان تابع روش صدا زده شده». مقدارش موقع فراخوانی تعیین می‌شه (به‌جز arrow function).

قواعد تعیین this

۱. فراخوانی ساده

function show() { return this; }
show();   // حالت عادی: globalThis (window/global)
          // در "use strict": undefined

۲. فراخوانی به‌عنوان متد

this = آبجکت سمت چپ نقطه:

const user = {
  name: "Ali",
  hi() { return `سلام ${this.name}`; },
};
user.hi(); // → "سلام Ali"

۳. گم شدن this

const f = user.hi;
f();   // this = undefined/global → "سلام undefined" (یا خطا)

setTimeout(user.hi, 0);   // همین مشکل
[1].forEach(user.hi);      // همین مشکل

۴. سازنده (new)

function Person(name) {
  this.name = name;   // this = آبجکت جدید
}
new Person("Sara").name; // → "Sara"

۵. صریح: call/apply/bind

(پایین‌تر)

۶. Arrow function

this رو از scope بیرونی (lexical) می‌گیره و هیچ‌وقت عوض نمی‌شه:

const timer = {
  seconds: 0,
  start() {
    setInterval(() => {
      this.seconds++;          // this = timer ✅
    }, 1000);
  },
};

با تابع معمولی داخل setInterval، this درست نبود.

arrow function رو به‌عنوان متد object ننویس:

const bad = {
  name: "x",
  hi: () => this.name,   // this = بیرون object (undefined یا global)
};

۷. Event handler (DOM)

button.addEventListener("click", function () {
  this;                    // → خود button
});
button.addEventListener("click", (e) => {
  e.currentTarget;         // → button (در arrow از این استفاده کن)
});

۸. class

class Btn {
  label = "OK";
  handle = () => console.log(this.label);   // arrow field: this ثابته
  other() { console.log(this.label); }       // اگه جدا بشه this گم می‌شه
}

call

فراخوانی فوری با this دلخواه و آرگومان‌های جدا:

function intro(greet, punct) {
  return `${greet}, ${this.name}${punct}`;
}
const p = { name: "Ali" };
intro.call(p, "سلام", "!");   // → "سلام, Ali!"

apply

مثل call ولی آرگومان‌ها در آرایه:

intro.apply(p, ["سلام", "!"]);   // → "سلام, Ali!"
Math.max.apply(null, [1, 5, 3]); // → 5  (امروز: Math.max(...arr))

حافظه: Apply = Array.

bind

تابع جدید با this ثابت برمی‌گردونه (فوری اجرا نمی‌کنه):

const boundIntro = intro.bind(p, "سلام");
boundIntro("؟");   // → "سلام, Ali؟"

Partial application

function mul(a, b) { return a * b; }
const double = mul.bind(null, 2);
double(5); // → 10

حل مشکل گم شدن this

const safe = user.hi.bind(user);
setTimeout(safe, 0);   // ✅
  • bind شده را نمی‌شه دوباره bind کرد (اولی می‌مونه).
  • bound.name → "bound hi".

قرض گرفتن متد (Method Borrowing)

function sumArgs() {
  return Array.prototype.reduce.call(arguments, (a, b) => a + b, 0);
}
sumArgs(1, 2, 3); // → 6

Array.prototype.map.call("abc", (c) => c.toUpperCase()); // → ["A","B","C"]

globalThis و strict mode

"use strict";
function f() { return this; }
f(); // → undefined (نه window)

ماژول‌های ES و class ها همیشه strict هستن.

جدول خلاصه

روش فراخوانیمقدار this
fn()undefined (strict) / global
obj.fn()obj
new Fn()آبجکت تازه‌ساخته
fn.call(x) / apply(x) / bind(x)x
arrow functionthis بیرونی
event handler (تابع معمولی)عنصر DOM

تمرین

  1. بدون اجرا پیش‌بینی کن خروجی چیه:
const o = {
  n: 1,
  a() { return this.n; },
  b: () => typeof this,
  c() { return [1].map(() => this.n); },
};
console.log(o.a(), o.b(), o.c());
// → 1 "object" [ 1 ]
// (در Node با CommonJS. در ماژول ESM مقدار this سطح بالا undefined است و b() مقدار "undefined" برمی‌گردونه.)
  1. تابع myBind(fn, ctx) بنویس که رفتار bind رو پیاده کنه:
const myBind = (fn, ctx, ...pre) => (...args) => fn.apply(ctx, [...pre, ...args]);

ایده‌ای دارید؟ برایمان بگویید

مشاوره و پیشنهاد اولیه رایگان است.

تماس با ما