سؤال

أنا أكتب بعض رمز JavaScript لتحليل الوظائف التي يديرها المستخدم (لوظائف تشبه جدول البيانات). بعد تحليل الصيغة i استطاع تحويله إلى JavaScript وتشغيله eval() عليها لإعطاء النتيجة.

ومع ذلك ، لطالما ابتعدت عن الاستخدام eval() إذا كان بإمكاني تجنب ذلك لأنه شرير (وبشكل صحيح أو خطأ ، اعتقدت دائمًا أنه أكثر شرًا في JavaScript ، لأن المستخدم قد يتم تغييره من قبل المستخدم).

لذا ، عندما يكون من المقبول استخدامه؟

هل كانت مفيدة؟

المحلول

أود أن أتوقف لحظة لمعالجة فرضية سؤالك - أن eval () هو ""شر". الكلمة "شر"، كما هو مستخدم من قبل أشخاص لغة البرمجة ، يعني عادة" خطير "، أو على وجه التحديد" قادر على التسبب في الكثير من الأذى بأمر بسيط المظهر ". لذا ، متى يكون من المقبول استخدام شيء خطير؟ هو ، وعندما تتخذ الاحتياطات المناسبة.

إلى هذه النقطة ، دعونا نلقي نظرة على المخاطر في استخدام eval (). من المحتمل أن يكون هناك العديد من الأخطار الخفية الصغيرة تمامًا مثل كل شيء آخر ، لكن المخاطر الكبيرة - السبب في أن Eval () تعتبر شريرة - هما الأداء والحقن.

  • الأداء - eval () يدير المترجم/التحويل البرمجي. إذا تم تجميع التعليمات البرمجية الخاصة بك ، فهذا نجاح كبير ، لأنك بحاجة إلى استدعاء برنامج التحويل البرمجي المحتمل في منتصف وقت التشغيل. ومع ذلك ، لا يزال JavaScript في الغالب لغة تفسير ، مما يعني أن استدعاء eval () ليس أداءً كبيرًا في الحالة العامة (ولكن انظر ملاحظاتي المحددة أدناه).
  • حقن الكود - تقييم () يحتمل أن يقوم بتشغيل سلسلة من التعليمات البرمجية تحت امتيازات مرتفعة. على سبيل المثال ، لن يرغب البرنامج الذي يعمل كمسؤول/جذر أبدًا في تقييم () إدخال المستخدم ، لأن هذا الإدخال يمكن أن يكون "RM -RF/etc/file المهم" أو ما هو أسوأ. مرة أخرى ، لا يواجه JavaScript في المتصفح هذه المشكلة ، لأن البرنامج يعمل في حساب المستخدم الخاص على أي حال. يمكن أن تواجه JavaScript من جانب الخادم هذه المشكلة.

إلى حالتك المحددة. من ما أفهمه ، أنت تولد الأوتار بنفسك ، لذا افترض أنك حريص على عدم السماح لسلسلة مثل "RM -RF شيء مهم" ، لا يوجد خطر في حقن الرمز (ولكن يرجى تذكره ، إنه صعب جدا جدا لضمان هذا في الحالة العامة). أيضًا ، إذا كنت تعمل في المتصفح ، فإن حقن الكود يمثل خطرًا بسيطًا جدًا ، على ما أعتقد.

أما بالنسبة للأداء ، فسيتعين عليك الوزن مقابل سهولة الترميز. في رأيي أنه إذا كنت تقوم بتحليل الصيغة ، فقد تقوم أيضًا بحساب النتيجة أثناء التحليل بدلاً من تشغيل محلل آخر (واحد داخل eval ()). ولكن قد يكون من الأسهل رمز باستخدام eval () ، ومن المحتمل أن يكون ضرب الأداء غير ملحوظ. يبدو أن eval () في هذه الحالة ليس أكثر شريرًا من أي وظيفة أخرى يمكن أن توفر لك بعض الوقت.

نصائح أخرى

eval() ليس شرًا. أو ، إذا كان الأمر كذلك ، فهو شرير بنفس الطريقة التي تكون بها الانعكاس والملف/الشبكة I/O و Threading و IPC "شريرة" بلغات أخرى.

إذا، لغرضك, eval() أسرع من التفسير اليدوي ، أو يجعل الكود أكثر بساطة ، أو أكثر وضوحًا ... ثم يجب عليك استخدامه. إذا لم يكن كذلك ، فلا ينبغي لك ذلك. سهل هكذا.

عندما تثق في المصدر.

في حالة JSON ، يصعب العبث بالمصدر ، لأنه يأتي من خادم ويب تتحكم فيه. طالما أن JSON نفسها لا تحتوي على بيانات تم تحميلها للمستخدم ، فلا يوجد عيب كبير لاستخدام Eval.

في جميع الحالات الأخرى ، سأبذل قصارى جهدي لضمان مطابقة البيانات المقدمة من المستخدم مع قواعدي قبل إطعامها إلى eval ().

دعنا نحصل على أشخاص حقيقيين:

  1. يحتوي كل متصفح رئيسي الآن على وحدة تحكم مدمجة يمكن للمتسللين المحتملين استخدامها بوفرة لاستدعاء أي وظيفة بأي قيمة - لماذا يزعجهم استخدام بيان EVER - حتى لو استطاعوا؟

  2. إذا استغرق الأمر 0.2 ثانية لتجميع 2000 سطر من JavaScript ، فما هو تدهور أدائي إذا قمت بتقييم أربعة أسطر من JSON؟

حتى تفسير كروكفورد لـ "Eval Is Evil" ضعيف.

Eval is Evil ، وظيفة eval هي الميزة الأكثر إساءة استخدامها في JavaScript. تجنبه

كما يقول كروكفورد نفسه "هذا النوع من البيان يميل إلى توليد العصاب غير المنطقي. لا تشتريه".

يعد فهم التقييم ومعرفة متى قد يكون مفيدًا أكثر أهمية. على سبيل المثال ، تعد Eval أداة معقولة لتقييم استجابات الخادم التي تم إنشاؤها بواسطة البرنامج.

راجع للشغل: النموذج الأولي. js استدعاء eval مباشرة خمس مرات (بما في ذلك في evaljson () و evalresponse ()). يستخدم JQuery في Parsejson (عبر مُنشئ الوظيفة).

أنا أميل إلى المتابعة نصيحة كروكفورد إلى عن على eval(), وتجنبها تماما. حتى الطرق التي يبدو أنها لا تتطلب ذلك. على سبيل المثال ، setTimeout() يتيح لك تمرير وظيفة بدلاً من التقييم.

setTimeout(function() {
  alert('hi');
}, 1000);

حتى لو كان موثوق به المصدر ، لا أستخدمه ، لأن الرمز الذي تم إرجاعه بواسطة JSON قد يتم تشويهه ، والذي يمكن أن يفعل في أحسن الأحوال شيئًا متزعزعًا ، في أسوأ الأحوال ، يعرض شيئًا سيئًا.

eval هو مكمل للتجميع الذي يتم استخدامه في ترتيب الكود. من خلال التقدير ، أعني أنك تكتب مولد قالب مبسط يولد رمز قالب مفيد يزيد من سرعة التطوير.

لقد كتبت إطار عمل ، حيث لا يستخدم المطورون Eval ، لكنهم يستخدمون إطار عملنا وبالتالي يجب على هذا الإطار استخدام Eval لإنشاء قوالب.

يمكن زيادة أداء Eval باستخدام الطريقة التالية ؛ بدلاً من تنفيذ البرنامج النصي ، يجب عليك إرجاع وظيفة.

var a = eval("3 + 5");

يجب تنظيمه على أنه

var f = eval("(function(a,b) { return a + b; })");

var a = f(3,5);

التخزين المؤقت F بالتأكيد سيحسن السرعة.

كما يسمح Chrome بتصحيح هذه الوظائف بسهولة شديدة.

فيما يتعلق بالأمان ، فإن استخدام eval أو لا يحدث أي فرق ،

  1. بادئ ذي بدء ، يستدعي المتصفح البرنامج النصي بالكامل في صندوق الرمل.
  2. أي رمز شرير في التقييم ، هو الشر في المتصفح نفسه. يمكن للمهاجم أو أي شخص أن يضخ عقدة البرنامج النصي بسهولة في DOM والقيام بأي شيء إذا كان بإمكانه تقييم أي شيء. عدم استخدام eval لن يحدث أي فرق.
  3. إنه في الغالب أمان ضعيف من جانب الخادم ضار. يؤدي التحقق من صحة ملفات تعريف الارتباط السيئة أو تنفيذ ACL على الخادم إلى معظم الهجمات.
  4. كان هناك ثغرة جافا الأخيرة ، وما إلى ذلك في الكود الأصلي لجافا. تم تصميم JavaScript وهو مصمم لتشغيله في صندوق رمل ، في حين تم تصميم التطبيقات للركض خارج صندوق الرمل مع الشهادات ، وما إلى ذلك.
  5. إن كتابة رمز لتقليد المتصفح ليس صعبًا. كل ما عليك فعله هو تقديم طلب HTTP إلى الخادم مع سلسلة وكيل المستخدم المفضلة لديك. جميع أدوات الاختبار متصفحات وهمية على أي حال ؛ إذا أراد المهاجم أن يؤذيك ، فإن Eval هو الملاذ الأخير. لديهم العديد من الطرق الأخرى للتعامل مع الأمان من جانب الخادم.
  6. لا يمكن لـ Browser DOM الوصول إلى الملفات وليس اسم المستخدم. في الواقع لا شيء على الجهاز الذي يمكن أن يتيح Eval الوصول إليه.

إذا كان الأمان من جانب الخادم الخاص بك صلبًا بما يكفي لأي شخص للهجوم من أي مكان ، فلن تقلق بشأن EVER. كما ذكرت ، إذا لم يكن Eval موجودًا ، فإن المهاجمين لديهم العديد من الأدوات اللازمة للاختراق في الخادم الخاص بك بغض النظر عن إمكانية تقييم المستعرض الخاص بك.

تعد Eval جيدة فقط لإنشاء بعض القوالب للقيام بمعالجة السلسلة المعقدة بناءً على شيء لا يتم استخدامه مسبقًا. على سبيل المثال ، سأفضل

"FirstName + ' ' + LastName"

في مقابل

"LastName + ' ' + FirstName"

كاسم العرض الخاص بي ، والذي يمكن أن يأتي من قاعدة بيانات والذي لم يتم ترميزه.

رأيت أشخاصًا يدافعون عن عدم استخدام Eval ، لأن ذلك شر, ، لكنني رأيت نفس الأشخاص يستخدمون الوظيفة و setTimeOut ديناميكيًا ، لذلك يستخدمون EVER تحت القلنسوات

راجع للشغل ، إذا لم يكن صندوق الرمل الخاص بك متأكداً بما فيه الكفاية (على سبيل المثال ، إذا كنت تعمل على موقع يسمح بحقن الكود) ، فالإيصال هو آخر مشاكلك. قاعدة الأمن الأساسية هي ذلك الكل المدخلات شريرة ، ولكن في حالة JavaScript حتى يمكن أن تكون JavaScript نفسها شريرة ، لأنه في JavaScript ، يمكنك الكتابة فوق أي وظيفة ولا يمكنك التأكد من أنك تستخدمها الحقيقية ، لذا ، إذا بدأت رمز ضار قبلك ، فلن تتمكن من الوثوق بأي JavaScript في الوظيفة: د

الآن الخاتمة لهذا المنصب هي:

اذا أنت حقًا بحاجة إليه (80 ٪ من الوقت eval ليس مطلوب) وأنت متأكد من ما تفعله ، ما عليك سوى استخدام Eval (أو وظيفة أفضل ؛)) ، وتغطي الإغلاق و OOP 80/90 ٪ من الحالة التي يمكن استبدالها باستخدام نوع آخر من المنطق ، الباقي يتم إنشاء رمز تم إنشاؤه ديناميكيًا (على سبيل المثال ، إذا كنت تكتب مترجمًا) وكما قلت بالفعل تقييم JSON (هنا يمكنك استخدام التقييم الآمن Crockford ؛)))

عند تصحيح الأخطاء في Chrome (v28.0.1500.72) ، وجدت أن المتغيرات ليست ملزمة بالإغلاق إذا لم يتم استخدامها في وظيفة متداخلة تنتج الإغلاق. أعتقد ، هذا تحسين محرك JavaScript.

لكن: متى eval() يستخدم داخل وظيفة تسبب الإغلاق ، الكل ترتبط متغيرات الوظائف الخارجية بالإغلاق ، حتى لو لم يتم استخدامها على الإطلاق. إذا كان لدى شخص ما الوقت لاختبار ما إذا كان يمكن إنتاج تسريبات الذاكرة بذلك ، فيرجى ترك تعليق أدناه.

هذا هو رمز الاختبار الخاص بي:

(function () {
    var eval = function (arg) {
    };

    function evalTest() {
        var used = "used";
        var unused = "not used";

        (function () {
            used.toString();   // Variable "unused" is visible in debugger
            eval("1");
        })();
    }

    evalTest();
})();

(function () {
    var eval = function (arg) {
    };

    function evalTest() {
        var used = "used";
        var unused = "not used";

        (function () {
            used.toString();   // Variable "unused" is NOT visible in debugger
            var noval = eval;
            noval("1");
        })();
    }

    evalTest();
})();

(function () {
    var noval = function (arg) {
    };

    function evalTest() {
        var used = "used";
        var unused = "not used";

        (function () {
            used.toString();    // Variable "unused" is NOT visible in debugger
            noval("1");
        })();
    }

    evalTest();
})();

ما أود أن أشير إليه هنا هو أن التقييم () يجب ألا يشير بالضرورة إلى الأم eval() وظيفة. كل هذا يتوقف على اسم الوظيفة. لذلك عند الاتصال بالمواطن eval() مع اسم الاسم المستعار (قل var noval = eval; ثم في وظيفة داخلية noval(expression);) ثم تقييم expression قد تفشل عندما يشير إلى المتغيرات التي يجب أن تكون جزءًا من الإغلاق ، ولكنها في الواقع ليست كذلك.

تشرح Microsoft سبب بطيئة التقييم () في متصفحها على مدونة IE ، IE+JavaScript Performance توصيات الجزء 2: عدم الكفاءة في رمز JavaScript.

المثيل الوحيد الذي يجب أن تستخدمه في eval () هو عندما تحتاج إلى تشغيل JS الديناميكي أثناء الطيران. أنا أتحدث عن JS التي تقوم بتنزيلها بشكل غير متزامن من الخادم ...

... و 9 مرات من 10 يمكنك تجنب القيام بذلك بسهولة عن طريق إعادة البناء.

لا بأس في استخدامه إذا كان لديك تحكم كامل في الكود الذي يتم تمريره إلى eval وظيفة.

eval نادرا ما يكون الاختيار الصحيح. على الرغم من أنه قد يكون هناك العديد من الحالات التي يمكنك فيها تحقيق ما تحتاج إلى إنجازه من خلال تسلسل البرنامج النصي معًا وتشغيله على الطيران ، فإنك عادة ما يكون لديك تقنيات أكثر قوة وقابلة للصيانة تحت تصرفك: تدوين المباراة الترابطية (obj["prop"] بالضبط مثل obj.prop) ، الإغلاق ، التقنيات الموجهة للكائنات ، التقنيات الوظيفية - استخدمها بدلاً من ذلك.

بقدر ما يذهب نص العميل ، أعتقد أن مسألة الأمان هي نقطة نقاش. كل شيء يتم تحميله في المتصفح يخضع للتلاعب ويجب معاملته على هذا النحو. لا يوجد أي خطر في استخدام عبارة eval () عندما تكون هناك طرق أسهل بكثير لتنفيذ رمز JavaScript و/أو معالجة الكائنات في DOM ، مثل شريط عنوان URL في متصفحك.

javascript:alert("hello");

إذا أراد شخص ما التلاعب بـ DOM ، فأنا أقول يتأرجح. يجب أن يكون الأمان لمنع أي نوع من الهجوم دائمًا مسؤولية تطبيق الخادم ، الفترة.

من وجهة نظر براغماتية ، لا توجد فائدة لاستخدام eval () في موقف يمكن فيه القيام بالأمور على خلاف ذلك. ومع ذلك ، هناك حالات محددة يجب أن تستخدم فيها تقييم. عندما يكون الأمر كذلك ، يمكن القيام به بالتأكيد دون أي خطر في تفجير الصفحة.

<html>
    <body>
        <textarea id="output"></textarea><br/>
        <input type="text" id="input" />
        <button id="button" onclick="execute()">eval</button>

        <script type="text/javascript">
            var execute = function(){
                var inputEl = document.getElementById('input');
                var toEval = inputEl.value;
                var outputEl = document.getElementById('output');
                var output = "";

                try {
                    output = eval(toEval);
                }
                catch(err){
                    for(var key in err){
                        output += key + ": " + err[key] + "\r\n";
                    }
                }
                outputEl.value = output;
            }
        </script>
    <body>
</html>

متى يكون eval () eval () JavaScript ليس الشر؟

أحاول دائما يثبط عن استخدام eval. دائما تقريبا ، يتوفر حل أكثر نظافة وقابل للصيانة. تقييم ليس هناك حاجة حتى لحلية JSON. تقييم يضيف إلى الجحيم الصيانة. ليس من دون سبب ، فإنه يعبّر من قبل الماجستير مثل دوغلاس كروكفورد.

لكنني وجدت مثالًا واحدًا عند ذلك يجب ان يكون تستخدم:

عندما تحتاج إلى تمرير التعبير.

على سبيل المثال ، لدي وظيفة تقوم ببناء عام google.maps.ImageMapType اعترض بالنسبة لي ، لكنني بحاجة إلى إخبارها بالوصفة ، كيف يجب أن تبني عنوان URL للبلاط من zoom و coord المعلمات:

my_func({
    name: "OSM",
    tileURLexpr: '"http://tile.openstreetmap.org/"+b+"/"+a.x+"/"+a.y+".png"',
    ...
});

function my_func(opts)
{
    return new google.maps.ImageMapType({
        getTileUrl: function (coord, zoom) {
            var b = zoom;
            var a = coord;
            return eval(opts.tileURLexpr);
        },
        ....
    });
}

مثالي على الاستخدام eval: يستورد.

كيف يتم ذلك عادة.

var components = require('components');
var Button = components.Button;
var ComboBox = components.ComboBox;
var CheckBox = components.CheckBox;
...
// That quickly gets very boring

ولكن بمساعدة eval ودالة مساعد صغير تحصل على مظهر أفضل بكثير:

var components = require('components');
eval(importable('components', 'Button', 'ComboBox', 'CheckBox', ...));

importable قد يبدو (هذا الإصدار لا يدعم استيراد أعضاء الخرسانة).

function importable(path) {
    var name;
    var pkg = eval(path);
    var result = '\n';

    for (name in pkg) {
        result += 'if (name !== undefined) throw "import error: name already exists";\n'.replace(/name/g, name);
    }

    for (name in pkg) {
        result += 'var name = path.name;\n'.replace(/name/g, name).replace('path', path);
    }
    return result;
}

على جانب الخادم ، يكون Eval مفيدًا عند التعامل مع البرامج النصية الخارجية مثل SQL أو influxDB أو Mongo. حيث يمكن إجراء التحقق المخصص في وقت التشغيل دون إعادة نشر خدماتك.

على سبيل المثال خدمة الإنجاز مع البيانات الوصفية التالية

{
  "568ff113-abcd-f123-84c5-871fe2007cf0": {
    "msg_enum": "quest/registration",
    "timely": "all_times",
    "scope": [
      "quest/daily-active"
    ],
    "query": "`SELECT COUNT(point) AS valid from \"${userId}/dump/quest/daily-active\" LIMIT 1`",
    "validator": "valid > 0",
    "reward_external": "ewallet",
    "reward_external_payload": "`{\"token\": \"${token}\", \"userId\": \"${userId}\", \"amountIn\": 1, \"conversionType\": \"quest/registration:silver\", \"exchangeProvider\":\"provider/achievement\",\"exchangeType\":\"payment/quest/registration\"}`"
  },
  "efdfb506-1234-abcd-9d4a-7d624c564332": {
    "msg_enum": "quest/daily-active",
    "timely": "daily",
    "scope": [
      "quest/daily-active"
    ],
    "query": "`SELECT COUNT(point) AS valid from \"${userId}/dump/quest/daily-active\" WHERE time >= '${today}' ${ENV.DAILY_OFFSET} LIMIT 1`",
    "validator": "valid > 0",
    "reward_external": "ewallet",
    "reward_external_payload": "`{\"token\": \"${token}\", \"userId\": \"${userId}\", \"amountIn\": 1, \"conversionType\": \"quest/daily-active:silver\", \"exchangeProvider\":\"provider/achievement\",\"exchangeType\":\"payment/quest/daily-active\"}`"
  }
}

الذي يسمح بعد ذلك ،

  • الحقن المباشر للكائن/القيم من خلال السلسلة الحرفية في JSON ، مفيدة لترتيب النصوص

  • يمكن استخدامها كمقارنة ، على سبيل المثال ، نقوم بإعداد قواعد كيفية التحقق من صحة السعي أو الأحداث في CMS

يخدع هذا:

  • يمكن أن تكون أخطاء في الكود وتفكيك الأشياء في الخدمة ، إن لم يتم اختبارها بالكامل.

  • إذا كان بإمكان أحد المتسللين كتابة البرنامج النصي على نظامك ، فأنت مشدود إلى حد كبير.

  • تتمثل إحدى طرق التحقق من صحة البرنامج النصي الخاص بك في الحفاظ على تجزئة البرامج النصية الخاصة بك في مكان آمن ، حتى تتمكن من التحقق منها قبل الجري.

أعتقد أن أي حالات من الحالات التي يتم تبريرها ستكون نادرة. من المرجح أن تستخدمه التفكير في أنه مبرر أكثر مما تستخدمه عندما يكون ذلك في الحقيقة مبررة.

قضايا الأمن هي الأكثر شهرة. ولكن كن أيضًا على دراية بأن JavaScript تستخدم مجموعة JIT وهذا يعمل بشكل سيء للغاية مع Eval. يشبه Eval إلى حد ما الصندوق الأسود للمترجم ، ويجب أن يكون JavaScript قادرًا على التنبؤ بالدولة في وقت مبكر (إلى حد ما) من أجل تطبيق تحسينات الأداء بأمان وصحيح. في بعض الحالات ، يمكن أن يؤثر تأثير الأداء على التعليمات البرمجية الأخرى خارج Eval.

إذا كنت تريد أن تعرف أكثر:https://github.com/getify/you-dont-know-js/blob/master/scope٪20٪26٪20Closures/Ch2.md#eval

فقط أثناء الاختبار ، إن أمكن. لاحظ أيضًا أن eval () أبطأ بكثير من غيرها من المقيمين JSON المتخصصة.

رمز الجيل. لقد كتبت مؤخرًا مكتبة تسمى Hyperbars الذي يسد الفجوة بين الافتراضية و المقاود. يقوم بذلك عن طريق تحليل قالب المقاود وتحويله إلى فرط. يتم إنشاء HyperScript كسلسلة أولاً وقبل إعادتها ، eval() لتحويله إلى رمز قابل للتنفيذ. لقد وجدت eval() في هذا الموقف بالذات عكس الشر تمامًا.

أساسا من

<div>
    {{#each names}}
        <span>{{this}}</span>
    {{/each}}
</div>

الى هذا

(function (state) {
    var Runtime = Hyperbars.Runtime;
    var context = state;
    return h('div', {}, [Runtime.each(context['names'], context, function (context, parent, options) {
        return [h('span', {}, [options['@index'], context])]
    })])
}.bind({}))

اداء ال eval() ليست مشكلة في مثل هذا الموقف أيضًا لأنك تحتاج فقط إلى تفسير السلسلة التي تم إنشاؤها مرة واحدة ثم إعادة استخدام الإخراج القابل للتنفيذ عدة مرات.

يمكنك أن ترى كيف تم تحقيق توليد الكود إذا كنت فضوليًا هنا.

لا يوجد سبب لعدم استخدام eval () طالما يمكنك التأكد من أن مصدر الرمز يأتي منك أو للمستخدم الفعلي. على الرغم من أنه يمكنه معالجة ما يتم إرساله إلى وظيفة eval () ، فإن هذه ليست مشكلة أمان ، لأنه قادر على معالجة الكود المصدري لموقع الويب وبالتالي يمكنه تغيير رمز JavaScript نفسه.

لذلك ... متى لا تستخدم eval ()؟ لا ينبغي استخدام eval () فقط عندما تكون هناك فرصة لتغيير طرف ثالث. مثل اعتراض الاتصال بين العميل والخادم الخاص بك (ولكن إذا كانت هذه مشكلة استخدم HTTPS). يجب ألا تقوم بتقييم () للحصول على رمز التحليل الذي كتبه آخرون كما في المنتدى.

إذا كان هناك حاجة حقا alivence ليست شريرة. لكن 99.9 ٪ من استخدامات eval التي تتعثر فيها ليس مطلوب (لا يشمل setTimeout الأشياء).

بالنسبة لي ، فإن الشر ليس أداءًا أو حتى مشكلة أمنية (حسنًا ، بشكل غير مباشر). كل هذه الاستخدامات غير الضرورية لإثبات إضافة إلى جحيم الصيانة. يتم التخلص من أدوات إعادة التجهيز. البحث عن الكود صعب. الآثار غير المتوقعة لتلك evals هي الفيلق.

اعتقادي هو أن Eval هي وظيفة قوية للغاية لتطبيقات الويب من جانب العميل وآمنة ... آمنة مثل JavaScript ، والتي ليست كذلك. :-) مشكلات الأمان هي في الأساس مشكلة من جانب الخادم لأنه ، الآن ، مع أداة مثل Firebug ، يمكنك مهاجمة أي تطبيق JavaScript.

Eval مفيد لتوليد الكود عندما لا يكون لديك وحدات الماكرو.

على سبيل المثال (غبي) ، إذا كنت تكتب Brainfuck برنامج التحويل البرمجي ، ربما ترغب في إنشاء وظيفة تنفذ تسلسل التعليمات كسلسلة ، وتقييمها لإرجاع وظيفة.

عندما تقوم بتحليل بنية JSON مع وظيفة تحليل (على سبيل المثال ، jQuery.Parsejson) ، فإنها تتوقع بنية مثالية لملف JSON (كل اسم خاصية في عروض أسعار مزدوجة). ومع ذلك ، جافا سكريبت أكثر مرونة. لذلك ، يمكنك استخدام eval () لتجنب ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top