تابع Eval در جاوا اسکریپت

تابع Eval در جاوا اسکریپت

نوشته شده توسط: تیم فنی نیک آموز
تاریخ انتشار: ۲۵ مهر ۱۴۰۳
آخرین بروزرسانی: 25 مهر 1403
زمان مطالعه: 9 دقیقه
۰
(۰)

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

آشنایی با تابع Eval در جاوا اسکریپت

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

درصورتی‌که ورودی eval یک رشته نباشد، این تابع همان ورودی را بدون تغییر برمی‌گرداند. تابع eval مثل یک چاقو عمل می‌کند. از یک طرف، ابزاری قدرتمند برای اجرای کدهای پویا و انعطاف‌پذیر است. از طرف دیگر، استفاده نادرست از آن ممکن است خطرات امنیتی جدی به همراه داشته باشد.

انواع فراخوانی تابع Eval در جاوا اسکریپت 

نحوه فراخوانی Eval روی محدوده و دسترسی آن به متغیرها تاثیر می‌گذارد. در جاوا اسکریپت دو نوع فراخوانی برای eval وجود دارد: مستقیم و غیرمستقیم.

  • فراخوانی مستقیم

این نوع فراخوانی همانطور که از اسمش مشخص است، به‌صورت مستقیم با نوشتن eval(…) انجام می‌شود. در این حالت، کد داخل رشته می‌تواند به متغیرهای محلی که در همان محدوده تعریف شدند، دسترسی داشته باشند.

  • فراخوانی غیر مستقیم

هر روشی به غیر از فراخوانی مستقیم، غیرمستقیم محسوب می‌شود. استفاده غیرمستقیم از eval مثل این است که یک تگ <script> جداگانه داشته باشیم. به همین دلیل کد داخل eval در فضای سراسری (global) اجرا می‌شود نه فضای (local) که آن را فراخوانی کرده است. زیرا کد داخل eval به متغیرهای لوکالی که فراخوانی کرده، دسترسی ندارد.

eval غیرمستقیم، از strict mode محیط پیرامون خود تبعیت نمی‌کند و فقط زمانی در این حالت قرار می‌گیرد که رشته منبع خود دستور «use strict» را داشته باشد.

 

function nonStrictContext() {
  eval?.(`with (Math) console.log(PI);`);
}
function strictContext() {
  "use strict";
  eval?.(`with (Math) console.log(PI);`);
}
function strictContextStrictEval() {
  "use strict";
  eval?.(`"use strict"; with (Math) console.log(PI);`);
}
nonStrictContext(); // Logs 3.141592653589793
strictContext(); // Logs 3.141592653589793
strictContextStrictEval(); // Uncaught SyntaxError: Strict mode code may not include a with statement

 

در مثال پایین، دو روش فراخوانی تابع eval در جاوا اسکریپت را استفاده کردیم:

 

// Direct eval
let directEvalResult = eval("2 + 2");
console.log("Direct eval result:", directEvalResult);
// Indirect eval
let indirectEval = "eval";
let indirectEvalResult = window[indirectEval]("3 + 3");
console.log("Indirect eval result:", indirectEvalResult);

 

Direct eval result: 4

Indirect eval result: 6

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

کاربرد تابع Eval در جاوا اسکریپت

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

  • اجرای کدهای پویا: اگر بخواهید کدی را براساس ورودی کاربر اجرا کنید، با استفاده از eval() به‌سادگی این کار قابل انجام است.
  • ایجاد کدهای خودکار: با eval() می‌توانید به‌طور خودکار کدهایی را براساس الگوها یا قوانین خاصی تولید کنید.
  • تست و اشکال‌زدایی کد: eval() برای تست و اشکال‌زدایی قطعات کوچک کد JavaScript نیز کاربرد دارد.

نحوه کارکرد Eval؛ eval در جاوا اسکریپت چگونه کار می‌کند؟

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

 

console.log(eval('2 + 2'));
// Expected output: 4
console.log(eval(new String('2 + 2')));
// Expected output: 2 + 2
console.log(eval('2 + 2') === eval('4'));
// Expected output: true
console.log(eval('2 + 2') === eval(new String('2 + 2')));
// Expected output: false

 

نتیجه

 

> 4
> String { "2 + 2" }
> true
> false

 

  • در بخش اول، تابع Eval در جاوا اسکریپت رشته ۲ + ۲ را به عنوان یک عبارت ریاضی ارزیابی می‌کند و نتیجه آن، یعنی ۴ را به عنوان خروجی نمایش می‌دهد.
  • در بخش دوم، eval() یک آبجکت رشته‌ای جدید با محتوای ۲ + ۲ ایجاد می‌کند و سپس آن را به عنوان کد JavaScript ارزیابی می‌کند. در این حالت، تابع Eval در جاوا اسکریپت خود رشته ۲ + ۲ را به جای نتیجه آن (۴) به عنوان خروجی برمی‌گرداند.
  • در بخش بعدی eval() دو رشته ۲ + ۲ و ۴ را به عنوان عبارات ریاضی ارزیابی می‌کند و مقادیر نهایی آن‌ها را با یک‌دیگر مقایسه می‌کند. از آنجایی که هر دو عبارت نتیجه یکسانی (۴) دارند، عبارت eval(‘2 + 2’) === eval(‘4’) مقدار true را به عنوان خروجی برمی‌گرداند.
  • در بخش دوم فهمیدیم تابع Eval در جاوا اسکریپت رشته ۲ + ۲ را به عنوان خود رشته به جای نتیجه آن (۴) به عنوان خروجی برمی‌گرداند. eval(‘2 + 2’) رشته ۲ + ۲ را به عنوان خروجی برمی‌گرداند، درحالی که eval(new String(‘2 + 2’)) شیء String جدید با محتوای ۲ + ۲ را به عنوان خروجی برمی‌گرداند. از آنجا که این دو خروجی با یکدیگر متفاوت هستند، عبارت eval(‘2 + 2’) === eval(new String(‘2 + 2’)) مقدار false را به عنوان خروجی برمی‌گرداند.

مزایا و معایب استفاده از Eval

تابع Eval در جاوا اسکریپت از یک طرف به شما امکان می‌دهد با اجرای کدهای نوشته‌شده در قالب رشته، انعطاف‌پذیری فوق‌العاده‌ای به برنامه خود ببخشید. از طرف دیگر، خطرات امنیتی و خوانایی ضعیف کد را به ارمغان می‌آورد که ممکن است اثرات ناخوشایندی به بار آورد.

مزایای تابع Eval در جاوا اسکریپت 

  • اجرای کدهای پویا: Eval به شما این امکان را می‌دهد کدهایی را که در زمان اجرا به دست می‌آیند، به‌طور پویا ارزیابی و اجرا کنید. این قابلیت برای مواردی مانند بارگذاری اسکریپت‌های خارجی یا پردازش ورودی‌های کاربر که نیاز به پویایی دارند، بسیار مفید است.
  • ایجاد کدهای فشرده: با استفاده از Eval می‌توانید کدهای خود را به‌صورت فشرده و خلاصه بنویسید. به عنوان مثال، می‌توانید به جای نوشتن چندین خط کد تکراری، از یک رشته کوتاه و Eval برای دستیابی به همان نتیجه استفاده کنید.
  • ایجاد رابط‌های کاربری تعاملی: Eval می‌تواند برای ایجاد رابط‌های کاربری تعاملی پویا که براساس ورودی‌های کاربر تغییر می‌کنند، مورد استفاده قرار گیرد.

معایب و خطرات امنیتی Eval

تابع Eval در جاوا اسکریپت حاوی ریسک‌های امنیتی جدی است. به این دلیل که امکان اجرای کد دلخواه (arbitrary code execution) را فراهم می‌کند. اجرای کد دلخواه یعنی هر کسی می‌تواند کد مخرب به این قسمت از برنامه شما تزریق کند و باعث آسیب‌های جدی شود. این آسیب‌ها می‌تواند شامل سرقت اطلاعات، کنترل سیستم شما و یا حتی از کار انداختن کل برنامه باشد. به دلایل زیر به هیچ وجه از دستور eval() به‌صورت مستقیم استفاده نکنید:

  • امنیت پایین

eval() کدی را که به آن می‌دهید با همان سطح دسترسی اجرا می‌کند. اگر این کد بتواند تحت تاثیر فردی مخرب قرار بگیرد، ممکن است باعث اجرای کد مخرب روی دستگاه کاربر با سطح دسترسی صفحه وب یا افزونه شما شود. مهم‌تر اینکه اجازه دادن به کدهای شخص ثالث برای دسترسی به محدوده‌ فراخوانی eval() ممکن است منجر به حملاتی شود که متغیرهای لوکال را خوانده یا تغییر دهند.

  • سرعت پایین

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

  • عملکرد نامناسب

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

بهترین روش‌ ها برای استفاده ایمن از Eval

در وضعیت (Strict Mode) که برای افزایش امنیت و جلوگیری از اشتباهات رایج برنامه‌نویسی طراحی شده است، استفاده از کد eval مجاز نیست. با وجود این، اگر مجبور به استفاده از تابع Eval در جاوا اسکریپت هستید، از آن در حالت strict mode استفاده کنید. این کار باعث می‌شود تا Eval در یک محیط امن‌تر اجرا شود و خطرات امنیتی آن را کاهش دهد.

جایگزین‌ های Eval در جاوا اسکریپت

خبر خوش این است که جایگزین‌های امن‌تر و کارآمدتری برای تابع Eval در جاوا اسکریپت وجود دارند که نیاز شما به اجرای کدهای پویا را بدون به خطر انداختن امنیت و خوانایی کدتان برآورده می‌کنند. شما می‌توانید از روش‌های امن‌تر مانند گزینه‌های زیر استفاده کنید:

  • Function constructor

این روش به شما امکان می‌دهد تا با استفاده از کدهای نوشته‌شده در قالب رشته، به‌طور پویا تابع بسازید. مزیت اصلی این روش نسبت به Eval، امنیت بیشتر آن است. علاوه‌براین، کد شما را خواناتر می‌کند.

  • new Function()

این روش مشابه Function constructor است، اما امکانات بیشتری به شما می‌دهد. برای مثال، می‌توانید با استفاده از این روش، به آرگومان‌ها و متغیرهای محلی تابع دسترسی داشته باشید.

  • Web Workers

اگر به اجرای کدهای پویا نیاز دارید که بار پردازشی سنگینی دارند، از Web Workers می‌توانید استفاده کنید. این روش به شما امکان می‌دهد تا کدهای پویا را در یک بلوک جداگانه اجرا کنید. به این ترتیب، از کند شدن رابط کاربری اصلی جلوگیری می‌شود.

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

روش استفاده از eval()

در کد ارائه شده، متغیرهایی به نام x و y با مقادیر ۱۰ و ۲۰ تعریف شدند. سپس، یک رشته به نام text حاوی عبارت x * y ایجاد می‌شود. درنهایت، از تابع eval() برای اجرای کد موجود در text استفاده می‌شود.

 

let x = 10;
let y = 20;
let text = "x * y";
let result = eval(text);

 

جایگزین امن تر: استفاده از اپراتور ضرب

به جای استفاده از تابع Eval در جاوا اسکریپت برای این مثال، می‌توانید از اپراتور ضرب (*) برای محاسبه حاصل ضرب x و y به‌طور مستقیم استفاده کنید. این روش امن‌تر و خواناتر است.

 

let x = 10;
let y = 20;
let result = x * y;

 

همانطور که می‌بینید، نتیجه هر دو کد یکسان است.

کلام پایانی راجع به Eval در جاوا اسکریپت

تابع Eval در جاوا اسکریپت ممکن است در نگاه اول ابزاری قدرتمند و جذاب به‌نظر برسد، اما خطرات امنیتی و خوانایی ضعیف کد، آن را به گزینه‌ای نامناسب برای اکثر برنامه‌نویسان تبدیل کرده است. خوشبختانه، جایگزین‌های امن و کارآمدی مانند Function constructor ،new Function و استفاده از Eval در حالت Strict وجود دارند که به امنیت و خوانایی کدتان کمک کنند. بنابراین، اگر دنبال راهکار امن و کارآمدتر هستید، بهتر است سراغ جایگزین‌های قدرتمند و امن Eval بروید.

چه رتبه ای می‌دهید؟

میانگین ۰ / ۵. از مجموع ۰

اولین نفر باش

گوش به زنگ یلدا
title sign
معرفی نویسنده
تیم فنی نیک آموز
مقالات
401 مقاله توسط این نویسنده
محصولات
0 دوره توسط این نویسنده
تیم فنی نیک آموز
title sign
دیدگاه کاربران