기본 유형 값에는 정의되지 않음, NUll, Boolean, Number 및 String이 포함됩니다. 이러한 유형은 메모리에서 고정된 크기 공간을 차지하며 해당 값은 스택 공간에 저장되며 값으로 액세스합니다.
(1) 값 유형: 숫자 값, 부울 값, null, 정의되지 않음.
(2) 참조 유형: 객체, 배열, 함수.
할당된 값이 참조 유형인 경우 힙 메모리에 이 값에 대한 공간을 할당해야 합니다. 이러한 값의 크기는 고정되어 있지 않기 때문에(객체에는 많은 속성과 메서드가 있음) 스택 메모리에 저장할 수 없습니다. 하지만 메모리 주소 크기는 고정되어 있으므로 메모리 주소를 스택 메모리에 저장할 수 있습니다.
<script type="text/javascript”> var box = new Object(); //创建一个引用类型 var box = "lee"; //基本类型值是字符串 box.age = 23; //基本类型值添加属性很怪异,因为只有对象才可以添加属性。 alert(box.age); //不是引用类型,无法输出; </script>
간단히 말하면 힙 메모리는 참조 값을 저장하고, 스택 메모리는 고정형 값을 저장합니다.
<script type="text/javascript"> var man = new Object();//man指向了栈内存的空间地址 man.name = "Jack"; var man2 = man;//man2获得了man的指向地址 alert(man2.name);//两个都弹出Jack alert(man.name); </script>
변수 값 복사
다음 예를 살펴보세요.
<script type="text/javascript"> var man = new Object();//man指向了栈内存的空间地址 man.name = "Jack"; var man2 = man;//man2获得了man的指向地址 man2.name = "ming";//因为他们都指向同一个object,同一个name,不管修改谁,大家都修改了 alert(man2.name);//两个都弹出ming alert(man.name); </script>
위에서 결론을 내릴 수 있습니다. 변수 복사의 경우 기본 유형과 참조 유형도 다릅니다. 기본 유형은 값 자체를 복사하고 참조 유형은 주소를 복사합니다.
패스 매개변수
ECMAScript에서는 모든 함수 매개변수가 값으로 전달됩니다.
<script type="text/javascript"> function box(num){ //按值传递 num+=10; return num; } var num = 10; var result = box(num); alert(result); //如果是按引用传递,那么函数里的num会成为类似全局变量,把外面的number替换掉 alert(num); //也就是说,最后应该输出20(这里输出10) </script>
Javascript는 참조로 전달하지 않습니다. 참조로 전달이 있는 경우 함수 내의 변수는 전역 변수가 되며 외부에서도 액세스할 수 있습니다. 그러나 이것은 분명히 불가능하다.
실행 환경 및 범위
실행 환경은 JavaScript에서 가장 중요한 개념 중 하나입니다. 실행 환경은 다른 데이터에 액세스하기 위한 변수나 함수의 권한을 정의합니다.
전역 실행 환경은 웹 브라우저에서 가장 주변적인 실행 환경입니다. 따라서 전역 변수의 모든 기능은 창의 속성과 메서드로 생성됩니다.
<script type="text/javascript"> var name = "Jack"; //定义全局变量 function setName(){ return "trigkit4"; } alert(window.name); //全局变量,最外围,属于window属性 alert(window.setName()); //全局函数,最外围,属于window方法 </script>
실행환경의 코드가 실행되면 환경은 소멸되며, 그 안에 저장된 변수와 함수도 소멸됩니다. 글로벌 환경이라면 모든 프로그램이 실행되거나 종료될 때까지 소멸되지 않습니다. 웹페이지가 완성되었습니다.
var의 지역변수 제거
<script type="text/javascript"> var name = "Jack"; function setName(){ name = "trigkit4"; //去掉var变成了全局变量 } setName(); alert(name);//弹出trigkit4 </script>
매개변수를 전달하면 지역변수이기도 합니다
<script type="text/javascript"> var name = "Jack"; function setName(name){ //通过传参,也是局部变量 alert(name); } setName("trigkit4");//弹出trigkit4 alert(name);//弹出Jack </script>
함수 본문에도 함수가 포함되어 있습니다. 이 함수만 함수의 내부 계층에 액세스할 수 있습니다.
<script type="text/javascript"> var name = "Jack"; function setName(){ function setYear(){ //setYear()方法的作用域在setName()内 return 21; } } alert(setYear());//无法访问,出错 </script>
다음 방법을 통해 액세스할 수 있습니다:
<script type="text/javascript"> var name = "Jack"; function setName(){ function setYear(){ //setYear()方法的作用域在setName()内 return 21; } return setYear(); } alert(setName()); //弹出21 </script>
또 다른 범위 예:
<script type="text/javascript"> var name = "Jack"; function setName(){ function setYear(){ //setYear()方法的作用域在setName()内 var b = "hi"; //变量b的作用域在setYear()内 return 21; } alert(b);//无法访问 } </script>
환경에서 코드가 실행되면 범위 체인이라는 것이 형성됩니다. 그 목적은 실행 환경에서 액세스 권한이 있는 변수 및 함수에 대한 질서 있는 액세스를 보장하는 것입니다(액세스할 규칙 계층 참조). , 범위 체인의 프런트 엔드는 실행 환경의 변수 개체입니다.
범위
함수 내에서 선언되지 않거나 var 없이 선언된 변수는 전역 범위를 갖습니다. 창 개체의 모든 속성은 코드 내 어디에서나 액세스할 수 있습니다. 함수 내부에서 var로 장식됩니다. 변수는 지역 변수이며 함수 본문 내에서만 사용할 수 있습니다. 함수의 매개변수는 var를 사용하지 않지만 여전히 지역 변수입니다.
블록 범위 없음
블록 범위 없음
// if语句: <script type="text/javascript"> if(true){ //if语句的花括号没有作用域的功能。 var box = "trigkit4"; } alert(box);//弹出 trigkit4 </script>
for 루프 문에도 마찬가지입니다.
변수 쿼리
변수 쿼리에서는 지역 변수에 액세스하는 것이 전역 변수보다 빠르므로 범위 체인을 검색할 필요가 없습니다.
아래 예:
<script type="text/javascript"> var name = "Jack"; function setName(){ var name = "trigkit4"; return name; //从底层向上搜索变量 } alert(setName()); </script>
메모리 문제
Javascript에는 자동 가비지 수집 메커니즘이 있으므로 데이터가 더 이상 사용되지 않으면 "null"로 설정하여 참조를 해제할 수 있습니다.
참고문헌
아주 간단한 예: DOM 객체는 Javascript 객체에 의해 참조되는 동시에 동일하거나 다른 Javascript 객체를 참조합니다. 이 DOM 객체는 메모리 누수를 일으킬 수 있습니다. 이 DOM 개체에 대한 참조는 스크립트가 중지될 때 가비지 수집기에 의해 회수되지 않습니다. 참조 순환을 끊으려면 DOM 요소를 참조하는 객체나 DOM 객체에 대한 참조를 null로 할당해야 합니다.
폐업
클로저 외부의 변수가 클로저에 도입되면 클로저가 종료될 때 객체를 가비지 수집(GC)할 수 없습니다.
var a = function() { var largeStr = new Array(1000000).join('x'); return function() { return largeStr; } }();
DOM 유출
원본 COM이 제거되면 제거되지 않는 한 하위 노드 참조를 재활용할 수 없습니다.
var select = document.querySelector; var treeRef = select('#tree'); //在COM树中leafRef是treeFre的一个子结点 var leafRef = select('#leaf'); var body = select('body'); body.removeChild(treeRef); //#tree不能被回收入,因为treeRef还在 //解决方法: treeRef = null; //tree还不能被回收,因为叶子结果leafRef还在 leafRef = null; //现在#tree可以被释放了。
타이머 유출
타이머는 메모리 누수가 흔히 발생하는 장소이기도 합니다.
for (var i = 0; i < 90000; i++) { var buggyObject = { callAgain: function() { var ref = this; var val = setTimeout(function() { ref.callAgain(); }, 90000); } } buggyObject.callAgain(); //虽然你想回收但是timer还在 buggyObject = null; }
디버그 메모리
Chrome에 내장된 메모리 디버깅 도구를 사용하면 메모리 사용량과 메모리 누수를 쉽게 확인할 수 있습니다.
타임라인에서 기록 클릭 ->