وظيفة التقييم بسيطة جدًا في الواقع، وهي تمرير سلسلة إلى مترجم JS، وسيقوم مترجم Javascript بترجمة السلسلة إلى كود Javascript وتنفيذها.
خذ أبسط مثال:
انسخ رمز الكود كما يلي:
<نوع البرنامج النصي = "نص/جافا سكريبت">
eval("تنبيه(1+1)");
البرنامج النصي>
الأمر بسيط للغاية، قم بتفسير السلسلة إلى كود JS وتنفيذها، وسينبثق الرقم 2.
وبطبيعة الحال، المثال أعلاه هو مجرد لعبة، ولن يكون أحد غبيا بما فيه الكفاية لاستخدامها في الممارسة العملية. أعتقد أن الطريقة الأساسية لاستخدام وظيفة التقييم هي في DOM، على سبيل المثال، إذا كان لدينا div1 وdiv2 وdiv3، فلا توجد طريقة للحصول على المعرف الخاص بنا عند استخدام document.getElementByID. لذا فإن أبسط طريقة هي القيام بذلك استخدامه في حلقة استخدم eval لربط مثل هذا البرنامج. على سبيل المثال:
انسخ رمز الكود كما يلي:
<نوع البرنامج النصي = "نص/جافا سكريبت">
لـ (var حلقة = 1؛ حلقة < 10؛ حلقة ++) {
eval('document.getElementById("div"+loop).innerHTML="123"');
}
البرنامج النصي>
بعد الحديث عن الاستخدام الأساسي، أعتقد أن الجميع ما زالوا مهتمين بهذه الوظيفة. إذا كانت هذه الوظيفة لها استخدامات قليلة فقط، فستكون مملة للغاية. ثم دعونا نلقي نظرة على وظيفة eval () شيئًا فشيئًا.
لنبدأ بنطاق التقييم وننظر إلى هذه الوظيفة:
انسخ رمز الكود كما يلي:
<نوع البرنامج النصي = "نص/جافا سكريبت">
eval("var i=3");
تنبيه (ط)؛
البرنامج النصي>
الكود بسيط للغاية، والنتيجة يمكن أن تظهر 3. بعد ذلك، قارن هذا الكود:
انسخ رمز الكود كما يلي:
<نوع البرنامج النصي = "نص/جافا سكريبت">
اختبار فار = الوظيفة () {
eval("var i=3");
تنبيه (ط)؛
}
امتحان()؛
تنبيه (ط)؛
البرنامج النصي>
والنتيجة هي أن 3 ينبثق أولا، ثم غير محدد.
لذا اشرح: الكود الذي يتم تنفيذه ديناميكيًا بواسطة وظيفة eval() لا ينشئ نطاقًا جديدًا، ويتم تنفيذ الكود الخاص به في النطاق الحالي. بمعنى آخر، يمكن للدالة eval() أيضًا استخدام هذا الوسيط والكائنات الأخرى في النطاق الحالي.
في IE، يتم دعم وظيفة مشابهة جدًا لـ eval(): execScript(). يمكننا كتابة رمز بسيط.
انسخ رمز الكود كما يلي:
<نوع البرنامج النصي = "نص/جافا سكريبت">
اختبار فار = الوظيفة () {
execScript("var i=3");
تنبيه (ط)؛
}
امتحان()؛
تنبيه (ط)؛
البرنامج النصي>
ونتيجة لذلك، ظهرت 3s وهذا يوضح أيضًا خصائص وظيفة execScript، وهي تشبه في المقام الأول eval، ويمكنها تفسير السلاسل في كود JS وتنفيذها، ولكن نطاقها ليس هو النطاق الحالي النطاق العالمي. عندما نجرب الكود أعلاه على Firefox وGoogle Chrome: نجد أن الكود الموجود على execScript غير صالح على Firefox، مما يوضح أيضًا وجود مشكلة في توافق المتصفح مع كود execScript.
ثم يطرح السؤال كيف يمكننا الجمع بين "مزايا" هاتين الوظيفتين، أي التوافق العالمي + المتصفح. لقد بحثت في الإنترنت ولخصته بنفسي، والذي ربما يكون على النحو التالي:
انسخ رمز الكود كما يلي:
<نوع البرنامج النصي = "نص/جافا سكريبت">
فار StrongEval = الوظيفة (الكود) {
إذا (window.navigator.userAgent.indexOf("MSIE") >= 1) {
execScript(code);
}
إذا (window.navigator.userAgent.indexOf("Firefox") >= 1) {
window.eval(code);
}
آخر {
execScript(code);
}
};
اختبار فار = الوظيفة () {
StrongEval("var i=3");
}
امتحان()؛
تنبيه (ط)؛
البرنامج النصي>
بهذه الطريقة، يمكن أن يكون متوافقًا تمامًا مع FF وIE. الرمز الأساسي هو أن eval وwindow.eval ليسا متكافئين في FF.
بالإضافة إلى ذلك، يمكننا أيضًا استخدام eval+with لتحقيق بعض الحيل الغريبة.
بشكل عام يمكننا كتابة التعليمات البرمجية مثل هذا:
انسخ رمز الكود كما يلي:
فار أوبج = وظيفة () {
this.a = 1;
this.b = 2;
this.c = 5;
هذا.متعة = وظيفة () {
this.c = this.a + this.b;
}
};
var o = new obj();
o.fun();
تنبيه (أوك)؛
أو هذا:
انسخ رمز الكود كما يلي:
فار أوبج = {
ج: 1،
ب: 2،
ج: 5،
متعة: وظيفة () {
this.c = this.a + this.b;
}
}
أو هذا:
انسخ رمز الكود كما يلي:
فار أوبج = وظيفة () {
this.a = 1;
this.b = 2;
this.c = 5;
};
obj.prototype.fun = الوظيفة () {
this.c = this.a + this.b;
}
var o = new obj();
o.fun();
تنبيه (أوك)؛
مهما حدث، هل سئمت من هذا الشعور؟ ثم دعونا نتبع نهجًا مختلفًا تمامًا، بحيث يكون أكثر راحة للحواس على الأقل.
انسخ رمز الكود كما يلي:
<نوع البرنامج النصي = "نص/جافا سكريبت">
فار funtemp = وظيفة () {
ج = أ + ب؛
}
فار أوبج = {
ج: 1،
ب: 2،
ج: 5
};
فار متعة؛
مع (الكائن) {
eval("fun =" + funtemp);
}
هزار()؛
تنبيه (obj.c)؛
البرنامج النصي>
هذا المنتج قسري جدًا وجيد جدًا، ولن نناقش ما إذا كان يبدو مريحًا أم لا. دعونا نناقش مثل هذا الوضع.
انسخ رمز الكود كما يلي:
<النص البرمجي>
varDBCommon = الوظيفة () {
تنبيه ("1.")؛
تنبيه ("2.")؛
تنبيه ("3.")؛
تنبيه("4.");
تنبيه("5.");
}
فار SQLServerCommon = {
CreateConnection: function () { تنبيه ("إنشاء اتصال SQL Server" })؛
OpenConnection: function () { تنبيه ("فتح اتصال SQL Server" })؛
CreateCommand: function () { تنبيه ("إنشاء أمر SQL Server" })؛
ExcuteCommand: function () { تنبيه ("تنفيذ أمر خادم DSQL" })؛
CloseConnection: function () { تنبيه ("إغلاق اتصال SQL Server" })؛
};
فار أوراكل كومون = {
إنشاء اتصال: وظيفة () { تنبيه ("إنشاء اتصال أوراكل" })؛
OpenConnection: function () { تنبيه ("فتح اتصال أوراكل" })؛
CreateCommand: function () { تنبيه ("إنشاء أمر ¨Oracle" })؛
ExcuteCommand: function () { تنبيه ("تنفيذ أمر DOracle" })؛
CloseConnection: function () { تنبيه ("إغلاق؟ اتصال أوراكل" })؛
};
مع (SQLServerCommon) {
eval("forSQLServer=" + DBCommon);
}
مع (أوراكلكومون) {
eval("forOracle=" + DBCommon);
}
forSQLServer();
forOracle();
البرنامج النصي>
هل يمكننا التفكير في هذا كنمط أسلوب قالب بسيط؟ الكالينجيون. يمكننا أيضًا استدعاء هذا باستخدام eval وwith لتغيير سياق الوظيفة.
ولكن مرة أخرى، نادرًا ما يتم استخدام Eval في المواقف العامة، ويمكننا تجنب استخدامه تمامًا.