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

سردرگمی زیادی در اطراف وجود دارد 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 با تو بودن!
اگر از این پست لذت بردید من را دنبال کنید ایکس یا لینکدین



