کلمه کلیدی فراموش شده (with) در جاوااسکریپت

آفلاین
user-avatar
عرفان حشمتی
31 مرداد 1400, خواندن در 5 دقیقه

توسعه جاوااسکریپت می‌تواند یک کار هیجان انگیز باشد. اگر با این زبان کار کنید، تقریبا هر روز چیزهای جدید و غیرعادی پیدا می‌کنید. گاهی اوقات این یک تجربه جالب است و گاهی اوقات هم ممکن است ترسناک به نظر برسد.

در این مقاله قصد داریم به کلمه کلیدی "with" نگاهی بیاندازیم. این یکی از جنبه‌های تاریک زبان است که حتی توسعه‌دهندگان با تجربه هم اغلب از آن مطلع نیستند.

کاربرد و نحوه استفاده

با استفاده از کلمه کلیدی with یک پیام به کنسول وارد می‌کنیم:

with (console) {
  log('I dont need the "console." part anymore!');
}

و سپس از آن برای متصل کردن یک آرایه به یک رشته استفاده می‌نماییم:

with (console) {
  with (['a', 'b', 'c']) {
    log(join('')); // writes "abc" to the console.
  }
}

بله دوستان، چه باور کنید یا نه، چنین کاری در جاوااسکریپت قابل اجرا است.

کارهایی که "with" انجام می‌دهد

جاوااسکریپت با جستجو در یک محدوده مرتبط با یک اسکریپت یا یک تابع، به دنبال نام مورد نظر می‌گردد. عبارت "with" شی داده شده را هنگام ارزیابی کد به ابتدای این محدوده اضافه می‌کند. اگر نام مورد نظر در کد با یک ویژگی در محدوده مطابقت داشته باشد، نام به ویژگی و شی حاوی آن ویژگی متصل می‌گردد، در غیر این صورت ReferenceError نشان داده می‌شود.

به بیان ساده‌تر هنگامی که یک شناسه در کد خود می‌نویسید (مانند log یا join در قطعه کد بالا) زنجیره‌ای از اشیا وجود دارد که جاوااسکریپت به آنها نگاه می‌کند و اگر یکی از این اشیا دارای ویژگی با همان نامی که در کد خود نوشته‌اید باشد، جاوااسکریپت از مقدار آن ویژگی استفاده می‌نماید.

به علاوه کلمه کلیدی with به شما امکان می‌دهد هر شی دلخواه را در قسمت جلوی زنجیره تزریق کنید. در اینجا مثال دیگری وجود دارد که ممکن است آن را واضح‌تر نشان دهد:

with ({ myProperty: 'Hello world!' }) {
  console.log(myProperty); // Logs "Hello world!"	
}	

از آن استفاده نکنید

عالی به نظر می‌رسد، نه؟ شاید هم اینگونه نباشد.

در بیشتر موارد تنها با استفاده از متغیرهای موقت می‌توان به همان نتیجه رسید، که از زمان معرفی destructing این کار آسانتر شده است.

همچنین MDN تعدادی از مشکلات آن را ذکر می‌کند:

ممنوع بودن در strict mode

نمی‌توانید در strict mode از آن استفاده کنید. با توجه به اینکه ماژول‌ها و کلاس‌های ES به طور خودکار در strict mode قرار دارند، این محدودیت حتی امکان استفاده از with را در بسیاری از موارد دیگر از بین می‌برد.

Shadowing تصادفی

کد زیر را برای میانگین دو عدد در نظر بگیرید و نتیجه را به یک عدد صحیح گرد کنید:

function getAverage(min, max) {
  with (Math) {
    return round((min + max) / 2);
  }
}

getAverage(1, 5);

این قطعه کد در نتیجه NaN را برمی‌گرداند. اما دلیل آن چیست؟ از آنجا که ()Math.min و ()Math.max در نهایت آرگومان‌های تابع را می‌گیرند، بنابراین ما مجموع دو تابع را که NaN است محاسبه می‌کنیم.

اساسا اگر از with استفاده می‌کنید، باید در انتخاب شناسه‌ها دقت بیشتری داشته باشید. همچنین باید به آنچه که از طریق with منتقل شده نگاه کنید تا مطمئن شوید که دارای ویژگی‌هایی نباشد که بتواند ناخواسته چیز دیگری را در یک محدوده بالاتر تحت تاثیر قرار دهد.

این رفتار همچنین می‌تواند آسیب پذیری‌های امنیتی را ایجاد کند. اگر مهاجم بتواند ویژگی‌هایی را به شی موردنظر شما اضافه کند، در نتیجه می‌تواند شناسه‌های شما را تحت تاثیر قرار داده و رفتار کد را به روش‌های غیر منتظره تغییر دهد.

به عنوان مثال، ارسال یک شی به with که از بدنه درخواست JSON HTTP نامعتبر تجزیه شده، بسیار خطرناک خواهد بود.

عملکرد و کارایی

با افزودن هر چیزی به محدوده تقریبا اجرای هر خط کد را کند می‌کنید، زیرا تعداد اشیایی که باید جستجو شوند تا شناسه‌های خود را به مقادیر مورد نظر منتقل کنند را افزایش می‌دهید.

محرومیت

اگر از کلمه کلیدی with استفاده کنید، همه فکر می‌کنند دیوانه هستید و از شما دوری می‌کنند، یا ممکن است شما را مسخره کنند!

در هر صورت استفاده از ویژگی‌های جادویی زبان که هیچ کس از آنها اطلاع ندارد، حفظ و نگهداری کد شما را دشوارتر می‌کند و در این صورت سود چندانی برای شما نخواهد داشت.

جمع بندی

کلمه کلیدی with قابلیت‌های جالبی به زبان اضافه می‌کند، اما در نهایت دارای نقاط ضعف زیاد و مزایای بسیار کمی است تا بتوان استفاده از آن را توصیه کرد.

البته این نظر تنها شخص من نیست و MDN هم به شدت از آن متنفر است و به همین دلیل استفاده از آن در strict mode ممنوع می‌باشد.

من بیش از پنج سال است که با جاوااسکریپت کدنویسی می‌کنم و این مرا شگفت زده می‌کند که تا به امروز هنوز هم کلمات کلیدی این زبان محبوب را یاد می‌گیرم. شما چه موارد دیگری را سراغ دارید؟ در بخش نظرات آنها را به اشتراک بگذارید.

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

همچنین می‌توانید به منظور افزایش معلومات خود، مقالات نگاهی به اکوسیستم جاوااسکریپت و ۱۰ کتابخانه مفید جاوااسکریپت را دنبال کنید.

منبع

چه امتیازی به این مقاله می دید؟
خیلی بد
بد
متوسط
خوب
عالی

دیدگاه‌ها و پرسش‌ها

برای ارسال دیدگاه لازم است، ابتدا وارد سایت شوید.

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

آفلاین
user-avatar
عرفان حشمتی @heshmati74
مهندس معماری سیستم های کامپیوتری، طراح و توسعه دهنده وب سایت
دنبال کردن

گفتگو‌ برنامه نویسان

بخشی برای حل مشکلات برنامه‌نویسی و مباحث پیرامون آن وارد شو