في JavaScript ، يمكنك استخدام وظيفة eval () لتحليل رمز JavaScript في سلسلة وإرجاع نتيجة تنفيذ الكود المقابل:
نسخة الكود كما يلي:
console.log (eval ("42 * 2")) ؛ // 84
eval () هي في الأساس وظيفة كائن عالمي JavaScript. على سبيل المثال ، الرمز أعلاه يعادل:
نسخة الكود كما يلي:
console.log (this.eval ("42 * 2")) ؛ // 84
ومع ذلك ، عند استخدام عبارة eval () ، يتم اعتماد الطريقة الأولى المذكورة أعلاه بشكل عام ، أي تجاهل الكائن العالمي واستخدام eval () مباشرة.
استخدام eval ()
للسببين التاليين ، ما لم تكن في حاجة إليه حقًا ، يجب أن تحاول تجنب استخدام عبارة eval () في الكود الخاص بك:
1. من الناحية المنطقية ، يجب استخدام السلاسل لتخزين المحتوى والمعلومات أثناء تشغيل البرنامج ، بدلاً من تخزين منطق حساب معين.
2. نظرًا لأن المعلمة eval () عبارة عن سلسلة ، ولا يمكن أن تكون معجمية لقطعة من السلسلة ، لا يمكن لمترجم JavaScript تحسين عبارة استدعاء eval ().
قيمة إرجاع eval ()
تتبع قيمة إرجاع eval () القواعد التالية:
1. إذا كانت معلمة eval () ليست سلسلة ، فإن eval () ستعود مباشرة إلى المعلمة.
2. إذا كانت معلمة eval () عبارة عن سلسلة ، فإن Eval () تتوصل إلى السلسلة في الكود وتنفيذها ، وتُرجع نتيجة السطر الأخير من تنفيذ التعليمات البرمجية.
3. إذا كان لا يمكن تحليل السلسلة في رمز شرعي ، فسيقوم eval () بإلقاء خطأ في بناء الجملة.
4. إذا كان يمكن تحليل السلسلة في رمز قانوني ، ولكن تم الإبلاغ عن خطأ أثناء تنفيذ هذا الرمز ، فسيتم الإبلاغ عن الخطأ إلى بيان eval () وإلقاؤه بواسطة eval ().
نسخة الكود كما يلي:
console.log (eval ([1،2،3])) ؛ // [1 ، 2 ، 3]
console.log (typeof eval ([1،2،3])) ؛ // object
console.log (eval ("42 */2")) ؛ // syntaxerror
console.log (eval ("42 * 2 ؛ 22 * 3 ؛")) ؛ // 66. يعيد Eval نتيجة التعبير/البيان الأخير
console.log (eval ("null.toString ()")) ؛ // typeerror ، سيتم نشر استثناء في رمز eval-ed خارج eval ().
بيئة متغيرة
يحتوي eval () في JavaScript على ميزة مهمة: يمكن للرمز في سلسلة المعلمة eval () الوصول إلى المتغيرات في الكود الخارجي ، ويمكن أيضًا فضح المتغيرات التي تم إنشاؤها حديثًا في رمز سلسلة المعلمة إلى الرمز الخارجي. أي إذا كان من الممكن تحليل سلسلة المعلمة eval () قانونيًا ، فسيحل JS محل الكود المحسّن بالخط حيث يوجد eval ():
نسخة الكود كما يلي:
// بيئة متغيرة
var a = 108 ؛
console.log (eval ("function double (x) {return x*2 ؛} a = double (a)")) ؛
console.log (a) ؛ // 216
console.log (Double (33)) ؛ // 66
تجدر الإشارة إلى أن الشرط المسبق لتنفيذ الميزة أعلاه هو أن الكود في سلسلة المعلمة eval () يمكن تحليلها قانونًا. بالإضافة إلى تصحيح بناء جملة الكود ، يتطلب JS أيضًا أن يكون الكود في سلسلة المعلمة eval () "منظمًا ذاتيًا": يجب أن يكون الرمز منطقيًا فقط من حيث الرمز في سلسلة المعلمة. على سبيل المثال ، من المستحيل تمرير سلسلة مثل "العودة" ؛ إلى وظيفة eval ():
نسخة الكود كما يلي:
اختبار الوظيفة () {
var s = "test" ؛
eval ("return s ؛") ؛
}
Test () ؛ // syntaxerror: العودة ليس في الوظيفة
إذا كنت تستخدم وظيفة eval () مباشرة ، فإن المتغيرات التي يتم الوصول إليها بواسطة الكود في سلسلة المعلمة eval () هي تلك المتغيرات في الوظيفة التي توجد فيها عبارة eval () ، أي أن البيئة المتغيرة المستخدمة في دالة eval () هي "بيئة المتغير المحلي". إذا لم تستخدم وظيفة eval () مباشرة ، ولكن استخدم متغيرًا جديدًا يشير أيضًا إلى وظيفة eval () ، فإن المتغيرات التي يتم الوصول إليها بواسطة الكود في سلسلة المعلمة المقابلة هي متغيرات عالمية ، أي أن البيئة المتغيرة المستخدمة في وظيفة eval () هي "بيئة متغيرة عالمية":
نسخة الكود كما يلي:
// البيئة المتغيرة المحلية والبيئة المتغيرة العالمية
VAR المعاد تسميتها = eval ؛
var x = "Origin" ، y = "Origin" ؛
وظيفة f () {
var x = "new" ؛
eval ("x += 'change' ؛") ؛
إرجاع x ؛
}
وظيفة G () {
var y = "new" ؛
أعيد تسميته ("y += 'change' ؛") ؛
إرجاع y ؛
}
console.log (f () ، x) ؛ // newChanged Origin
console.log (g () ، y) ؛ // new OriginChanged
ومع ذلك ، تجدر الإشارة إلى أن السلوك في IE6 و 7 و 8 مختلف. في IE6 و 7 و 8 ، حتى لو تم إعادة تسمية وظيفة eval () ، لا تزال "البيئة المتغيرة المحلية" تستخدم.