JavaScript의 자료형과 JavaScript만의 특성은 무엇일까?
느슨한 타입(loosely typed)의 동적(dynamic)언어
자바스크립트는 다른 언어와 다르게 변수 선언시 따로 자료형을 지정하지 않는다.
대입되는 데이터의 타입에 따라서 내부적으로 자동으로 변경되기 때문에
비교적 다른 Strong type의 언어에 비해 변수 선언이 자유로운데
이것을 느슨한 타입(정해진 데이터 타입의 선언 없이)의 동적언어(대입되는 데이터에
따라 동적으로 설정되는)라고 한다.
JavaScript 형변환
자바스크립트의 형반환은 암시적변환과 명시적 변환 두가지로 나뉜다.
암시적 변환 : 자바 스크립트 엔진이 판단하여 필요에 따라 자동으로 데이터 타입이 변경되는 것
더하기연산자는 숫자/문자열보다 우선시되기 때문에 문자열과 만나면 문자형으로 변환된다. 이외의 연산자(-,*,/,%)은 문자형보다 숫자가 우선시 되기 때문에 숫자형으로 사용할 수 있다.
동치연산자 ==는 boolean 값으로 True/ False 만 반환한다.
명시적 연산자 : 개발자가 필요에 따라 의도적으로 데이터 타입을 변환시키는 것
'Object()/ Number()/ String()/ Boolean ... '함수에 데이터 값을 삽입해서 설정한 Type으로 강제적 변환을 시킨다.
==, ===
자바 스크립트에서 사용하는 두가지 종류의 동치연산자
'==' 연산자(동등연산자)는 동등연산자로 비교되는 두 피연산자들의 자료형에 상관없이 강제 형변환 후 비교하는 방식이며
'==='(일치연산자) 은 형 변환없이 두 피연산자의 값을 비교한다.
보다 정확한 비교를 원한다면 '===' 일치 연산자를 사용해야된다.
느슨한 타입(loosely typed)의 동적(dynamic) 언어의 문제점은 무엇이고 보완할 수 있는 방법에는 무엇이 있을지 생각해보세요.
동적언어의 경우 Strong 타입에 비해 자료 변형에 대한 위험이 높으며(+를 제외한 연산자와 결합시 의도치 않은 데이터 변형이 일어남) 내부적으로 데이터 타입을 지정하기 때문에 타입으로 오류가 발생된다면 디버그하기 어렵다는 단점이 있다.
undefined와 null의 미세한 차이들을 비교해보세요.
undefined은 변수는 이미 지정이 되어있지만 값이 할당되지 않은 것을 의미하며,
null은 변수는 존재하지만 값이 null이라는 자료형이 값으로 할당이 된 상태를 의미한다.
JavaScript 객체와 불변성
기본형 데이터와 참조형 데이터
기본형 데이터 (Primative Type)는 데이터의 실제 값을 그대로 메모리에 할당하여 고정된 크기로 사용하는 방식이다.
데이터 자체를 저장하는 것이기 때문에 불변적인 특징을 가지고 있다.
문자형(String) : 문자나 숫자를 큰따옴표("")또는 작은 따옴표('')를
감싸서 표현하는 방식
숫자형(Number) : 숫자타입이며 만약 큰 따옴표("")가 숫자를 감싸고 있다면 숫자가 아닌 문자형 데이터
논리형(Boolean) : 참/거짓 두 가지로 데이터를 비교할 때 사용
빈 데이터(Undefined)
참조형 데이터 (Reference Type)는 기본형 데이터들의 집합이다. 값이 저장된 주소값을 할당하는 형식으로 주소값을 통해 각각의 값이 연결되어있는 형태이다.
객체(Object)
배열 (Array)
정규표현식 (Function RegExp)
Map ... 등등
불변 객체를 만드는 방법
원본 훼손에 대한 위험에 노출(보든 변수가 같은 주소공간을 바라보기 때문에)되어 있어 자바스크립트에서는 일부 객체에 대해 불변객체 선언 후 접근을 제한하고 있다.
ES6 이후 문법에서는 const라는 키워드를 이용해 상수 개념을 도입해 불변객체 속성을 제공한다.
원본 객체 내부의 프로퍼티(값)들을 복사한 새로운 객체로 생성하여 변수에 할당해주는 방식이다.
const studentInfo = function(name, info....){
......
}
student1 = studentInfo(.....)
student2 = studentInfo(.....)
student3 = studentInfo(.....)
얕은 복사와 깊은 복사
얕은복사 : 객체를 복사할 때 원래값과 복사된 값이 같은 참조(주소값을 복사)를 가리키고 있는 것을 의미
깊은 복사 : 객체안에 객체가 있을 경우에도 원본과의 참조가 완전히 끊어진 객체(실제 객체의 값을 복사)를 의미.
호이스팅과 TDZ는 무엇일까?
스코프, 호이스팅, TDZ
스코프 : 변수에 접근할 수 있는 범위를 일컫는다. glodal/local 두가지 타입으로 나뉜다.
전역 스코프(Global Scope)는 전역에 선언되어있어 어느 곳에서든지 변수에 접근할 수 있다.
지역 스코프(Local Scope)는 해당 지역에서만 접근할 수 있어 지역을 벗어난 곳에서는 접근할 수 없다.
호이스팅 : 함수 실행문이 함수 선언문보다 위에 있어도 실행될 수 있도록 선언들을 모두 끌어올리는 것을 의미
TDZ(Temporal Dead Zone) : 스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 의미한다.
함수 선언문과 함수 표현식에서 호이스팅 방식 차이
함수를 사용하여 코드를 저장한 것을 함수 정의문이라고 하는데, 함수 정의문은 사용 방식에 따라서 함수 선언문과 익명함수로 나뉜다.
함수선언문
function 함수명(){
실행내용 코드
}
함수 선언문은 함수 사용에 가장 기본이 되는 기본형의 문법으로 함수명으로 메모리에 저장해두었다가 필요에 따라 호출이 되는 방식이며, 중복으로 함수를 사용할때 간단히 호출해서 편리하게 사용할 수 있다. 단, 메모리영역의 데이터를 항상 사용하고 있기 때문에 함수선언문이 많은 프로그램은 오버플로가 일어날 수 있다는 단점이 있다.
익명함수(함수명이 없는 함수)
참조변수 = function(){
실행내용 코드
}
익명함수는 함수명이 존재하지 않는 함수로 정의 즉시 실행이 되는 함수이다.
메모리에 따로 저장하지 않고 사용할때마다 즉시 실행이 되기 때문에 불필요한 메모리 낭비가 없다.
프로그램은 계층적 구조(위에서 아래로)이기 때문에 선언문보다 실행문이 먼저 작성이 되면 함수 실행이 불가하다.
그러나 자바스크립트에서는 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하여 사용할 수 있도록 하는데 이를 호이스팅(hoisting)이라 한다.
익명함수의 경우에는 메모리 할당없이 즉시 실행이 되는 함수다보니, 위와 같은 호이스팅 방식을 지원하지 않는다.
실행 컨텍스트와 콜 스택
실행 컨텍스트는 코드가 실행되기 위해 필요한 정보들을 가진 범위를 추상화하기 위해 객체 형태로 나타낸 것을 의미한다.
자바 스크립트 엔진은 코드 실행을 위해서 실행에 필요한 여러가지 정보를 가지고 있어야한다. (ex.. 전역변수/매개변수/ 스코프/this등등)
실행 컨텍스트가 활성화될 때, 자바스크립트 엔진은 필요한 정보들을 수집해서 실행 컨텍스트에 저장한다.
실행되는 순서대로 콜 스택(call stack)에 쌓았다가. 가장 위에 쌓여있는 정보들부터 순차적으로 실행하는 식으로 동일한 환경과 순서를 보장한다.
스코프체인 / 변수의 은닉화
스코프체인은 코드의 유효범위 (in Scope)안에 있는 변수를 정의하는 객체의 체인, 리스트를 의미한다.
자바 스크립트가 변수 값을 얻을 때, 유효범위에 해당되는 스코프 체인에서 변수를 찾는다.(스코프 체인은 객체의 리스트이기 때문에 해당되는 변수값이 발견될 때 까지 리스트 형식으로 서칭한다.)
스코프체인은 함수가 정의될 때 저장하고, 함수가 호출될 때 함수는 지역변수를 보관하는 새로운 객체를 만들면서, 그 객체를 기존에 만들어 둔 스코프 체인에 추가한다.
변수의 은닉화는 외부에서 직접적으로 데이터 변경을 할 수 없도록 변수에 대한 접근을 막는 방식으로 캡슐화라고도 한다.
자바스크립트는 클로저(Closure)를 사용하여 캡슐화를 사용한다.
function exClosure(){
let name = 'boram'
return name;
}
console.log(name) error: name is not defined
const result = return name; ▶ 보람
console.log(result); 보람
name은 exClosure의 지역변수이기 때문에 외부에서 접근을 할 수 없다.
따라서 console.log로 name을 바로 접근하면 'name'이라는 변수가 없는 것처럼 정의되지 않았다고 출력된다.
그러나, 자바스크립트은 함수의 리턴과 동시에 클로저가 생성이 되기 때문에
return 값에 name을 담아낸다면 간접적으로 지역변수 name에 접근하여 출력을 할 수 있다.
실습과제