ค่าประเภทพื้นฐานคือ: undefined, null, boolean, จำนวนและสตริง ประเภทเหล่านี้ใช้พื้นที่ขนาดคงที่ในหน่วยความจำและค่าของพวกเขาจะถูกบันทึกไว้ในพื้นที่สแต็กซึ่งเราเข้าถึงได้ตามค่า
(1) ประเภทค่า: ตัวเลข, บูลีน, โมฆะ, ไม่ได้กำหนด
(2) ประเภทการอ้างอิง: วัตถุ, อาร์เรย์, ฟังก์ชั่น
หากค่าที่กำหนดเป็นประเภทการอ้างอิงจะต้องจัดสรรพื้นที่สำหรับค่านี้ในหน่วยความจำฮีป เนื่องจากขนาดของค่าดังกล่าวไม่ได้รับการแก้ไข (วัตถุมีคุณสมบัติและวิธีการมากมาย) จึงไม่สามารถบันทึกลงในหน่วยความจำสแต็กได้ อย่างไรก็ตามขนาดที่อยู่หน่วยความจำได้รับการแก้ไขดังนั้นที่อยู่หน่วยความจำสามารถบันทึกในหน่วยความจำสแต็ก
<script type = "text/javascript"> var box = new Object (); // สร้างกล่องประเภทอ้างอิง var = "lee"; // ค่าประเภทพื้นฐานคือกล่องสตริง = 23; // มันแปลกที่จะเพิ่มแอตทริบิวต์ให้กับค่าประเภทพื้นฐานเนื่องจากวัตถุเท่านั้นสามารถเพิ่มแอตทริบิวต์ การแจ้งเตือน (box.age); // ไม่ใช่ประเภทอ้างอิงและไม่สามารถส่งออกได้ </script>
ในระยะสั้นหน่วยความจำฮีปจะเก็บค่าอ้างอิงและหน่วยความจำสแต็กจะเก็บค่าประเภทคงที่
<script type = "text/javascript"> var man = new Object (); // Man ชี้ไปที่ที่อยู่เชิงพื้นที่ของหน่วยความจำสแต็ก man.name = "jack"; var man2 = man; // man2 ได้รับที่อยู่ของการแจ้งเตือนการชี้ของมนุษย์ (man2.name); // ทั้งสองป๊อปอัพการแจ้งเตือนแจ็ค (man.name); </script>
คัดลอกค่าตัวแปร
มาดูตัวอย่างต่อไปนี้:
<script type = "text/javascript"> var man = new Object (); // Man ชี้ไปที่ที่อยู่เชิงพื้นที่ของหน่วยความจำสแต็ก man.name = "jack"; var man2 = man; // man2 ได้รับที่อยู่ของที่อยู่ชี้ของมนุษย์ man2.name = "ming"; // เพราะพวกเขาทั้งหมดชี้ไปที่วัตถุเดียวกันและชื่อเดียวกันไม่ว่าใครจะถูกแก้ไขทุกคนได้ปรับเปลี่ยนการแจ้งเตือน (man2.name); //
จากด้านบนเราจะเห็นได้ว่าในแง่ของการคัดลอกตัวแปรประเภทพื้นฐานและประเภทการอ้างอิงก็แตกต่างกันเช่นกัน ประเภทพื้นฐานจะคัดลอกค่าเองในขณะที่ประเภทการอ้างอิงจะคัดลอกที่อยู่
ผ่านพารามิเตอร์
ใน eCmascript พารามิเตอร์ทั้งหมดของฟังก์ชั่นจะถูกส่งผ่านด้วยค่า
<script type = "text/javascript"> กล่องฟังก์ชัน (num) {// pass num โดยค่า num+= 10; กลับมา; } var num = 10; var result = box (num); การแจ้งเตือน (ผลลัพธ์); // หากผ่านการอ้างอิงแล้ว NUM ในฟังก์ชั่นจะกลายเป็นตัวแปรส่วนกลางและตัวเลขภายนอกจะถูกแทนที่ด้วยการแจ้งเตือน (NUM); // กล่าวอีกนัยหนึ่ง 20 ควรเป็นเอาต์พุตในตอนท้าย (10 คือเอาต์พุตที่นี่) </script>JavaScript ไม่ได้ผ่านการอ้างอิง หากมีการอ้างอิงตัวแปรในฟังก์ชั่นจะเป็นตัวแปรทั่วโลกและยังสามารถเข้าถึงได้จากภายนอก แต่เห็นได้ชัดว่าเป็นไปไม่ได้
สภาพแวดล้อมการดำเนินการและขอบเขต
สภาพแวดล้อมการดำเนินการเป็นหนึ่งในแนวคิดที่สำคัญที่สุดใน JavaScript สภาพแวดล้อมการดำเนินการกำหนดตัวแปรหรือฟังก์ชั่นที่ได้รับอนุญาตให้เข้าถึงข้อมูลอื่น ๆ
สภาพแวดล้อมการดำเนินการทั่วโลกเป็นสภาพแวดล้อมการดำเนินการต่อพ่วงมากที่สุด ในเว็บเบราว์เซอร์สภาพแวดล้อมการดำเนินการทั่วโลกเป็นวัตถุหน้าต่าง ดังนั้นฟังก์ชั่นทั้งหมดของตัวแปรทั่วโลกจึงถูกสร้างขึ้นเป็นคุณสมบัติและวิธีการของ Windows
<script type = "text/javascript"> var name = "jack"; // กำหนดฟังก์ชันตัวแปรส่วนกลาง setName () {return "trigkit4"; } Alert (window.name); // ตัวแปรทั่วโลกด้านนอกสุดเป็นของการแจ้งเตือนแอตทริบิวต์หน้าต่าง (window.setName ()); // ฟังก์ชั่นทั่วโลกด้านนอกสุดเป็นของวิธีหน้าต่าง </script>เมื่อมีการดำเนินการรหัสในสภาพแวดล้อมการดำเนินการสภาพแวดล้อมจะถูกทำลายและตัวแปรและฟังก์ชั่นที่บันทึกไว้จะถูกทำลายเช่นกัน หากเป็นสภาพแวดล้อมทั่วโลกโปรแกรมทั้งหมดจะต้องดำเนินการหรือหน้าเว็บจะถูกทำลาย
ลบตัวแปรท้องถิ่นของ var
<script type = "text/javascript"> var name = "jack"; ฟังก์ชั่น setName () {name = "trigkit4"; // ลบ var และกลายเป็นตัวแปรส่วนกลาง} setName (); แจ้งเตือน (ชื่อ); // ป๊อปอัพ Trigkit4 </script>โดยการผ่านพารามิเตอร์มันยังเป็นตัวแปรท้องถิ่น
<script type = "text/javascript"> var name = "jack"; ฟังก์ชั่น setName (ชื่อ) {// อาร์กิวเมนต์ที่ส่งผ่านก็คือการแจ้งเตือนตัวแปรโลคัล (ชื่อ); } setName ("trigkit4"); // ป๊อปอัพ trigkit4 Alert (ชื่อ); // ป๊อปอัพแจ็ค </script>ฟังก์ชั่นยังมีฟังก์ชั่นและฟังก์ชั่นนี้เท่านั้นที่สามารถเข้าถึงเลเยอร์ด้านในของฟังก์ชั่น
<script type = "text/javascript"> var name = "jack"; ฟังก์ชั่น setName () {function setYear () {// ขอบเขตของวิธี setYear () อยู่ภายใน setName () ส่งคืน 21; }} Alert (setYear ()); // ไม่สามารถเข้าถึงได้ข้อผิดพลาด </script>คุณสามารถเข้าถึงได้โดย:
<script type = "text/javascript"> var name = "jack"; ฟังก์ชั่น setName () {function setYear () {// ขอบเขตของวิธี setYear () อยู่ภายใน setName () ส่งคืน 21; } return setYear (); } Alert (setName ()); // ป๊อป 21 </script>ตัวอย่างขอบเขตอื่น:
<script type = "text/javascript"> var name = "jack"; ฟังก์ชัน setName () {function setYear () {// ขอบเขตของวิธี setYear () อยู่ใน setName () var b = "hi"; // ขอบเขตของตัวแปร B อยู่ใน SetYear () Return 21; } Alert (B); // The Occessible} </script>เมื่อรหัสถูกดำเนินการในสภาพแวดล้อมสิ่งที่เรียกว่าห่วงโซ่ขอบเขตจะเกิดขึ้น วัตถุประสงค์คือเพื่อให้แน่ใจว่าการเข้าถึงตัวแปรและฟังก์ชั่นที่มีสิทธิ์การเข้าถึงในสภาพแวดล้อมการดำเนินการอย่างเป็นระเบียบ (หมายถึงการเข้าถึงตามระดับกฎ) ส่วนหน้าของห่วงโซ่ขอบเขตเป็นวัตถุตัวแปรของสภาพแวดล้อมการดำเนินการ
ขอบเขต
เมื่อตัวแปรไม่ได้ประกาศหรือประกาศในฟังก์ชั่นมันเป็นตัวแปรทั่วโลกและมีขอบเขตทั่วโลก คุณสมบัติทั้งหมดของวัตถุหน้าต่างมีขอบเขตทั่วโลก มันสามารถเข้าถึงได้ทุกที่ในรหัสและตัวแปรที่ประกาศภายในและแก้ไขด้วย VAR เป็นตัวแปรท้องถิ่นซึ่งสามารถใช้ในร่างกายฟังก์ชั่นเท่านั้น แม้ว่าพารามิเตอร์ฟังก์ชันจะไม่ใช้ VAR แต่ก็ยังคงเป็นตัวแปรท้องถิ่น
ไม่มีขอบเขตระดับบล็อก
ไม่มีขอบเขตระดับบล็อก
// ถ้าคำสั่ง: <script type = "text/javascript"> ถ้า (จริง) {// การจัดฟันดัดผมของคำสั่ง IF ไม่มีฟังก์ชันขอบเขต var box = "trigkit4";} alert (box); // popt up trigkit4 </script>เช่นเดียวกับคำสั่งลูป
แบบสอบถามของตัวแปร
ในการสืบค้นตัวแปรการเข้าถึงตัวแปรท้องถิ่นนั้นเร็วกว่าตัวแปรทั่วโลกดังนั้นจึงไม่จำเป็นต้องค้นหาโซ่ขอบเขต
ดังที่แสดงในตัวอย่างต่อไปนี้:
<script type = "text/javascript"> var name = "jack"; ฟังก์ชัน setName () {var name = "trigkit4"; ชื่อคืน; // ค้นหาตัวแปรจากการแจ้งเตือนเลเยอร์ด้านล่าง} การแจ้งเตือน (setName ()); </script>ปัญหาหน่วยความจำ
JavaScript มีกลไกการรวบรวมขยะอัตโนมัติและเมื่อข้อมูลไม่ได้ใช้งานอีกต่อไปก็สามารถตั้งค่าเป็น "null" เพื่อปล่อยการอ้างอิง
การอ้างอิงรีไซเคิล
ตัวอย่างที่ง่ายมาก: วัตถุ DOM ถูกอ้างอิงโดยวัตถุ JavaScript และในเวลาเดียวกันหมายถึงวัตถุ JavaScript เดียวกันหรืออื่น ๆ วัตถุ DOM นี้อาจทำให้หน่วยความจำรั่ว การอ้างอิงถึงวัตถุ DOM นี้จะไม่ถูกรีไซเคิลโดยตัวเก็บขยะเมื่อสคริปต์หยุด ในการทำลายการอ้างอิงแบบวงกลมวัตถุที่อ้างถึงองค์ประกอบ DOM หรือการอ้างอิงไปยังวัตถุ DOM จะต้องได้รับการกำหนดค่าของ NULL
การปิด
เมื่อแนะนำตัวแปรที่อยู่นอกการปิดเข้าไปในการปิดวัตถุนี้ไม่สามารถเก็บขยะ (GC) เมื่อปิดสิ้นสุดลง
var a = function () {var largestr = new Array (10,00000) .Join ('x'); ฟังก์ชั่น return () {return larsestr; -ดอมรั่วไหล
เมื่อ Compon ดั้งเดิมถูกลบออกการอ้างอิงโหนดย่อยจะไม่สามารถรีไซเคิลได้หากไม่ได้ลบออก
var select = document.QuerySelector; var treeref = select ('#tree'); // ในทรี com, leafref เป็นโหนดลูกของ treefre var leafref = select ('#leaf'); var body = select ('body'); body.removeChild (treeref); // #ต้นไม้ไม่สามารถรีไซเคิลได้เนื่องจาก treeref ยังคงอยู่ที่นั่น // โซลูชัน: treeref = null; // ต้นไม้ไม่สามารถรีไซเคิลได้เพราะ leafref ยังคงมี leafref = null; // #treeตัวจับเวลาการวัด (กำหนด) การรั่วไหลของตัวจับเวลา
ตัวจับเวลายังเป็นสถานที่ทั่วไปที่มีการรั่วไหลของหน่วยความจำ:
สำหรับ (var i = 0; i <90000; i ++) {var buggyObject = {callagain: function () {var ref = this; var val = settimeout (function () {ref.callagain ();}, 90000); }} buggyObject.callagain (); // แม้ว่าคุณต้องการรีไซเคิลตัวจับเวลายังคงเป็น buggyObject = null;}การดีบักหน่วยความจำ
เครื่องมือการดีบักหน่วยความจำของ Chrome สามารถดูการใช้หน่วยความจำและการรั่วไหลของหน่วยความจำได้อย่างง่ายดาย:
คลิกบันทึกในไทม์ไลน์ -> หน่วยความจำ: