برنامه نویسی

رمزگشایی کلمه کلیدی «این» در جاوا اسکریپت

سردرگمی زیادی در اطراف وجود دارد this کلمه کلیدی در جاوا اسکریپت راه this شرح داده شده در اسناد وب رسمی MDN بسیار بصری نیست. اگر شما هم چنین احساسی دارید، بیایید در مورد آن بیاموزیم this کلمه کلیدی با استفاده از چند مثال عملی

چیست this ?

را this کلمه کلیدی به زمینه ای اشاره دارد که یک قطعه کد باید در آن اجرا شود. اگر موارد زیر را در مرورگر خود وارد کنسول کنیم چه چیزی به دست می آید؟

console.log(this)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نتیجه اجرای کد بالا کل مرورگر است Window هدف – شی. اگر به جای آن آن را در Node اجرا کنید، آن را دریافت خواهید کرد جهانی است هدف – شی. از این رو، this نشان دهنده زمینه جایی است که کد تعریف شده است.

بیایید نگاهی به یک مثال بیندازیم. در زیر یک شی به نام داریم student و در داخل شی تابعی به نام تعریف خواهیم کرد testFunction.

const student = {
  name: "Jon",
  phone: 415887231,

  testFunction: function () {
    console.log(this);
  },
};
student.testFunction();
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خروجی:


{
    name: "Jon"
    phone: 415887231
    testFunction: ƒ testFunction()
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما در حال ورود به سیستم کنسول هستیم this از داخل testFunction. از آنجا که testFunction در داخل تعریف شده است student شی ما کل را دریافت می کنیم student شی به عنوان خروجی را student شیء زمینه ای است که تابع در آن تعریف می شود.

this و strict حالت در Node

هنگامی که از حالت سخت در Node استفاده می کنید، رفتار از this متفاوت است. مثال زیر این رفتار را نشان می دهد.

'use strict';

// Top level
console.log(this);  // {}

function strictFunction() {
    console.log(this);  // undefined
}

strictFunction();
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در سطح بالا در یک ماژول this هنوز است شی جهانی. با این حال، در داخل یک تابع this اکنون است تعریف نشده.

چرا این می تواند مفید باشد؟ موارد استفاده زیادی از strict حالت در ادامه به برخی از آنها اشاره می شود.

اجتناب از جهانی های تصادفی:

'use strict';
x = 10; // ReferenceError: x is not defined
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اختصاص دادن یک مقدار به یک متغیر اعلام نشده، یک متغیر سراسری ایجاد می کند. حالت سختگیرانه از این امر جلوگیری می کند.

موارد تکراری در لفظ شیء:

'use strict';

var obj = {
    prop: 1,
    prop: 2 // SyntaxError: Duplicate data property in object literal
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

حالت سختگیرانه برای نام‌های خصوصیات تکراری در لفظ شیء خطایی ایجاد می‌کند.

گرفتن خطاهای بی صدا:

در حالت غیر دقیق، تخصیص یک مقدار به یک ویژگی غیرقابل نوشتن هیچ کاری بی‌صدا نمی‌کند. در حالت سخت، خطا می دهد.

// non strict mode
var obj = {};
Object.defineProperty(obj, 'x', { value: 42, writable: false });

obj.x = 9; // Fails silently, obj.x remains 42
console.log(obj.x); // 42
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

'use strict';

var obj = {};
Object.defineProperty(obj, 'x', { value: 42, writable: false });

obj.x = 9; // TypeError: Cannot assign to read only property 'x' of object '#
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

چگونه می کند this در داخل توابع منظم و توابع پیکانی رفتار کنید؟

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

مثال زیر رفتار this در یک تابع تماس معمولی که در داخل یک تابع تعریف شده است.

const student = {
  name: "Jon Doe",
  printAllCourses: function () {
    const subjects = ["cs-101", "cs-202", "econ-101"];
    subjects.forEach(function (sub) {
      console.log(sub);
      console.log("Student Name", this.name);
    });
  },
};

student.printAllCourses();

// outputs

/**
cs-101
Student Name undefined
cs-202
Student Name undefined
econ-101
Student Name undefined
**/
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

به عملکرد برگشت به تماس توجه کنید forEach در حال تلاش برای دسترسی به name دارایی اما در حال بازگشت است تعریف نشده.

حالا تابع callback را به یک تابع فلش تبدیل کنید و دوباره کد را اجرا کنید.

const student = {
  name: "Jon Doe",
  printAllCourses: function () {
    const subjects = ["cs-101", "cs-202", "econ-101"];
    subjects.forEach((sub) => {
      console.log(sub);
      console.log("Student Name", this.name);
    });
  },
};

student.printAllCourses();

// outputs

/**
cs-101
Student Name Jon Doe
cs-202
Student Name Jon Doe
econ-101
Student Name Jon Doe
**/
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

توجه داشته باشید که این بار می تواند همانطور که انتظار می رود به ویژگی name دسترسی پیدا کند.

در واقع اینجا چه اتفاقی می افتد؟

this داخل یک تابع منظم بستگی به نحوه فراخوانی تابع دارد. هنگامی که یک تابع معمولی به عنوان پاسخ به تماس استفاده می شود، فقط در آن صورت this به شی جهانی اشاره دارد (window در مرورگرها)، که در مثال بالا وجود دارد. از طرف دیگر، اگر تابع به عنوان یک تابع فراخوانی فراخوانی نشود، می تواند با استفاده از ویژگی های اشیاء والد دسترسی پیدا کند this. بنابراین، اساسا، یک تابع فراخوان همیشه به عنوان تابعی در نظر گرفته می شود که در زمینه جهانی تعریف شده است.

از سوی دیگر، توابع پیکان، خود را ندارند this متن نوشته. در عوض از نظر لغوی ارث می برند this از کد اطراف این به سادگی به این معنی است که تابع فلش به خصوصیات شیئی که در آن تعریف شده است دسترسی دارد this داخل یک فلش تابع همان است this خارج از تابع فلش

const student = {
  name: "Jon Doe",
  printAllCourses: function () {
    const subjects = ["cs-101", "cs-202", "econ-101"];
    console.log("outside arrow func", this); // this here is the same this inside the callback arrow function below
    subjects.forEach((sub) => {
      console.log("inside arrow func", this); // same this as above
    });
  },
};
student.printAllCourses();
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سلام، اگر از این پست لذت می برید و می خواهید موارد بیشتری را مشاهده کنید، فراموش نکنید که من را در dev.to دنبال کنید. ایکس یا لینکدین

چگونه می کند this در زمینه کلاس es6 کار کنید؟

در کلاس های ES6، this کلمه کلیدی در مقایسه با توابع سنتی جاوا اسکریپت قابل پیش بینی تر و سازگارتر است. هنگام استفاده از this در داخل متدهای یک کلاس، به طور کلی به نمونه کلاسی که متد در آن فراخوانی شده است اشاره دارد.

یک کلاس ES6 ساده را در نظر بگیرید:

class Person {
  constructor(name) {
    this.name = name;
  }

  printName() {
    console.log(this.name);
  }
}

const person = new Person('Alice');
person.printName(); // Outputs: Alice

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در مثال this درون constructor متد به نمونه جدیدی از کلاس در حال ایجاد اشاره دارد.

this درون printName روش به نمونه ای اشاره دارد Person کلاسی که در آن printName روش نامیده شد.

حال بیایید نگاهی به مثالی بیندازیم که مشکلات احتمالی را هنگام استفاده از متدهای کلاس به‌عنوان بازگشت تماس و نحوه رسیدگی به آنها نشان می‌دهد:

class Person {
  constructor(name) {
    this.name = name;
  }

  printName() {
    console.log(this.name);
  }

  printNameDelayed() {
    setTimeout(function() {
      console.log(this.name);
    }, 1000);
  }

  printNameDelayedWithArrow() {
    setTimeout(() => {
      console.log(this.name);
    }, 1000);
  }

  printNameDelayedWithBind() {
    setTimeout(function() {
      console.log(this.name);
    }.bind(this), 1000);
  }
}

const person = new Person('Bob');
person.printName(); // Outputs: Bob
person.printNameDelayed(); // Outputs: undefined (or error in strict mode)
person.printNameDelayedWithArrow(); // Outputs: Bob
person.printNameDelayedWithBind(); // Outputs: Bob

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

توجه کنید، در printNameDelayed تابع فراخوانی را به روش ارسال کنید setTimeout یک تابع منظم است، بنابراین this داخل آن به مصداق اشاره نمی کند Person. در عوض، به شی جهانی (یا undefined در حالت سختگیرانه).

استفاده از یک تابع فلش به عنوان پاسخ تماس، حفظ می کند this زمینه از روش محصور کردن، بنابراین this اشاره به نمونه از Person. را printNameDelayedWithArrow یک راه حل ممکن برای مشکل برگشت تماس است.

راه دیگر برای حل این مشکل برگشت از طریق اتصال است. که در printNameDelayedWithBind ما به صراحت تابع callback را به آن متصل می کنیم this . آن را تضمین می کند this در داخل callback اشاره به نمونه از Person.

کلمات پایانی

امیدوارم این مقاله درک بهتری از این موضوع به شما داده باشد this.

به این به عنوان فریبکار شیطانی جاوا اسکریپت فکر کنید – که همیشه شما را سرپا نگه می دارد. اما اکنون، شما در حال شوخی هستید. به آزمایش خود ادامه دهید و به زودی این فرد مورد اعتماد شما خواهد بود، نه دشمن شما.

بنابراین دفعه بعد که کسی می گوید جاوا اسکریپت گیج کننده است، فقط چشمک بزنید و بگویید: “من دقیقا می دانم چه کسی this است!» برو و فتح کن، و باشد this با تو بودن!

اگر از این پست لذت بردید من را دنبال کنید ایکس یا لینکدین

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا