آموزش bind در جاوا اسکریپت

آموزش Bind در جاوا اسکریپت به زبانی ساده
متد
bind در جاوا اسکریپتبه زبانی بسیار ساده راهی برای پیوند دادن تابعی به شیئی خاص است. در این رابطه کلمه کلیدی this به تابع اجازه میدهد تا بر اساس شیئی که با آن مرتبط است رفتار متفاوتی داشته باشد. به طور معمول، تابع ممکن است نتایج ثابتی ایجاد کند، اما با عمل اتصال یا binding، میتواند رفتار خود را بسته به زمینه مد نظر تطبیق دهد. برای این منظور از متد bind استفاده میشود.
اگر
آموزش جاوا اسکریپترا از قبل دیده باشید امکان دارد که با متد bind کموبیش آشنایی داشته باشید ولی با این حال در این مطلب از مجله سبزلرن میخواهیم که به صورت کامل و با رویکردی کاملاً عملی به آموزش
متد bind در جاوا اسکریپتبپردازیم. قبل از این که این متد را مورد بررسی دقیق قرار دهیم در ابتدا باید با مفهوم کلمه کلیدی This در جاوا اسکریپت آشنا شویم و چند مثال را در همان ابتدا بررسی کنیم تا در ادامه با دستی باز تر بتوانیم در مورد این متد سخن بگوییم.
کلمه کلیدی this در جاوا اسکریپت
this در
زبان برنامه نویسی جاوا اسکریپتبه شیئی که به آن تعلق دارد اشاره دارد و مقدار آن بسته به نحوه فراخوانی تابع تغییر میکند. هنگامیکه تابع بخشی از شی (یا متدی) است، this آن شی را نشان میدهد؛ اما در یک تابع معمولی، this معمولاً به شی سراسری اشاره میکند که معمولاً در این سناریو شی پنجره (window) در محیطهای مرورگر است. به عنوان نمونه به این مثال توجه کنید:
let Sabz = {
name: "ABC",
printFunc: function () {
console.log(this.name);
}
}
sabz.printFunc();
در مثال بالا، this در متد printFunc به شی sabz اشاره دارد زیرا printFunc روی sabz فراخوانی میشود؛ بنابراین، زمانی که sabz.printFunc اجرا میشود، مقدار sabz.name را چاپ میکند که ABC است.
همچنین در مثال زیر، ارتباط this با شی آن از بین رفته و در نتیجه خروجی تولید نمیشود.
let sabz = {
name: "ABC",
printFunc: function () {
console.log(this.name);
}
}
let printFunc2 = sabz.printFunc;
printFunc2();
در مثال فوق، printFunc2 به متد printFunc از شی sabz اختصاص داده میشود. با این حال، وقتی printFunc2 به طور مستقل، بدون اینکه به sabz گره بخورد، فراخوانی شود، اتصال this از بین میرود. در نتیجه، this.name به هیچ شیئی اشاره نمیکند و منجر به خروجی تعریف نشده میشود.
همچنین در مثال زیر، ما سناریوی قبلی را با استفاده از متد
bind در جاوا اسکریپتبهبود میدهیم. متد bind یک تابع جدید ایجاد میکند که در آن this به شی مشخصشده در پرانتز آن اشاره دارد.
let sabz = {
name: "ABC",
printFunc: function () {
console.log(this.name);
}
}
let printFunc2 = sabz.printFunc.bind(sabz);
// Using bind()
// bind() takes the object sabz as a parameter
printFunc2();
در مثال فوق، printFunc2 به متد printFunc از شی sabz اختصاص داده میشود اما با یک زمینه خاص که با استفاده از
bind در جاوا اسکریپتمشخصشده است. در این رابطه کلمه کلیدی this تضمین میکند که وقتی printFunc2 فراخوانی میشود، this.name به ویژگی name شی sabz اشاره میکند؛ بنابراین، خروجی ABC است.
در نهایت و در مثال زیر ما سه شی داریم که هر کدام ویژگیهای متفاوتی دارند. سپس از متد bind برای مرتبط کردن یک تابع مشترک با هر شی استفاده میکنیم.
// Object sabz1
let sabz1= {
name: "ABC",
article: "C++"
}
// Object sabz2
let sabz2 = {
name: "CDE",
article: "JAVA"
}
// Object sabz3
let sabz3 = {
name: "IJK",
article: "C#"
}
// Function to print values
function printVal() {
console.log(this.name + " contributes about " +
this.article + "
");
}
// Using bind() to associate printVal with each object
let printFunc2 = printVal.bind(sabz1);
printFunc2();
let printFunc3 = printVal.bind(sabz2);
printFunc3();
let printFunc4 = printVal.bind(sabz3);
printFunc4();
هر بار که printVal را صدا میزنیم، با استفاده از متد
bind در جاوا اسکریپتبا یک شی متفاوت مرتبط میشود. این رویکرد به ما اجازه میدهد تا اطلاعات منحصربهفردی را در مورد هر شیء تولید کنیم. در نهایت خروجی مثال فوق خواهد بود:
ABC contributes about C++
CDE contributes about JAVA
IJK contributes about C#
تا به اینجای مطلب پیش زمینه نسبتاً مناسبی از متد
bind در Javascriptارائه کردیم و حال آمادهایم که به صورت جزئیتری به تعریف آن بپردازیم.
تابع Bind در جاوا اسکریپت چیست؟
متد
bind در جاوا اسکریپتبرای ایجاد نوعی تابع جدید استفاده میشود. هنگامیکه این تابع جدید فراخوانی میشود، کلمه کلیدی this آن با مقدار خاصی که ما ارائه میکنیم تنظیم میشود. به زبان ساده، متد bind در زبان برنامهنویسی جاوا اسکریپت راهی برای ایجاد نوعی تابع جدید با مقداری خاص برای کلمه کلیدی this است. این متد زمانی مفید است که میخواهید اطمینان حاصل کنید که یک تابع همیشه با یک زمینه یا شی خاص فراخوانی میشود.
به عنوان مثال، اگر تابعی دارید که متعلق به یک شی است اما میخواهید آن را در زمینه متفاوت بدون از دست دادن ارتباطش با شی اصلی استفاده کنید، میتوانید از bind برای ایجاد تابع جدید با زمینه مورد نظر استفاده کنید. در اینجا نحوه استفاده از متد
bind در Javascriptآمده است:
fn.bind(thisArg[, arg1[, arg2[, ...]]])
تشریح سینتکس فوق به صورت زیر است:
- fn تابعی است که میخواهیم عمل اتصال به زمینه خاص برای آن انجام شود.
- thisArg مقداری است که میخواهیم کلمه کلیدی this هنگام فراخوانی تابع محدود روی آن تنظیم شود.
- arg1»، «arg2» و غیره، آرگومانهای اختیاری هستند که میتوانند هنگام فراخوانی تابع محدود به آن ارسال شوند.
let greet = function(message) {
console.log(message + ', ' + this.name);
};
let person = {
name: 'John'
};
let greetJohn = greet.bind(person, 'Hello');
greetJohn(); // Output: Hello, John
در کد فوق، greet.bind(person, 'Hello') تابع جدید greetJohn ایجاد میکند که در آن this روی شی person تنظیم شده است. هنگامیکه greetJohn فراخوانی میشود، Hello, John را به کنسول وارد میکند.
کاربرد متد bind چیست؟
متد
bind در جاوا اسکریپتمعمولاً در سناریوهای مختلفی استفاده میشود که از مهمترین این کاربردها میتوان موارد زیر را ذکر کرد:
- کنترلکننده رویداد یا Event Handler
- توابع Callback
- توابع جزئی
- توابع Currying
- ایجاد نام مستعار
در اصل متدی همهکاره است که به مدیریت و کنترل زمینهای که توابع در آن اجرا میشوند کمک میکند و از رفتار قابل پیشبینی و کد تمیزتر در سناریوهای مختلف اطمینان میدهد.
استفاده از bind در جاوا اسکریپت برای اتصال تابع
وقتی متدی از یک شی را به عنوان نوعی فراخوانی به تابع دیگری ارسال میکنید، گاهی اوقات کلمه کلیدی this گم میشود. فرض کنید یک شی به نام person با متدی به نام getName داریم. اگر بخواهیم از person.getName به عنوان نوعی تابع تماس برای setTimeout استفاده کنیم، ممکن است آنطور که انتظار میرود کار نکند. طبق مثال زیر:
let person = {
name: 'John Doe',
getName: function() {
console.log(this.name);
}
};
setTimeout(person.getName, 1000);
خروجی مثال بالا ممکن است تعریف نشده (undefined) را به جای John Doe بیرون دهد. این اتفاق میافتد زیرا setTimeout، person.getName را جداگانه از شی person دریافت میکند، بنابراین نمیداند this باید به چه چیزی اشاره کند.
برای حل این مشکل، میتوانیم تماس person.getName را در تابعی ناشناس قرار دهیم یا از متد bind استفاده کنیم. طبق مثال زیر:
// Using an anonymous function
setTimeout(function () {
person.getName();
}, 1000);
// Using the bind() method
let f = person.getName.bind(person);
setTimeout(f, 1000);
در مثال فوق با
bind در جاوا اسکریپتتابع جدیدی ایجاد میکنیم که در آن this به طور دائم روی شی person تنظیم میشود. سپس، این تابع جدید f را به setTimeout منتقل کرده و مطمئن میشویم که this زمینه صحیح خود را هنگام فراخوانی person.getName حفظ میکند.
استفاده از bind برای قرض گرفتن متدها از یک شی متفاوت
فرض کنید دو شی runner با متد run و flyer با متد fly دارید. اگر بخواهید شی flyer نیز بتواند اجرا شود، میتوانید از متد bind به صورت زیر استفاده کنید.
let runner = {
name: 'Runner',
run: function(speed) {
console.log(this.name + ' runs at ' + speed + ' mph.');
}
};
let flyer = {
name: 'Flyer',
fly: function(speed) {
console.log(this.name + ' flies at ' + speed + ' mph.');
}
};
برای اینکه flyer بتواند اجرا شود، میتوانید تابعی جدید با استفاده از bind به صورت زیر ایجاد کنید:
let run = runner.run.bind(flyer, 20); run();
در کد فوق ما از متد bind در runner.run استفاده میکنیم و flyer را به عنوان اولین آرگومان و 20 را به عنوان آرگومان دوم پاس میکنیم. سپس تابع run را فراخوانی خواهیم کرد. خروجی به صورت زیر خواهد بود:
Flyer runs at 20 mph.
استفاده از
bind در جاوا اسکریپتبه شی اجازه میدهد تا یک متد را از یک شی دیگر بدون کپی کردن آن قرض بگیرد. این ویژگی در جاوا اسکریپت قرض تابع نامیده میشود.
مزایا و معایب استفاده از متد bind در جاوا اسکریپت چیست؟
استفاده از متد
bind در Javascriptچندین مزیت دارد اما برخی از اشکالات بالقوه را نیز دارد که باید در نظر گرفت:
مزایای این متد به صورت زیر است:
- قابلیت اتصال آسان
- قابلیت استفاده مجدد تابع
- توابع جزئی
- اجتناب از درگیر کردن دامنه جهانی
- سربار عملکرد
- مصرف حافظه
- سردرگمی
میتواند منجر به کدهایی شود که درک و نگهداری آن دشوار است، به خصوص برای توسعهدهندگانی که با رفتار آن آشنا نیستند.
- پتانسیل نشت حافظه
در چه سناریوهایی نباید از متد bind استفاده کنیم؟
چندین سناریو وجود دارد که استفاده از
متد bind در جاوا اسکریپتممکن است بهترین رویکرد نباشد. این سناریوها به صورت موارد زیر هستند:
- برنامههای کاربردی حیاتی
- فراخوانیهای توابع عمیق تودرتو
- متدهای نمونه اولیه در جاوا اسکریپت
- اتصال با زمینه پویا
متدهای و رویکردهای جایگزین برای متد bind در جاوا اسکریپت
در جاوا اسکریپت، چندین متد و تکنیک جایگزین برای متد bind وجود دارد که میتواند به جای آن برای مدیریت بافت تابع و دستیابی به عملکرد مشابه استفاده شود که در زیر این روشهای جایگزین همراه با مثال آورده شدهاند.
توابع پیکان
توابع پیکان (`=>`) به صورت لغوی کلمه کلیدی this را به زمینه مدنظر متصل میکنند، به این معنی که آنها مقدار this را از کد در زمان تعریف خود به ارث میبرند. این امر نیاز به اتصال صریح با استفاده از bind را از بین میبرد. با این حال، توابع پیکان را نمیتوان به عنوان سازنده استفاده کرد و زمینه this خود را ندارند.
let obj = {
name: 'John',
sayName: () => {
console.log(this.name); // 'this' refers to the outer scope
}
};
متدهای call و apply
به جای استفاده از
bind در جاوا اسکریپت، میتوانید از متدهای call یا apply برای تعیین صریح زمینه this هنگام فراخوانی تابع استفاده کنید. این متدها بلافاصله تابع را با مقدار this مشخصشده و آرگومانهای اختیاری فراخوانی میکنند.
let obj1 = { name: 'John' };
let obj2 = { name: 'Jane' };
function sayName() {
console.log(this.name);
}
sayName.call(obj1); // 'John'
sayName.apply(obj2); // 'Jane'
توابع Closure
میتوانید با تعریف تابع wrapper که تابع اصلی و زمینه مورد نظر آن را در برمیگیرد، یک بسته یا Closure ایجاد کنید. این کار به شما امکان میدهد تا زمانی که تابع فراخوانی میشود، زمینه صحیح this را حفظ کنید.
let obj = { name: 'John' };
function sayNameClosure() {
let self = this;
return function() {
console.log(self.name);
};
}
let boundFunc = sayNameClosure.call(obj);
boundFunc(); // 'John'
پارامترهای destructuring و rest در ES6
ES6 پارامترهای destructuring و rest را معرفی میکند که میتواند برای ضبط و ارسال آرگومانها به تابع استفاده شود. این رویکرد میتواند برای ایجاد توابع مرتبه بالاتر که زمینه را حفظ میکنند مفید باشد.
let obj = { name: 'John' };
function sayNameWithArgs(...args) {
console.log(args[0].name);
}
let boundFunc = sayNameWithArgs.bind(null, obj);
boundFunc(); // 'John'
Polyfill
اگر نیاز به پشتیبانی از مرورگرهای قدیمی دارید که به طور بومی از bind پشتیبانی نمیکنند، میتوانید یک polyfill برای متد bind با استفاده از متدهای call یا apply به صورت زیر ایجاد کنید.
if (!Function.prototype.bind) {
Function.prototype.bind = function(thisArg) {
var fn = this,
args = Array.prototype.slice.call(arguments, 1);
return function() {
return fn.apply(thisArg, args.concat(Array.prototype.slice.call(arguments)));
};
};
}
این متدها و روشهای جایگزین انعطافپذیری را فراهم میکنند و به شما این امکان را میدهند که بافت و زمینه اجرایی تابع را به طور مؤثر بدون تکیهبر
متد bind در جاوا اسکریپتمدیریت کنید. در این رابطه بهتر است روشی را انتخاب کرده که به بهترین وجه با الزامات و محدودیتهای پروژه شما مطابقت دارد.
آموزش جاوا اسکریپت از صفر تا صد
متد
bind در جاوا اسکریپتابزاری قدرتمند برای مدیریت زمینه اجرایی تابع است که به توسعهدهندگان این امکان را میدهد تا به صراحت مقدار کلمه کلیدی this را در تابعی تنظیم کنند. این متد در اصل امکان ایجاد توابع جدید با زمینههای از پیش تعریفشده را فراهم میکند، رفتار قابل پیشبینی را تضمین کرده و قابلیت استفاده مجدد کد را ارتقا میدهد. در مطلب فوق از مجله سبز لرن ما اطلاعات کاملی از متد
bind در جاوا اسکریپتارائه کردیم. به امید اینکه برای شما مفید بوده باشد.
قضیه متد
bind در JAvascriptفقط و فقط یکی از مباحث مهم و حیاتی جاوا اسکریپت است. برای آن دسته از افرادی که میخواهند که به همه مسائل و چالشهای جاوا اسکریپت مسلط شوند، مطالعه و آموزش دیدن اهمیت بسیار زیادی دارد. در این رابطه توصیه ما به شما شرکت در دوره آموزش صفر تا صد جاوا اسکریپت سبز لرن است. در این دوره آموزشی شما از صفر تا صد جاوا اسکریپت را با رویکردی متفاوت و کاربردی یاد میگیرد و در عین حال پشتیبانی اساتید دوره را دریافت خواهید کرد.
مقالات مرتبط
نظرات
اولین نفری باش که برای این مقاله نظر میدی.