Чому використання функції JavaScript eval погана ідея?


534

Функція eval - це потужний і простий спосіб динамічного генерування коду, тож які застереження?



5
Як зазначено в moduscreate.com/javascript-performance-tips-tricks - (нова функція (str)) () є більш ефективною, ніж eval (str). Просто мої 2 копійки :)
Grgur

3
мабуть, новий fcuntion (a) на 67% повільніше, ніж eval (a) на хромі
що таке сон

для мене нові функції (а) на 80% повільніше, останній хром на ОСХ
Джон Сміт,

3
Я додав статичну функцію, просто для порівняння продуктивності. jsperf.com/eval-vs-new-function/2
Nepoxx

Відповіді:


386
  1. Неправильне використання eval відкриває ваш код для ін'єкційних атак

  2. Налагодження може бути складнішим (без номерів рядків тощо)

  3. Код eval'd виконується повільніше (немає можливості компілювати / кешувати код eval'd)

Редагувати: Як в коментарях зазначає @Jeff Walden, сьогодні №3 є менш правдивим, ніж це було у 2008 році. Однак, хоча може відбуватися кешування скомпільованих сценаріїв, це обмежується лише сценаріями, які повторюються без змін. Більш вірогідний сценарій полягає в тому, що ви є сценаріями eval'ing, які щоразу зазнавали незначних змін і не могли бути кешовані. Скажімо, що ДЕЯКІЙ код eval'd виконується повільніше.


2
@JeffWalden, чудовий коментар. Я оновив свою посаду, хоча розумію, що минуло року, коли ви опублікували повідомлення. Xnzo72, якби ти дещо кваліфікував свій коментар (як це робив Джефф), я, можливо, зможу погодитися з тобою. Джефф вказав на ключ: "Овалювання одного і того ж рядка кілька разів може уникнути розбору накладних даних". Як це є, ви просто помиляєтесь; №3 справедливо для багатьох сценаріїв.
Prestaul

7
@Prestaul: Оскільки передбачуваний зловмисник може просто використовувати будь-який інструмент розробника для зміни JavaScript у клієнті, чому ви кажете, що Eval () відкриває ваш код для ін'єкційних атак? Ще не відкрито? (Я звичайно кажу про клієнтський JavaScript)
Едуардо Молтені

60
@EduardoMolteni, ми не піклуємося (і справді не можемо перешкодити) користувачам виконувати js у власних браузерах. Атаки, яких ми намагаємося уникнути, - це коли значення, що надаються користувачем, зберігаються, а потім їх розміщують у javascript та eval'd. Наприклад, я можу встановити своє ім’я користувача: badHackerGuy'); doMaliciousThings();а якщо ви візьмете моє ім’я користувача, сформулюйте його в якийсь сценарій і оцініть його в інших браузерах, то я можу запускати будь-який javascript, який я хочу на своїх машинах (наприклад, змушувати їх ставити +1 до моїх публікацій, розмістити свої дані на моєму сервері тощо)
Prestaul

3
Загалом, номер 1 справедливий для багатьох, якщо не більшості функціональних дзвінків. eval () не слід виокремлювати та уникати досвідчених програмістів, лише тому, що недосвідчені програмісти зловживають цим. Однак досвідчені програмісти часто мають кращу архітектуру в своєму коді, і eval () рідко буде потрібно або навіть замислюватися завдяки цій кращій архітектурі.
frodeborli

4
@TamilVendhan Звичайно, ви можете поставити точки прориву. Ви можете отримати доступ до віртуального файлу, створеного Chrome для кодованого вами ейла, додавши debugger;заяву до вихідного коду. Це зупинить виконання вашої програми в цьому рядку. Потім після цього ви можете додати точки налагодження налагодження, як це був лише інший файл JS.
Сід

346

eval не завжди є злом. Бувають випадки, коли це цілком доречно.

Однак зараз eval і історично масово переживають люди, які не знають, що роблять. Це, на жаль, включає людей, які пишуть підручники JavaScript, а в деяких випадках це дійсно може мати наслідки для безпеки - або, що найчастіше, прості помилки. Отже, чим більше ми можемо зробити, щоб кинути знак питання над eval, тим краще. Кожен раз, коли ви використовуєте eval, вам потрібно з розумом перевірити, що ви робите, тому що, швидше за все, ви можете зробити це кращим, безпечнішим і чистішим способом.

Щоб навести занадто типовий приклад, встановити колір елемента з ідентифікатором, збереженим у змінній "картопля":

eval('document.' + potato + '.style.color = "red"');

Якби автори цього виду коду мали уявлення про основи роботи об’єктів JavaScript, вони зрозуміли б, що квадратні дужки можуть використовуватися замість буквальних точок-імен, що заперечує необхідність eval:

document[potato].style.color = 'red';

... що набагато простіше читати, а також менш потенційно баггі.

(Але тоді хтось, хто / насправді / знав, що вони роблять, скаже:

document.getElementById(potato).style.color = 'red';

що є більш надійним, ніж хитрий старий трюк доступу до елементів DOM прямо з об’єкта документа.)


82
Хм, напевно, мені пощастило, коли я вперше вивчив JavaScript. Я завжди використовував "document.getElementById" для доступу до DOM; за іронією долі, я робив це лише в той час, тому що я не мав уявлення, як об’єкти працювали в JavaScript ;-)
Майк Спросс

5
згоден. Іноді eval нормально, наприклад, для відповідей JSON з веб-сервісів
scietbi

40
@schoetbi: Чи не слід використовувати JSON.parse()замість eval()JSON?
nyuszika7h

4
@bobince code.google.com/p/json-sans-eval працює у всіх браузерах, як і github.com/douglascrockford/JSON-js . Дай Крокфорд json2.js використовує eval всередині, але з чеками. Крім того, він сумісний вперед із вбудованою підтримкою браузера для JSON.
Мартійн

8
@bobince Існує щось, що називається функцією виявлення функцій та поліфілів для обробки відсутніх бібліотек JSON та інших речей (дивіться на modernizr.com )
MauganRa

37

Я вважаю, це тому, що він може виконувати будь-яку функцію JavaScript з рядка. Використовуючи це, людям стає простіше вводити в програму негідний код.


5
Яка альтернатива тоді?
модернізується

5
Дійсно, альтернатива - це просто написати код, який цього не вимагає. Крокфорд розглядає це питання, і якщо вам потрібно це використати, він майже говорить, що його недолік у дизайні програми і його потрібно переробити. По правді кажучи, я згоден і з ним. JS за всіма вадами є дійсно гнучким і дозволяє багато місця зробити його гнучким.
kemiller2002

3
Неправда, у більшості фреймворків є метод розбору JSON, і якщо ви не використовуєте фреймворк, ви можете використовувати JSON.parse (). Більшість браузерів підтримує це, і якщо ви справді перебуваєте в крайній мірі, ви можете написати парсер для JSON досить легко.
kemiller2002

6
Я не купую цей аргумент, тому що вже вводити негідний код у додаток Javascript просто. У нас є консолі браузера, розширення скриптів тощо ... Кожен фрагмент коду, надісланий клієнтові, необов'язковий для виконання клієнтом.
користувач2867288

6
Справа в тому, що мені простіше вводити код у ваш браузер. Скажімо, ви використовуєте eval у рядку запиту. Якщо я обману вас, натиснувши посилання, яке переходить на цей сайт із доданою моєю рядком запитів, я виконав свій код на вашій машині з повним дозволом браузера. Я хочу ввести в журнал все, що ви вводите на цьому веб-сайті, і надіслати його мені? Зроблено і ніякого способу зупинити мене, тому що при виконанні eval браузер надає йому найвищі повноваження.
kemiller2002

27

На думку спадають два моменти:

  1. Безпека (але поки ви створюєте рядок, який потрібно оцінювати самостійно, це може бути проблемою)

  2. Продуктивність: поки код, який потрібно виконати, невідомий, його неможливо оптимізувати. (про javascript та продуктивність, безумовно , презентація Стіва Йегге )


9
Чому безпека - це проблема, якщо клієнт так чи інакше може зробити з нашим кодом все, що він хоче? Greasemonkey?
Пол Бревчинський

2
@PaulBrewczynski, проблема безпеки з’являється, коли користувач A зберігає свою частину коду, щоб бути використаною, evalа потім цей маленький фрагмент коду працює у веб-переглядачі B
Феліпе Перейра

21

Передача користувача вводу до eval () - це ризик безпеки, але також кожне виклик eval () створює новий екземпляр інтерпретатора JavaScript. Це може бути ресурсна свиня.


27
За три роки, відколи я відповів на це, моє розуміння того, що відбувається, скажемо, поглибилося. Що насправді відбувається, це створюється новий контекст виконання. Дивіться dmitrysoshnikov.com/ecmascript/chapter-1-execution-contexts
Andrew Hedges

20

Як правило, це лише проблема, якщо ви передаєте вхід користувача eval.


16

В основному, це набагато складніше в обслуговуванні та налагодженні. Це як а goto. Ви можете використовувати його, але це ускладнює пошук проблем і важче для людей, яким, можливо, доведеться пізніше внести зміни.


Eval можна використовувати для заміни відсутніх функцій метапрограмування, як-от шаблони. Мені подобається компактний генератор набагато більше, ніж нескінченний список функцій за функціями.
слабенькапаза

Поки рядок не надходить від користувача або обмежується браузером, який ви можете. У JavaScript є багато можливостей метапрограмування, використовуючи такі речі, як зміна прототипів, obj [member], proxy, json.parse, вікно, функції декоратора (прислівники), де newf = decorator (oldf), функція вищого порядку, наприклад Array.prototype.map (f) , передаючи аргументи до інших функцій, аргументи ключових слів через {}. Чи можете ви сказати мені про випадки використання, коли ви не можете зробити це замість eval?
aoeu256

13

Слід пам’ятати, що ви часто можете використовувати eval () для виконання коду в іншому середовищі з обмеженим доступом - сайти соціальних мереж, які блокують певні функції JavaScript, іноді можна обдурити, розбивши їх у блоці eval -

eval('al' + 'er' + 't(\'' + 'hi there!' + '\')');

Тож якщо ви хочете запустити якийсь код JavaScript, де він інакше не може бути дозволений ( Myspace , я дивлюся на вас ...), то eval () може стати корисною хитрістю.

Однак, з усіх вищезгаданих причин, ви не повинні використовувати його для власного коду, де ви маєте повний контроль - це просто не потрібно, і краще перенести на полицю "хитрі JavaScript хакі".


1
Просто оновлення вищевказаного коду .. - там! - має бути в лапках, оскільки це рядок. eval ('al' + 'er' + 't (' + '"привіт там!"' + ')');
Махеш

2
[]["con"+"struc"+"tor"]["con"+"struc"+"tor"]('al' + 'er' + 't(\'' + 'hi there!' + '\')')()
Конрад Боровський

3
Так, були сайти соціальних мереж, які обмежували сповіщення (), але дозволяли eval () ?!
joshden

12

Якщо ви не дозволите eval () динамічному контенту (через cgi або вхід), він настільки ж безпечний і надійний, як і всі інші JavaScript на вашій сторінці.


Хоча це правда - якщо ваш вміст не динамічний, то яка причина взагалі використовувати для нього eval? Ви можете просто поставити код у функцію та назвати його замість цього!
Periata Breatta

Наприклад, для того, щоб проаналізувати значення, що повертається (як JSON, рядки, визначені сервером тощо), що надійшло від виклику Ajax.
Thevs

2
О Я бачу. Я б назвав це динамічним, тому що клієнт не знає заздалегідь, що вони є, але я бачу, що ви маєте на увазі зараз.
Periata Breatta

7

Поряд з рештою відповідей, я не думаю, що твердження eval можуть мати просунуте мінімізацію.


6

Це можливий ризик безпеки, він має інший обсяг виконання і є досить неефективним, оскільки створює абсолютно нове сценарій середовища для виконання коду. Дивіться тут для отримання додаткової інформації: eval .

Це дуже корисно, однак, і використання при помірності може додати багато хорошої функціональності.


5

Якщо ви не впевнені на 100%, що код, який оцінюється, отриманий з надійного джерела (зазвичай це ваша власна програма), то це надійний спосіб піддавати вашій системі напад сценаріїв між сайтом.


1
Тільки якщо захист вашого сервера відстійний. Клієнтська безпека - це дурниці.
подвійнийОкт

5

Я знаю, що це обговорення давнє, але мені дуже подобається такий підхід від Google і хотів поділитися цим почуттям з іншими;)

Інша справа, що чим краще ти отримуєш більше, тим більше намагаєшся зрозуміти, і нарешті ти просто не віриш, що щось добре чи погано тільки тому, що хтось так сказав :) Це дуже надихаюче відео, яке допомогло мені більше подумати над собою :) ДОБРІ ПРАКТИКИ хороші, але не використовуйте їх непомітно :)


1
Так. Я знайшов, поки що, принаймні, в Chrome, випадок використання, який здається більш ефективним. Запустіть RAF, який оцінює рядок у заданій змінній кожній ітерації. Використовуйте setInterval, щоб встановити лише ті графічно орієнтовані речі, як встановлення перетворень тощо у цьому рядку. Я спробував багато інших підходів, таких як прокручування функцій у масиві або використання змінної для встановлення лише перетворень для елементів, які змінюються, але поки що це здається найбільш ефективним. Коли справа доходить до анімації, найвірнішим стенд-тестом є ваші очі.
jdmayfield

5

Це не обов'язково так погано, якщо ви знаєте, в якому контексті ви його використовуєте.

Якщо ваша програма використовує eval()для створення об’єкта з якогось JSON, який повернувся з XMLHttpRequest на ваш власний сайт, створений вашим надійним кодом на стороні сервера, це, мабуть, не проблема.

Ненадійний JavaScript-код на стороні клієнта так чи інакше не може зробити. За умови, що справа, яку ви виконуєте eval(), походить з розумного джерела, у вас все добре.


3
Не використовується eval повільніше, ніж просто розбирати JSON?
Брендан Лонг

@Qix - запуск цього тесту в моєму браузері (Chrome 53) показує, що eval є дещо швидшим, ніж аналіз .
Periata Breatta

@PeriataBreatta Гм, дивно. Цікаво, чому. У той час я коментував, що це не так. Однак для Chrome не чутно, щоб у певних областях часу виконання від версії до версії дивні підвищення продуктивності.
Qix - МОНІКА ПОМИЛИЛА

Трохи старої нитки тут, але з того, що я прочитав - не стверджуючи, що я простежив її назад - JSON.parse насправді є вхідним на останньому етапі. Тож ефективність вимагає більше роботи / часу. Але безпечно, чому б не просто розібратися? eval - дивовижний інструмент. Використовуйте його для речей, у яких немає іншого шляху. Для передачі функцій через JSON є спосіб зробити це без eval. Цей другий параметр у JSON.stringify дозволяє поставити зворотний виклик для запуску, який ви можете перевірити через typeof, чи це функція. Потім отримайте .toString () функції. Про це є кілька хороших статей, якщо шукати.
jdmayfield


4

Якщо ви хочете, щоб користувач вводив деякі логічні функції і оцінював ІЛІ АБО, то функція JavaScript eval є ідеальною. Я можу прийняти дві струни і eval(uate) string1 === string2т.д.


Ви також можете використовувати функцію () {}, але будьте обережні, використовуючи їх на сервері, якщо ви не хочете, щоб користувачі захопили ваш сервер ха-ха-ха.
aoeu256

3

Якщо ви помітили використання коду eval () у своєму коді, запам'ятайте мантру "eval () - це зло".

Ця функція займає довільну рядок і виконує її як код JavaScript. Коли код, про який йде мова, заздалегідь відомий (не визначається під час виконання), немає підстав використовувати eval (). Якщо код динамічно генерується під час виконання, часто існує кращий спосіб досягти мети без eval (). Наприклад, краще та простіше використовувати позначення квадратних дужок для доступу до динамічних властивостей:

// antipattern
var property = "name";
alert(eval("obj." + property));

// preferred
var property = "name";
alert(obj[property]);

Використання eval()також має наслідки для безпеки, тому що ви можете виконувати код (наприклад, що надходить з мережі), який був підроблений. Це звичайний антипаттерн, коли стосується відповіді JSON на запит Ajax. У цих випадках краще використовувати вбудовані методи веб-переглядачів, щоб проаналізувати відповідь JSON, щоб переконатися, що вона безпечна та дійсна. Для браузерів, які не підтримують JSON.parse()вбудовану систему, ви можете використовувати бібліотеку з JSON.org.

Також важливо пам’ятати, що передавання рядків до setInterval(), setTimeout()і Function()конструктор здебільшого схоже на використання, eval()і тому його слід уникати.

За лаштунками JavaScript все ще повинен оцінити та виконати рядок, який ви передаєте як код програмування:

// antipatterns
setTimeout("myFunc()", 1000);
setTimeout("myFunc(1, 2, 3)", 1000);

// preferred
setTimeout(myFunc, 1000);
setTimeout(function () {
myFunc(1, 2, 3);
}, 1000);

Використання нового конструктора Function () подібне до eval () і до нього слід підходити обережно. Це може бути потужною конструкцією, але часто не використовується. Якщо ви абсолютно повинні використовувати eval(), ви можете замість цього використати нову функцію ().

Існує невелика потенційна вигода, оскільки код, оцінений у новій функції (), буде працювати в локальній області функцій, тому будь-які змінні, визначені з var у коді, що оцінюється, не стануть глобальними автоматично.

Інший спосіб запобігання автоматичних глобальних мереж - eval()перетворити виклик у негайну функцію.


Чи можете ви підказати, як я можу оцінити ім'я динамічної змінної локальної функції без eval? Функції Eval (і подібні до них) є останніми можливостями більшості мов, які їх містять, але іноді це необхідно. У випадку отримання імені динамічної змінної чи безпечніше якесь рішення? У будь-якому випадку, сам JavaScript не для реальної безпеки (сервер, очевидно, є основною захистом). Якщо вас цікавить, ось мій приклад використання eval, який я хотів би змінити: stackoverflow.com/a/48294208
Регулярний Joe

2

Крім можливих проблем із безпекою, якщо ви виконуєте код, поданий користувачем, більшість випадків існує кращий спосіб, який не передбачає повторного розбору коду при кожному його виконанні. Анонімні функції або властивості об'єкта можуть замінити більшість застосувань eval і набагато безпечніші та швидші.


2

Це може стати більшою проблемою, оскільки наступне покоління браузерів виходить з деяким смаком компілятора JavaScript. Код, виконаний через Eval, може не працювати так само, як і решта вашого JavaScript проти цих нових браузерів. Хтось повинен зробити якийсь профіль.


2

Це одна з хороших статей, яка розповідає про eval і як це не зло: http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderpted/

Я не кажу, що ви повинні вибігати і починати використовувати eval () скрізь. Насправді, дуже мало випадків корисного використання для запуску eval (). Однозначно виникають проблеми з чіткістю коду, налагоджуваністю і, безумовно, продуктивністю, яку не слід нехтувати. Але вам не варто боятися використовувати його, коли у вас є випадок, коли eval () має сенс. Спробуйте не використовувати його спочатку, але не дозволяйте нікому лякати вас, думаючи, що ваш код є більш крихким або менш захищеним, коли eval () використовується належним чином.


2

eval () дуже потужний і може використовуватися для виконання оператора JS або оцінки виразу. Але питання не стосується використання eval (), а давайте лише скажемо, як на рядок, на який ви працюєте з eval (), впливає зловмисна сторона. Зрештою, у вас буде запущений шкідливий код. З владою виходить велика відповідальність. Тож використовуйте його розумно - це ви використовуєте. Це не дуже пов’язано з функцією eval (), але ця стаття має досить гарну інформацію: http://blogs.popart.com/2009/07/javascript-injection-attacks/ Якщо ви шукаєте основи eval () дивіться тут: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval


2

У JavaScript Engine є ряд оптимізацій продуктивності, які він виконує на етапі компіляції. Деякі з них зводяться до того, щоб мати змогу фактично статично проаналізувати код під час його використання та заздалегідь визначити, де знаходяться всі декларації змінної та функції, щоб зайняти менше зусиль для вирішення ідентифікаторів під час виконання.

Але якщо двигун знайде в коді eval (..), він, по суті, повинен припустити, що все його усвідомлення місця розташування ідентифікатора може бути недійсним, оскільки він не може знати в той час, який саме код ви можете передати в eval (..) щоб змінити лексичну область чи вміст об'єкта, з яким ви можете перейти, щоб створити нову лексичну область, з якою слід звертатися.

Іншими словами, в песимістичному розумінні більшість тих оптимізацій, які вона зробила б, безглуздо, якщо є eval (..), тому вона просто не виконує оптимізації.

Це все пояснює.

Довідка:

https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#eval

https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#performance


Жоден движок javascript не може знайти та оцінити в коді зі 100% гарантією. Тому до цього він повинен бути готовий у будь-який час.
Джек Гіффін

2

Це не завжди погана ідея. Візьмемо для прикладу генерацію коду. Нещодавно я написав бібліотеку під назвою Hyperbars, яка усуває розрив між віртуальним домом та рульовим рулем . Це робиться шляхом аналізу шаблону рулі та перетворення його в гіперскрипт, який згодом використовується virtual-dom. Гіперскрипт генерується спочатку як рядок, а перед поверненням 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()не є проблемою в подібній ситуації, тому що вам потрібно лише один раз інтерпретувати згенеровану рядок, а потім багато разів використовувати повторно виконаний файл.

Ви можете побачити, як було досягнуто створення коду, якщо вам цікаво тут .


2

Я б сказав, що це неважливо, якщо ви використовуєте eval()javascript, який запускається в браузерах. * (Нюанс)

У всіх сучасних браузерах є консоль розробника, де ви можете в будь-якому випадку виконати довільний javascript, і будь-який напіврозумний розробник може переглядати ваш джерело JS і вводити в консоль розробника всі необхідні для нього шматочки.

* Поки кінцеві точки вашого сервера мають правильну перевірку та санітацію значень, що надаються користувачем, це не має значення, що аналізується та eval'd у вашому JavaScript-коді на стороні клієнта.

Якщо ви хочете запитати, чи підходить вона для використання eval()в PHP, відповідь " НІ" , якщо ви не додасте до списку жодних значень, які можуть бути передані вашій заяві eval.


не тільки є консоль розробника, ви також можете ввести javascript: код на панелі URL, щоб створити власну консоль розробника на сторінці, якщо такої немає, як це стосується старих браузерів IE та мобільних пристроїв.
Дмитро

1

Я не намагатимусь спростувати що-небудь сказане до цього, але я запропоную це використання eval (), яке (наскільки я знаю) неможливо зробити іншим способом. Напевно, є й інші способи кодування цього, і, ймовірно, способи його оптимізації, але це робиться на довгі руки і без жодних дзвінків для наочності, щоб проілюструвати використання eval, що насправді не має інших альтернатив. Тобто: динамічні (або точніше) програмно створені імена об’єктів (на відміну від значень).

//Place this in a common/global JS lib:
var NS = function(namespace){
    var namespaceParts = String(namespace).split(".");
    var namespaceToTest = "";
    for(var i = 0; i < namespaceParts.length; i++){
        if(i === 0){
            namespaceToTest = namespaceParts[i];
        }
        else{
            namespaceToTest = namespaceToTest + "." + namespaceParts[i];
        }

        if(eval('typeof ' + namespaceToTest) === "undefined"){
            eval(namespaceToTest + ' = {}');
        }
    }
    return eval(namespace);
}


//Then, use this in your class definition libs:
NS('Root.Namespace').Class = function(settings){
  //Class constructor code here
}
//some generic method:
Root.Namespace.Class.prototype.Method = function(args){
    //Code goes here
    //this.MyOtherMethod("foo"));  // => "foo"
    return true;
}


//Then, in your applications, use this to instantiate an instance of your class:
var anInstanceOfClass = new Root.Namespace.Class(settings);

EDIT: до речі, я б не пропонував (з усіх причин безпеки, зазначених до цього), щоб ви базували об'єкти на імені користувачів. Я не уявляю жодної вагомої причини, що ти хотів би це зробити. І все-таки подумав, що зазначу, що це не буде гарною ідеєю :)


3
це можна зробити за допомогою namespaceToTest[namespaceParts[i]], тут не потрібно eval, тому if(typeof namespaceToTest[namespaceParts[i]] === 'undefined') { namespaceToTest[namespaceParts[i]] = {};єдина різниця для користувачаelse namespaceToTest = namespaceToTest[namespaceParts[i]];
user2144406

1

Збір сміття

Збір сміття веб-переглядачів не має уявлення про те, чи зможе вилучений код вилучити з пам'яті, щоб він просто зберігався, поки сторінка не буде завантажена. Не надто погано, якщо ваші користувачі незабаром з’являться лише на вашій сторінці, але це може бути проблемою для веб-користувачів.

Ось сценарій для демонстрації проблеми

https://jsfiddle.net/CynderRnAsh/qux1osnw/

document.getElementById("evalLeak").onclick = (e) => {
  for(let x = 0; x < 100; x++) {
    eval(x.toString());
  }
};

Щось таке просто, як наведений вище код, спричиняє збереження невеликої кількості пам’яті, поки додаток не вмирає. Це гірше, коли скрипт, що ухиляється, є гігантською функцією, і викликається на інтервалі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.