ฟังก์ชั่น eval เป็นวิธีที่ทรงพลังและง่ายต่อการสร้างรหัสแบบไดนามิกดังนั้นคำเตือนคืออะไร
ฟังก์ชั่น eval เป็นวิธีที่ทรงพลังและง่ายต่อการสร้างรหัสแบบไดนามิกดังนั้นคำเตือนคืออะไร
คำตอบ:
การใช้eval ที่ไม่เหมาะสมจะเปิดรหัสของคุณสำหรับการโจมตีฉีด
การดีบักอาจท้าทายกว่า (ไม่มีหมายเลขบรรทัด ฯลฯ )
โค้ด eval'd รันช้าลง (ไม่มีโอกาสรวบรวม / แคชโค้ด eval'd)
แก้ไข: เนื่องจาก @Jeff Walden ชี้ให้เห็นในความคิดเห็น # 3 ในปัจจุบันมีความเป็นจริงน้อยกว่าในปี 2008 อย่างไรก็ตามในขณะที่การแคชของสคริปต์ที่รวบรวมอาจเกิดขึ้นสิ่งนี้จะถูก จำกัด เฉพาะสคริปต์ที่ไม่ถูกแก้ไขซ้ำ สถานการณ์ที่เป็นไปได้มากกว่าคือคุณกำลังตรวจสอบสคริปต์ที่ผ่านการแก้ไขเล็กน้อยในแต่ละครั้งและไม่สามารถแคชได้ สมมุติว่าบางรหัส eval'd รันช้ากว่า
badHackerGuy'); doMaliciousThings();
และถ้าคุณนำชื่อผู้ใช้ของฉันเชื่อมต่อลงในสคริปต์บางส่วนและประเมินผลในเบราว์เซอร์ของผู้อื่นฉันสามารถเรียกใช้จาวาสคริปต์ที่ฉันต้องการบนเครื่องของพวกเขา โพสต์ข้อมูลของพวกเขาไปยังเซิร์ฟเวอร์ของฉัน ฯลฯ )
debugger;
คำสั่งลงในซอร์สโค้ดของคุณ นี่จะหยุดการทำงานของโปรแกรมของคุณในบรรทัดนั้น หลังจากนั้นคุณสามารถเพิ่มจุดพักการดีบักได้เหมือนกับไฟล์ JS อื่น
eval ไม่ใช่ความชั่วร้ายเสมอไป มีหลายครั้งที่มันเหมาะสมอย่างสมบูรณ์แบบ
อย่างไรก็ตามการใช้ eval ในปัจจุบันและในอดีตมักใช้กันอย่างแพร่หลายโดยผู้ที่ไม่ทราบว่ากำลังทำอะไรอยู่ ซึ่งรวมถึงคนที่เขียนบทช่วยสอน JavaScript โชคไม่ดีและในบางกรณีสิ่งนี้อาจส่งผลต่อความปลอดภัยอย่างแน่นอน - หรือบ่อยครั้งกว่านั้นคือข้อบกพร่องอย่างง่าย ดังนั้นยิ่งเราสามารถทำเครื่องหมายคำถามเพื่อหลีกเลี่ยง eval ยิ่งดี เมื่อใดก็ตามที่คุณใช้ eval คุณต้องมีสติตรวจสอบสิ่งที่คุณทำเพราะโอกาสที่คุณจะทำได้ดีกว่าปลอดภัยกว่าและสะอาดกว่า
เพื่อให้เป็นตัวอย่างที่ธรรมดาเกินไปให้ตั้งค่าสีขององค์ประกอบที่มี id ที่เก็บอยู่ในตัวแปร 'potato':
eval('document.' + potato + '.style.color = "red"');
หากผู้เขียนรหัสประเภทข้างต้นมีเงื่อนงำเกี่ยวกับพื้นฐานของวิธีการทำงานของวัตถุ JavaScript พวกเขาจะรู้ว่าสามารถใช้วงเล็บเหลี่ยมแทนตัวอักษรชื่อจริงและตัดความต้องการ eval:
document[potato].style.color = 'red';
... ซึ่งง่ายต่อการอ่านและค่าบั๊กที่น้อยกว่า
(แต่แล้วบางคนที่ / จริง / รู้ว่าสิ่งที่พวกเขากำลังทำจะพูดว่า:
document.getElementById(potato).style.color = 'red';
ซึ่งเชื่อถือได้มากกว่าเคล็ดลับเก่า ๆ ที่หลบการเข้าถึงองค์ประกอบ DOM ตรงจากวัตถุเอกสาร)
JSON.parse()
แทนeval()
JSON เหรอ?
ฉันเชื่อว่าเป็นเพราะสามารถเรียกใช้ฟังก์ชัน JavaScript ใด ๆ จากสตริง การใช้มันทำให้ผู้คนสามารถฉีดรหัสโกงเข้าไปในแอปพลิเคชันได้ง่ายขึ้น
จุดสองจุดอยู่ในใจ:
ความปลอดภัย (แต่ตราบใดที่คุณสร้างสตริงเพื่อประเมินด้วยตัวคุณเองนี่อาจจะไม่ใช่ปัญหา)
ประสิทธิภาพการทำงาน: จนกว่าจะไม่ทราบรหัสที่จะดำเนินการจะไม่สามารถปรับให้เหมาะสมได้ (เกี่ยวกับจาวาสคริปต์และประสิทธิภาพการทำงานนำเสนออย่างแน่นอนของSteve Yegge )
eval
uated จากนั้นรหัสชิ้นส่วนเล็ก ๆ นั้นจะทำงานบนเบราว์เซอร์ B ของผู้ใช้
การส่งอินพุตของผู้ใช้ไปยัง eval () เป็นความเสี่ยงด้านความปลอดภัย แต่การร้องขอ eval () แต่ละครั้งจะสร้างอินสแตนซ์ใหม่ของล่าม JavaScript นี่อาจเป็นหมูทรัพยากร
โดยทั่วไปเป็นเพียงปัญหาถ้าคุณผ่านการป้อนข้อมูลของผู้ใช้ที่ประเมินแล้ว
ส่วนใหญ่มันยากที่จะรักษาและแก้ไขปัญหา goto
มันเหมือน คุณสามารถใช้มันได้ แต่มันทำให้การค้นหาปัญหาและคนที่อาจจำเป็นต้องทำการเปลี่ยนแปลงนั้นยากขึ้นในภายหลัง
สิ่งหนึ่งที่ต้องจำไว้คือคุณสามารถใช้ eval () เพื่อเรียกใช้โค้ดในสภาพแวดล้อมที่ จำกัด เป็นอย่างอื่น - เว็บไซต์เครือข่ายสังคมที่บล็อกฟังก์ชัน JavaScript บางครั้งอาจถูกหลอกได้ด้วยการทำลายพวกเขาในบล็อก eval -
eval('al' + 'er' + 't(\'' + 'hi there!' + '\')');
ดังนั้นหากคุณต้องการเรียกใช้รหัส JavaScript ที่อาจไม่ได้รับอนุญาต ( Myspaceฉันกำลังมองคุณ ... ) ดังนั้น eval () อาจเป็นกลอุบายที่มีประโยชน์
อย่างไรก็ตามด้วยเหตุผลทั้งหมดที่กล่าวมาข้างต้นคุณไม่ควรใช้มันสำหรับรหัสของคุณเองซึ่งคุณสามารถควบคุมได้อย่างสมบูรณ์ - มันไม่จำเป็นเลยและดีกว่าที่จะลดชั้นวางของ 'แฮ็ค JavaScript แฮ็ก'
[]["con"+"struc"+"tor"]["con"+"struc"+"tor"]('al' + 'er' + 't(\'' + 'hi there!' + '\')')()
ถ้าคุณไม่ให้ eval () เนื้อหาแบบไดนามิก (ผ่าน cgi หรืออินพุต) มันจะปลอดภัยและมั่นคงเหมือน JavaScript อื่น ๆ ทั้งหมดในหน้าของคุณ
นอกเหนือจากคำตอบที่เหลือฉันไม่คิดว่าข้อความที่เป็นหลักฐานจะมีการย่อขนาดเล็กสุดได้
มีความเสี่ยงด้านความปลอดภัยที่เป็นไปได้มีขอบเขตการดำเนินการที่แตกต่างกันและค่อนข้างไม่มีประสิทธิภาพเนื่องจากจะสร้างสภาพแวดล้อมการเขียนสคริปต์ใหม่ทั้งหมดสำหรับการดำเนินการของรหัส ดูที่นี่สำหรับข้อมูลเพิ่มเติมบางส่วน: EVAL
มันค่อนข้างมีประโยชน์แม้ว่าและใช้กับการกลั่นกรองสามารถเพิ่มฟังก์ชันการทำงานที่ดีมากมาย
ถ้าคุณไม่แน่ใจ 100% ว่าโค้ดที่ถูกประเมินนั้นมาจากแหล่งที่เชื่อถือได้ (โดยปกติจะเป็นแอปพลิเคชันของคุณเอง) จากนั้นก็เป็นวิธีที่แน่นอนในการเปิดเผยระบบของคุณไปสู่การโจมตีสคริปต์ข้ามไซต์
ฉันรู้ว่าการสนทนานี้เก่า แต่ฉันชอบวิธีนี้โดย Google และต้องการแบ่งปันความรู้สึกนั้นกับผู้อื่น;)
อีกอย่างคือดีกว่าคุณจะได้มากขึ้นคุณพยายามที่จะเข้าใจและในที่สุดคุณก็ไม่เชื่อว่ามีบางอย่างที่ดีหรือไม่ดีเพียงเพราะมีคนพูดถึงมัน :) นี่เป็นวิดีโอที่สร้างแรงบันดาลใจให้ฉัน :) การปฏิบัติที่ดีเป็นสิ่งที่ดี แต่อย่าใช้อย่างไร้เหตุผล :)
ไม่จำเป็นว่าเลวร้ายหากคุณรู้ว่าคุณกำลังใช้บริบทอะไรอยู่
หากแอปพลิเคชันของคุณใช้eval()
เพื่อสร้างวัตถุจาก JSON บางตัวซึ่งกลับมาจากXMLHttpRequestในเว็บไซต์ของคุณเองซึ่งสร้างโดยรหัสฝั่งเซิร์ฟเวอร์ที่เชื่อถือได้ของคุณนั่นอาจไม่ใช่ปัญหา
โค้ด JavaScript ฝั่งไคลเอ็นต์ที่ไม่น่าเชื่อถือไม่สามารถทำเช่นนั้นได้มาก หากสิ่งที่คุณกำลังดำเนินการeval()
นั้นมาจากแหล่งข้อมูลที่สมเหตุสมผลคุณก็สบายดี
ช่วยลดระดับความมั่นใจของคุณเกี่ยวกับความปลอดภัยอย่างมาก
หากคุณต้องการให้ผู้ใช้ป้อนฟังก์ชันแบบลอจิคัลและประเมินค่าสำหรับ AND และ OR ฟังก์ชัน Eval ของ JavaScript นั้นสมบูรณ์แบบ ฉันสามารถยอมรับสองสายและeval(uate) string1 === string2
อื่น ๆ
หากคุณเห็นการใช้ eval () ในรหัสของคุณโปรดจำไว้ว่ามนต์“ eval () เป็นสิ่งที่ชั่วร้าย”
ฟังก์ชั่นนี้ใช้สตริงที่กำหนดเองและรันเป็นโค้ด JavaScript เมื่อทราบรหัสที่เป็นปัญหาล่วงหน้า (ไม่ได้กำหนดที่รันไทม์) ไม่มีเหตุผลที่จะใช้ eval () หากโค้ดถูกสร้างขึ้นแบบไดนามิกในรันไทม์มักจะมีวิธีที่ดีกว่าในการบรรลุเป้าหมายโดยไม่ต้องใช้ eval () ตัวอย่างเช่นเพียงใช้เครื่องหมายวงเล็บเหลี่ยมเพื่อเข้าถึงคุณสมบัติแบบไดนามิกจะดีกว่าและง่ายกว่า:
// antipattern
var property = "name";
alert(eval("obj." + property));
// preferred
var property = "name";
alert(obj[property]);
การใช้งานeval()
ยังมีผลกระทบด้านความปลอดภัยเนื่องจากคุณอาจกำลังเรียกใช้รหัส (ตัวอย่างเช่นมาจากเครือข่าย) ที่ได้รับการดัดแปลง นี่คือ antipattern ทั่วไปเมื่อจัดการกับการตอบสนอง 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()
คุณสามารถพิจารณาใช้ Function () ใหม่แทน
มีประโยชน์เล็กน้อยที่อาจเกิดขึ้นเนื่องจากรหัสที่ประเมินในฟังก์ชันใหม่ () จะทำงานในขอบเขตฟังก์ชันท้องถิ่นดังนั้นตัวแปรใด ๆ ที่กำหนดด้วย var ในรหัสที่กำลังประเมินจะไม่กลายเป็นรูปกลมอัตโนมัติ
อีกวิธีหนึ่งในการป้องกันไม่ให้กลมกลืนอัตโนมัติคือการตัดการ
eval()
โทรเข้าฟังก์ชันการทำงานทันที
นอกเหนือจากปัญหาด้านความปลอดภัยที่เป็นไปได้หากคุณกำลังเรียกใช้งานรหัสที่ผู้ใช้ส่งส่วนใหญ่มีวิธีที่ดีกว่าที่ไม่เกี่ยวข้องกับการแยกวิเคราะห์รหัสใหม่ทุกครั้งที่เรียกใช้งาน ฟังก์ชั่นที่ไม่ระบุชื่อหรือคุณสมบัติของวัตถุสามารถแทนที่การใช้ eval ส่วนใหญ่และมีความปลอดภัยและเร็วกว่ามาก
ปัญหานี้อาจมีปัญหามากขึ้นเนื่องจากเบราว์เซอร์รุ่นใหม่ออกมาพร้อมกับคอมไพเลอร์ JavaScript รหัสที่ดำเนินการผ่าน Eval อาจทำงานได้ไม่ดีเท่ากับ JavaScript ที่เหลือของคุณกับเบราว์เซอร์รุ่นใหม่เหล่านี้ บางคนควรทำโปรไฟล์
นี่เป็นหนึ่งในบทความที่ดีที่พูดถึง eval และมันไม่ใช่ความชั่วร้าย: http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/
ฉันไม่ได้บอกว่าคุณควรจะหมดและเริ่มใช้ eval () ทุกที่ ในความเป็นจริงมีกรณีการใช้งานที่ดีน้อยมากสำหรับการเรียกใช้ eval () เลย มีข้อสงสัยเกี่ยวกับความชัดเจนของรหัสการแก้จุดบกพร่องและประสิทธิภาพที่แน่นอนซึ่งไม่ควรมองข้าม แต่คุณไม่ควรกลัวที่จะใช้เมื่อคุณมีกรณีที่ eval () เข้าท่า พยายามอย่าใช้มันก่อน แต่อย่าให้ใครทำให้คุณกลัวว่ารหัสของคุณนั้นบอบบางหรือปลอดภัยน้อยกว่าเมื่อใช้ eval () อย่างเหมาะสม
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
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
ไม่ใช่ความคิดที่ดีเสมอไป ยกตัวอย่างเช่นการสร้างรหัส ผมเพิ่งเขียนห้องสมุดที่เรียกว่าHyperbarsซึ่งเชื่อมช่องว่างระหว่างเสมือน Domและแฮนด์ มันเป็นเช่นนี้โดยการแยกแม่แบบแฮนด์บาร์และแปลงเป็นไฮเปอร์สคริปต์ซึ่งต่อมาถูกใช้โดย 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()
ไม่ใช่ปัญหาในสถานการณ์เช่นนี้เนื่องจากคุณจำเป็นต้องตีความสายอักขระที่สร้างขึ้นเพียงครั้งเดียวและจากนั้นใช้งานผลลัพธ์ที่สามารถเรียกคืนได้หลายครั้ง
คุณสามารถดูวิธีการสร้างรหัสก็ประสบความสำเร็จถ้าคุณอยากรู้ที่นี่
ฉันจะไปไกลเท่าที่จะบอกว่ามันไม่สำคัญว่าถ้าคุณใช้eval()
ในจาวาสคริปต์ที่ทำงานในเบราว์เซอร์ * (ข้อแม้)
เบราว์เซอร์สมัยใหม่ทั้งหมดมีคอนโซลผู้พัฒนาซึ่งคุณสามารถใช้งานจาวาสคริปต์ได้เองและผู้พัฒนากึ่งอัจฉริยะสามารถดูซอร์ส JS ของคุณและวางบิตใด ๆ ที่จำเป็นต้องใช้ในคอนโซล dev เพื่อทำสิ่งที่ต้องการ
* ตราบใดที่จุดปลายเซิร์ฟเวอร์ของคุณมีการตรวจสอบความถูกต้องและถูกต้องของค่าที่ผู้ใช้ระบุมันไม่สำคัญว่าจะมีการแยกวิเคราะห์และประเมินค่าอะไรในจาวาสคริปต์ฝั่งไคลเอ็นต์ของคุณ
ถ้าคุณต้องถามว่ามันเหมาะสมที่จะใช้eval()
ใน PHP หรือไม่คำตอบคือไม่ยกเว้นว่าคุณอนุญาตรายการใด ๆ ที่อาจส่งผ่านไปยังคำสั่ง eval ของคุณ
ฉันจะไม่พยายามหักล้างสิ่งที่กล่าวมาก่อนหน้านี้ แต่ฉันจะเสนอการใช้ 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);
แก้ไข: โดยวิธีการที่ฉันจะไม่แนะนำ (ด้วยเหตุผลด้านความปลอดภัยทั้งหมดชี้ให้เห็นก่อนหน้านี้) ว่าคุณฐานคุณชื่อวัตถุในการป้อนข้อมูลของผู้ใช้ ฉันไม่สามารถจินตนาการถึงเหตุผลที่ดีที่คุณต้องการทำเช่นนั้น ยังคิดว่าฉันจะชี้ให้เห็นว่ามันจะไม่เป็นความคิดที่ดี :)
namespaceToTest[namespaceParts[i]]
ไม่จำเป็นต้อง eval ที่นี่ดังนั้นความif(typeof namespaceToTest[namespaceParts[i]] === 'undefined') { namespaceToTest[namespaceParts[i]] = {};
แตกต่างเพียงอย่างเดียวสำหรับelse namespaceToTest = namespaceToTest[namespaceParts[i]];
เก็บขยะ
คอลเล็กชันขยะของเบราว์เซอร์ไม่ทราบว่าจะสามารถลบรหัสที่มีการ eval'ed ออกจากหน่วยความจำได้หรือไม่ดังนั้นจึงเป็นเพียงการเก็บไว้จนกว่าจะโหลดหน้าเว็บอีกครั้ง ไม่เลวร้ายนักหากผู้ใช้ของคุณอยู่ในหน้าเว็บของคุณในไม่ช้า แต่อาจเป็นปัญหาสำหรับเว็บแอป
นี่คือสคริปต์เพื่อสาธิตปัญหา
https://jsfiddle.net/CynderRnAsh/qux1osnw/
document.getElementById("evalLeak").onclick = (e) => {
for(let x = 0; x < 100; x++) {
eval(x.toString());
}
};
สิ่งที่เรียบง่ายเหมือนโค้ดด้านบนจะทำให้มีหน่วยความจำเล็กน้อยที่จะจัดเก็บไว้จนกว่าแอปจะตาย นี่คือที่เลวร้ายยิ่งเมื่อสคริปต์ evaled เป็นฟังก์ชั่นใหญ่และเรียกในช่วงเวลา