من میدانم که هیچ نمیدانم.
بررسی Optional Chaining (.?) در جاوااسکریپت

اگر به تازگی شروع به خواندن آموزش و یادگیری جاوا اسکریپت کرده اید ، شاید این مشکل را هنوز لمس نکرده اید ، اما این یک مشکل کاملاً رایج است.
برای مثال, بیاید یک شی(object) برای ذخیره کردن اطلاعات کاربرانمان در نظر بگیریم. اکثر کاربران ما ویژگی(property) آدرس را در user.address و خیابان را در user.address.street را دارند ولی بعضی از آنان این اطلاعات را ارائه نکرده اند.
در همچین مثالی تلاش ما برای دریافت مقدار user.address.street, برای کاربری که آدرس ندارد با خطا مواجه شود :
let user = {}; // یک کاربر بدون ویژگی "address"
alert(user.address.street); // خطااین یک خروجی قابل حدس است٬ جاوااسکریپت اینگونه کار میکند٬ تا زمانی که user.address برابر با undefined است تلاش برای گرفتن آن با خطا مواجه میشود. ولی در بسیاری از موارد عملی ، ما ترجیح می دهیم به جای خطا ، undefined را دریافت کنیم (به معنای "بدون خیابان").
یا مثالی دیگر در توسعه وب٬ ما میخواهیم اطلاعاتی در مورد اِلمانی در صفحه را بگیریم.این اِلمان توسط این عبارت document.querySelector('.elem') گرفته میشود که ممکن است گاهی وجود نداشته باشد:
document.querySelector('.elem') // خواهد شد اگر المنت وجود نداشته باشد null
let html = document.querySelector('.elem'); // اگر باشد خطا خواهد داد NULLیکبار دیگر٬ اگر اِلمان وجود نداشته باشد ما با مقدار NULL نمیتوانیم به دسترسی داشته باشیم. و در بعضی موارد وقتی که نبود اِلمان طبیعی است ، ما میخواهیم از خطا جلوگیری کنیم و فقط "html = null" را قبول کنیم.
چگونه میتوانیم از این استفاده کنیم ؟
راهحل روشن این است که مقدار آن را با if یا عمگر شرطی ? بررسی کنیم قبل از اینکه به ویژگی (property) آن دسترسی پیدا کنیم.
let user = {};
alert(user.address ? user.address.street : undefined);الان بدون خطا کار میکند... ولی اصلا زیبا نیست. همانطور که میبینید مقدار"user.address" دوبار در کد تکرار شده است. برای دسترسی به ویژگیهای(property) با تو در تویی زیاد نیاز به تکرار بیشتری لازم است و این مشکل ایجاد میکند.
برای مثال بیاید مقدار عبارت user.address.street.nameرا بگیریم.
در این صورت ما باید هم user.address و user.address.street را بررسی کنیم :
let user = {}; // کاربر بدون آدرس
alert(user.address ? user.address.street ? user.address.street.name : null : null);این افتضاح است یک نفر ممکن حتی با درک این کد مشکل داشته باشد.
قبل از اینکه زنجیره اختیاری به جاوااسکریپت اضافه شود مردم از عملگر && برای بعضی مواقع استفاده میکردند:
نگران نباشید :) ٬ راه های بهتری هم هست میتوانیم از عملگر && استفاده کنیم.
let user = {}; // کاربر بدون آدرس
alert( user.address && user.address.street && user.address.street.name ); // undefined (بدون خطا)اند(AND) کردن کل مسیر رسیدن به ویژگی ، وجود همه ویژگی ها(property) را تضمین می کند(اگر ارزیابی متوقف نشود) ، اما نوشتن آن دست و پا گیر است.
همانطور که میبنید نام ویژگی ها همچنان در کد تکرار میشوند. به طور مثال در قطعه کد بالا user.address سه بار تکرار شده است.
و حالا در نهایت زنجیره اختیاری آمده است که ما را نجات دهد!
زنجیره اختیاری
زنجیره ای اختیاری ?. بررسی را متوقف میکند اگر مقدار قبل از قسمت ?. برابر با undefined یا null باشد و مقدار undefined را برمیگرداند.
یا به عبارت دیگر value?.prop :
- برابر است با
value.propاگرvalueوجود داشته باشد - در غیر اینصورت (زمانی که
valueبرابر باundefined/nullاست) مقدارundefinedرا برمیگرداند.
.? این یک دسترسی مطمئن به user.address.street است:
let user = {}; // کاربر بدون آدرس
alert( user?.address?.street ); // undefined (بدون خطا)حالا کد خیلی کوتاهتر و تمیزتر است و بدون هیچ تکرار اضافهای :)
خواندن ویژگی(property) آدرس با user?.address کار خواهد کرد حتی زمانی هم که شی(آبجکت) user وجود ندارد :
let user = null;
alert( user?.address ); // undefined
alert( user?.address.street ); // undefinedلطفا توجه داشته باشید : سینتکس ?. مقدارهای قبلی را اختیاری میکند نه مقدارهای جلوی آن را.
در مثال بالا user?. به user مقدار null/undefined خواهد داد.
در مثال بالا user?.address.street فقط به user اجازه میدهد که null/undefined باشد. مثلا در این کد user?.address.street.name عبارت .? اجازه میدهد که user برابر با null/undefined باشد. این همه کاری است که انجام میدهد.
ویژگی های جلویی به سبک معمولی به ویژگی ها دسترسی دارند.اگر ما میخواهیم بعضی از ویژگی ها را اختیاری کنیم میتوانیم تعداد بیشتری از . را با .? جایگزین کنیم
از طرف دیگر ، اگر user وجود داشته باشد ، پس باید ویژگی user.address داشته باشد ، در غیر این صورت user؟.address.streetدر نقطه دوم خطا می دهد.
ما باید از `?.` فقط زمانی استفاده کنیم که عدم وجود چیزی اشکالی ندارد.برای مثال اگر طبق منطق و لاجیک ما باید شی(object)`user` وجود داشته باشد ولی address اختیاری است. پس ما باید اینگونه بنویسیم user.address?.street نه user?.address?.street
بنابراین ، اگر تصادفاً به دلیل اشتباهی user برابر با undefined باشد، شاهد یک خطای برنامه نویسی در مورد آن خواهیم بود و آن را برطرف خواهیم کرد.
برای زنجیره اختیاری باید متغیر حتما تعریف شده باشد ( let/const/var user یا توابع ). زنجیره ای اختیاری فقط برای متغیرهای تعریف شده کار می کند.
// ReferenceError: user is not defined
user?.address;از زنجیره اختیاری میتوان برای صدا زدن توابع هم استفاده کرد :
let userAdmin = {
admin() {
alert("I am admin");
}
};
let userGuest = {};
userAdmin.admin?.(); // I am admin
userGuest.admin?.(); // هیچی (هیچ متدی نیست)اگر ما میخواهیم از براکت به جای نقطه برای دسترسی به ویژگی(property) استفاده کنیم زنجیره اختیاری برای آن حالت هم کارایی دارد.
let user1 = {
firstName: "John"
};
let user2 = null;
let key = "firstName"
alert( user1?.[key] ); // John
alert( user2?.[key] ); // undefined
alert( user1?.[key]?.something?.not?.existing); // undefinedخلاصه
سینتکس ?. سه حالت دارد:
- حالت اول:
obj?.prop- مقدار obj.propرا برمیگرداند اگرobjوجود داشته باشد در غیر اینصورت مقدارundefinedرا برمیگرداند - حالت دوم:
[obj?.[prop- مقدار [obj.[propرا برمیگرداند اگرobjوجود داشته باشد در غیر اینصورت مقدارundefinedرا برمیگرداند - حالت سوم:
()obj.method()- obj?.methodرا صدا میزند اگرobjوجود داشته باشد در غیر اینصورت مقدارundefinedرا برمیگرداند
همانطور که می بینیم ، همه آنها ساده و آسان برای استفاده هستند. ?. سمت چپ را از نظر null/undefined بررسی می کند و اجازه می دهد تا ارزیابی ادامه یابد اگر برابر باnull/undefined نباشد.
زنجیر ?. امکان دسترسی به خواص تودرتو را هم فراهم میکند.
با این حال هنوز ما باید ?. را با دقت اعمال کنیم ، فقط درصورتی قابل قبول است که سمت چپ ممکن است وجود نداشته باشد.با این حال خطاهای برنامه نویسی را از ما مخفی نمیکند اگر آنها اتفاق بیافتند.
مطلبی دیگر از این انتشارات
آموزش نصب کیف پول بایننس چین
مطلبی دیگر از این انتشارات
راهنمای مبتدیان برای سرمایه گذاری در ارزهای دیجیتال
مطلبی دیگر از این انتشارات
همه چیز درباره زبان برنامه نویسی سالیدیتی