호이스팅이란?
인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미함
var로 선언한 변수는 호이스팅 시 undefined로 변수를 초기화
let과 const로 선언한 변수는 호이스팅 시 변수를 초기화하지 않음
선언만 호이스팅 대상
console.log(num) // 호이스팅한 var 선언으로 undefined 출력
var num; // 선언
console.log(num) // 선언만 호이스팅 대상이기 때문에 에러 발생
num = 9; // 선언 없는 초기화
함수 호이스팅
함수 선언식 vs 함수 선언식
함수 선언식 예시
hoisted(); // 함수 실행
function hoisted() {
console.log('foo');
}
함수 표현식 예시
hoisted(); // 에러 발생
var notHoisted = function() {
console.log('bar');
}
함수 선언식의 경우 호이스팅의 대상이 되어 함수가 정의되기 전에 호출되도 끌어올려지지만 함수 표현식의 경우 호이스팅의 대상이 아니기 때문에 함수가 정의되기 전에 호출되면 끌어올려지지 않음
mdn-호이스팅
mdn-함수 호이스팅
스코프란?
변수에 접근할 수 있는 범위로 이 범위는 블록이나 함수에 의해 나누어짐
스코프에서 기억해야 할 점은 전역 가장 바깥 스코프는 전역 스코프, 그 외에는 지역 스코프이며 지역 변수는 전역변수보다 높은 우선순위를 가진다는 점!
let message = 'Outer';
function getMessage() {
return message;
}
function shadowGlobal() {
let message = 'Inner';
return message;
}
function shadowGlobal2(message) {
return message;
}
function shadowParameter(message) {
message = 'Do not use parameters like this!';
return message;
}
클로저란?
외부함수의 실행이 끝났지만 내부함수를 외부함수 밖에서 실행해서 외부함수에 접근할 수 있는 형태의 함수로 이 때 렉시컬 스코프를 이용함렉시컬 스코프 - 함수가 호출된 위치가 아닌 함수가 정의된 위치에 따라 상위 스코프가 결정됨
let age = 27;
let name = 'jin';
let height = 179;
function outerFn() {
let age = 24;
name = 'jimin';
let height = 178;
function innerFn() {
age = 26;
let name = 'suga';
return height;
}
innerFn();
//age의 값은? --- 1
//name의 값은? --- 2
return innerFn;
}
const innerFn = outerFn();
//age의 값은? --- 3
//name의 값은? --- 4
//innerFn 함수 호출 후 리턴값은? --- 5
배열이나 객체와 같은 참조 자료형의 경우 다른 변수에 이 객체를 할당하면 값 자체가 아닌 주소가 전달되어 두 객체는 같은 주소값을 가리키는데 이를 Shallow copy(얕은 복사)라고 함 반면, 주소를 공유하지 않고 값 자체를 복사해서 다른 변수에 대입하는 것을 Deep copy(깊은 복사)라고 함
그렇다면 배열이나 객체는 깊은 복사가 불가능할까?
Object.assign(target, ...sources) // 메소드 사용 방식
Object.assign() 메서드를 이용하면 객체의 속성 값을 복사할 수 있고 두 객체의 주소값은 달라짐 하지만 주의할 점은 객체가 1차원 객체일 경우만 깊은 복사가 가능하다는 점임 예를 들어 객체 안에 또 다른 객체가 요소로 들어가있는 2차원 이상의 객체일 경우 내부의 객체는 주소만을 공유함 따라서 Object.assign() 메서드를 통한 깊은 복사 가능 여부를 묻는다면 정확하게는 '아니다'라고 답할 수 있음
객체의 깊은 복사와 관련하여 대표적으로 JSON.parse(JSON.stringify(obj)) 사용 방법이 알려져 있음
한계: 자바스크립트의 일부 내장 객체나 bigint, 함수와 같이 JSON.stringify가 처리할 수 없는 객체들(즉, 문자로 바꿀 수 없는 객체들)을 만나면 이 역시 깊은 복사가 불가능함
객체에 다른 객체를 참조(주소값)하는 속성이 있는 경우 원본 객체의 속성과 병합본 대상 객체가 동일한 객체를 참조하므로 스프레드 연산자를 이용한 병합 역시 shallow copy로 볼 수 있음
<오늘의 일기>
새로운 방식으로 도전해봤던 페어 프로그래밍. 처음에는 낯설게 느껴져 버벅거리기도 했지만 내가 부족한 점들을 페어를 통해 보완하기도 하고 내가 알고 있는 부분을 페어에게 공유하며 진행하다보니 어지럽게 흩어져 있던 여러 개념들이 조금씩 정리되는 것 같았다. 특히 마지막에 과제 제출하는 순간까지 당황하던 나에게 큰 도움을 준 페어님께 너무 감사했다.
공부하면 할수록 내가 아는 것과 모르는 것을 구분할 수 있는 것이 얼마나 중요한 일인지 깨닫게 된다. 앞으로 더 많은 것들을 배우며 모든 지식을 다 아는 사람보다 내가 무엇을 알고 모르는지 잘 구분할 수 있는 사람이 되어야겠다.(세상의 모든 지식이 다 내 머릿속에 있다면 좋겠지만 그건 현실적으로 불가능하니까..ㅎ)