오늘 한 것
타입 변환과 단축 평가
자열 타입으로 변환
1.toString()
→ 중의적 표현이라서 문맥에 따라 숫자 뒤의 .
은 소수점으로 인식(1).toString()
으로 해야한다.
원시값과 객체의 비교
원시값
1 | // y에는 x를 평가하여 x의 값을 참조하여 값을 전달한다. (값에 의한 전달) |
원시값은 변경 불가이다.
변수값 변경은 ‘재할당’이다. 변수값 변경과 원시값 변경은 다른 의미이다.
상수는 단 한 번만 할당이 허용되는 변수이므로 상수와 변경 불가능한 값을 동일시하는 것은 곤란하다. 상수는 재할당이 금지된 변수일 뿐이다.
값에 의한 전달
1 | var score = 80; |
score의 80이 평가되어 score의 값 80을 복사한 후 메모리에 마련한 뒤 copy에 할당해 준다.
객체
객체는 프로퍼티의 개수가 정해져 있지 않으며, 동적으로 추가되고 삭제할 수 있다. 또한 프로퍼티의 값에도 제약이 없다. 따라서 객체는 원시값과 같이 확보해야 할 메모리 공간의 크기를 사전에 정해 둘 수 없다.
클래스 기반 객체 지향 언어는 객체에 할당된 메모리량을 정의한 클래스를 이용해 알 수 있다. 하지만 프로토타입 기반 객체 지향 언어는 객체의 할당 메모리량을 알 수 없다.
만약 객체가 원시값 처럼 동작한다면 메모리 소비가 매우 많다. → 변경 불가능한 값을 변경을 위해서는 복사한 값에 대한 새로운 메모리 공간이 필요하기 때문이다.
1 | var person = { |
1 | var person = { |
위 두 상황은 같은 과정일까? → 물론 아니다. 전자는 프로퍼티 값만을 갱신해주는 행위지만, 후자는 person 식별자에 새로운 객체 생성해서 참조해주는 것이다.
1 | var person1 = { |
person1과 person2의 변수 값은 객체의 참조 주소이다. 물론 person1과 person2는 내용이 같을 뿐 다른 객체이기에 참조 주소도 다르다.
반면 person1.name과 person2.name은 모두 원시값 문자열 ‘Lee’의 표현식이기 때문에 같은 값으로 평가된다.
얕은 복사와 깊은 복사
1 | // 얕은 복사 예 |
얕은 복사는 항상 조심해야한다.
깊은 복사를 해야 객체의 불변성을 얻을 수 있다. 하지만 깊은 복사는 퍼포먼스 측면에서 좋지 않기 때문에 대부분 얕은 복사를 기본으로 한다.
깊은 복사를 사용하고 싶다면 라이브러리를 사용해는 것이 좋다.
1 | const o = { |
함수
1 | // 변수에 함수 리터럴을 할당 (함수 표현식) |
;
이 붙는 것은 표현식이라는 것이다. 값으로 평가되는 함수 리터럴이다. 함수 리터럴은 변수에 참조하기 직전에 생성한다.(함수 선언문은 runtime 전에 정의됨)- 함수 이름
add
는 함수 몸체 내에서만 참조할 수 있는 식별자다.(함수 이름 생략 가능) - 함수가 객체라는 사실은 함수형 프로그래밍이 가능하다는 말이다. 함수가 객체가 아니라면 함수형 프로그래밍이 불가능하다.
1 | // 함수 선언문(function declaration/function statement) |
선언문은 익명함수가 불가능하고 ;
가 붙지 않으며 표현식처럼 값으로 평가되지 않는다. 값으로 평가되는 문맥에서는 함수는 표현식이다.
함수 호이스팅
1 | // 함수 호이스팅 |
가변인자 함수
1 | function sum() { |
argument는 유사배열로서 인자가 내부에 모두 저장되기 때문에 가능하다.
오늘 느낀 것
슬슬 어렵다. 그래도 본격적으로 공부하니까 재밌다.
배우는 것이 많다. 배움에서 끝내지 말고 학습하자.