갑자기 너무 어려운걸 너무 많이 배웠다...
한번에 이해되지 않는것이 당연하니 일단 이해한 대로만 기록하고
더 깊이 알게되면 그때 follow up을 적을것
메모리를 기준으로
변수 vs 상수
불변 vs 가변
으로 나눠진다.
1-1. 변수 & 상수
변수 : 변수 영역 메모리를 변경 가능
상수 : 변수 영역 메모리 변경 불가
1-2. 불변 & 가변
불변 : 데이터 영역 메모리를 변경할 수 없다
가변 : 데이터 영역 메모리를 변경할 수 있다.
Q. 데이터 영역 메모리를 변경한다는게 뭔데?
A. 어떤 객체가 있고 그 객체 속성에 접근해서 그걸 바꾸면 데이터 영역 메모리가 변경 됨.
Q. 그럼 객체에 새로운 데이터를 추가하는건?
A. 그건 기존 데이터를 변경하지 않으니 그 경우는 불변임.
Q. 애초에 이걸 왜 따지는건데?
A. 객체를 복사해서 새로운 객체를 만들때 이 부분이 문제가 될 수 있고, 이런걸 모르면 어디서 문제가 발생했는지조차 파악할 수 없기 때문이다.
var user = {
name: 'wonjang',
gender: 'male',
};
var changeName = function (user, newName) {
var newUser = user;
newUser.name = newName;
return newUser;
};
var user2 = changeName(user, 'twojang');
console.log(user.name, user2.name); // twojang twojang
이 예시를 보면 user객체를 이용해서 newUser를 정하고, newUser의 이름을 바꿨는데 의도와 다르게 user 의 이름까지 변경된 것을 확인할 수 있다.
Q. 그럼 객체를 복사하고 싶으면 어떡하는데?
A. 가장 간단한 방법은 다음과 같다.
var jsonString = JSON.stringify(user);
var newUser = JSON.parse(jsonString);
이러면 newUser 에 user가 복사되며 newUser를 변경해도 user가 따라서 변경되지 않는다.
하지만! 이 방법에도 한계가 있는데 객체 안의 함수나 undefined값을 가지는 속성은 복사 되지 않으며, 객체 안에 객체가 들어 있는 경우도 복사되지 않는다.
그래서 for~in 구문을 이용한 깊은 복사를 해야하는데 이부분 아직 이해가 안간다. 반드시 복습해서 제대로 이해할것!!
[follow up 10/15]
얕은 복사 하는법 하나 더 알아 왔다. 스프레드 구문을 이용하면 더 간단하게 복사할수 있다(근데 이것도 얕은 복사일듯하다...)
var user = {
name: 'wonjang',
gender: 'male',
}
var anotherUser = { ...user}
이렇게 하면 user의 내용을 그대로 복사해 오면서 새로운 객체를 만들기 때문에 메모리의 새로운 공간과 주소를 할당받게 되어 상술한 문제-하나를 변경했을때 의도치 않게 다른 하나도 변경되는-가 발생하지 않는다.
[follow up 10/20]
스프레드 구문을 이용한 깊은 복사 방법 알아옴.
const person = { name:'Kim', hobbies : ['cooking','coding'] }
const person2 = {...person, hobbies : [...person.hobbies] }
person2.hobbies.push('sleeping')
console.log(person.hobbies) // ['cooking','coding']
console.log(person2.hobbies)// ['cooking','coding','sleeping']
스프레드 구문으로 복사했을때 참조값이 깊은 복사가 되지 않기때문에, 참조값만 스프레드 구문을 써서 다시 한번 복사 해주면 된다. 위 예시 처럼.
이렇게 하면 person2의 hobbies에 뭔가를 추가해도 그것이 person 의 hobbies에는 반영되지 않는걸 확인할 수 있다.
실행 컨텍스트 는 객체다.
이 객체 안에는 VariableEnvironment, LexicalEnvironment, ThisBinding 이 들어간다.
2-1. VE와 LE는 VE가 스냅샷이고 LE는 스냅샷이 아니라는것을 제외하면 동일 하다.
2-2. VE와 LE 둘다 record 와 outer 가 저장된다.
2-3. record 에서는 호이스팅될 것들을 기록한다. 호이스팅 되는 것들은 다음과 같다 => 함수에 지정된 매개변수 식별자, 함수 자체, var로 선언된 변수 식별자 등
이것들은 호이스팅 되어 상단으로 끌어올려진다.
2-4. 함수 선언문 으로 이루어진 코드는 그 함수가 통째로 호이스팅 되며, 함수 표현식으로 이루어진 코드는 함수 선언부만 호이스팅된다.
따라서 협업을 많이 하며 복잡한 코드일수록 함수 표현식이 문제를 일으킬 확률이 적다.
스코프는 쉽게 이해하면 "변수가 어디까지 영향을 미칠수 있느냐" 이다.
예전에 함수 내부에서 선언한 변수는 함수 밖에서 접근할수 없다고 들었는데 그것도 스코프 때문이라고 이해해도 될 듯 하다.
스코프를 이해하려면 호이스팅을 이해하고 있어야만 한다.
var a = 1;
var outer = function() {
var inner = function() {
console.log(a); // 여기선 undefined가 찍힌다.
바로 아랫줄의 var a가 호이스팅 되었지만
=3은 호이스팅 되지 않았기 때문이다.
var a = 3;
};
inner();
console.log(a); // 여기선 outer컨텍스트 에 해당하는 전역의 1이 찍힌다.
};
outer();
console.log(a); // 여기선 당연히 1 이 찍힌다.
코딩 공부 시작하고 만난 첫 벽!
갑자기 너무 어렵다. 이것 말고도 this를 배웠는데 this 는 더 이해가 안간다. 깊은 복사, this 외에도 call, apply, bind 메서드도 아직 잘 모르겠다.
근데 완전 모르던 분야를 처음 배우는건데 쉬울꺼라고 예상하진 않았다. 내일 다시 공부하면 분명 오늘보다 훨씬 더 잘 이해갈 것이라고 믿는다. 그래도 안되면 또 공부해보면 되고, 그래도 안되면 잘 아는 분에게 물어보면 되겠지. 포기하지만 말자!