다루는 내용
- 변수의 원시값과 참조값
- 실행 컨텍스트의 이해
- 가비지 컬렉션의 이해
1. 원시값과 참조값
- 원시값은 기본타입(문자열, null, undefined etc), 참조값은 메모리에 저장된 객체(객체의 프로퍼티)
- 대부분의 언어에서는 문자열을 참조값으로 침 (Ex. Java String)
- 참조값의 경우 동적 프로퍼티가 가능 (원시값은 불가)
1 2 3 4 5 6 7 8 9
1) 참조값 var person = new Object(); person.name = "snack"; console.log(person.name); // snack 2) 원시값 var name = "snack"; name.age = 29; console.log(name.age); // undefined
- 값을 복사할 경우에도 원시값과 참조값은 서로 다름
1 2 3 4 5 6 7 8 9 10 11 12 13
1) 원시값 // 값이 각각 다른 곳에 저장 var num1 = 1; var num2 = num1; num1 = 10; console.log(num1); // 10 console.log(num2); // 1 2) 참조값 // 힙에 저장된 레퍼런스를 가리키기 때문 var obj1 = new Object(); var obj2 = obj1; obj1.name = "snack"; console.log(obj2); // snack
- 매개변수는 모두 값으로 전달됨
1 2 3 4 5 6 7 8 9 10 11 12 13 14
function setName(obj) { obj.name = "snack"; obj = new Object(); obj.name = "Gray"; } var person = new Object(); setName(person); console.log(person.name); // sanck /* * setName() 의 매개변수인 obj 가 전역변수인 person 을 가리키기 때문에 반영이 됨 * obj 가 값이 아니라 참조로 전달되었다면, console.log 가 Gray 가 나왔을 것 */
- 원시 타입에서는
typeof
참조 타입에서는instanceof
2. 실행 컨텍스트와 스코프
- 변수나 함수의 실행 컨텍스트는 다른 데이터에 접근할 수 있는지, 어떻게 행동하는지를 규정
- 이 코드 하나로 실행 컨텍스트가 대강 설명이 될 거 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
var color = "blue"; function changeColor() { var anotherColor = "red"; function swapColors() { var tempColor = anotherColor; anotherColor = color; color = tempColor; // swapColors 내부에서는 color, anotherColor, tempColor 전부 접근 가능 } // changeColor 내부에서는 color, anotherColor 만 접근 가능 swapColors(); } // color 만 접근 가능 changeColor();
- 블록 레벨 스코프가 없기에 if, for 같은 제어문은 조심
1 2 3 4 5
if(true) { var ex1 = "good"; } console.log(ex1); // good;
for(var i=0; i < 10; i++) {
doSomething(i);
}
console.log(i); // 10
- 식별자 검색은 로컬 컨텍스트에서 점점 범위를 넓혀 전역 컨텍스트까지 찾고, 정의되어 있지 않으면 undefined
```javascript
var color = "green"
function getColor() {
var color = "dark";
return color;
}
console.log(getColor()); // dark
// green 을 불러오고 싶다면 window.color
3. 가비지 콜렉션
- 필요한 메모리를 자동으로 할당하고 사용하지 않는 메모리는 자동으로 회수
- 가능한한 최소한의 메모리를 사용해야 페이지 성능을 올릴 수 있으므로 참조가 끝나 필요없어진 데이터는 null 을 할당해 참조를 제거 하는 게 좋음
3.1 표시하고 지우기
- 가장 널리 쓰이는 방법
- 변수 전체에 표시를 남기고, 컨텍스트에 있는 변수, 컨텍스트가 참조하는 변수등에 대해 표시를 지움. 이후 표시가 남아있는 변수 삭제 후 메모리 회수
3.2 참조 카운팅
- 각 값이 얼마나 많이 참조되었는지를 카운팅
- 참조할 경우 카운팅 증가, 참조 변수에 다른 값을 할당하면 카운팅 감소
- 상호 참조, 순환 참조의 경우 카운팅이 감소되지 않아 메모리 회수가 안되는 문제가 있을 수도 있음
생각해볼 점
- 내용은 짧지만, 다루고 있는 내용은 짧다는 느낌이 안 듦
- 힙, 스택 메모리 영역에 대한 이해가 다시금 필요할 것 같음