2주차) JavaScript에 대해서
JavaScript의 자료형
JavaScript의 8가지 기본 자료형
숫자형(number) - 정수, 부동 소수점 숫자 등의 숫자를 나타낼 때 사용한다. 정수의 한계는 ± 2의 53 제곱까지 가능하다.
Bigint형 - 길이 제약 없이 정수를 나타낼수 있다.
문자형 - 빈 문자열이나 글자들로 이루어진 문자열을 나타낼 때 사용한다. 단일 문자를 나타내는 별도의 자료형은 없다.
boolean형 - true, false를 나타낼 때 사용한다. Bigint값은 정수 리터널 끝에 n을 붙이면 만들 수 있다.
null형 - null 값만을 위한 독립 자료형이다. '존재하지 않는(nothing)'값, '비어있는(empty)'값, '알 수 없는(Unknown)'값을 나 타내는데 null은 알 수 없는 값을 나타낸다. 비교결과를 저장할 때도 사용한다.
undefined형 - '값이 할당되지 않는 상태' 를 나타낼 때, 변수는 선언했지만 값은 할당하지 않았을 때, 변수는 선언했지만 값을 할당하지 않았을 때, 개발자가 변수에 undefined를 명시적으로 할당할수 있다.
객체형(object) - 특수한 자료형, 복잡한 데이터구조 표현시 사용, 속성의 집합이다.
심볼형(symbol) - 객체와 고유한 식별자(unique identifier)를 만들 때 사용한다.
JavaScript만의 특성
JavaScript는 일단 모든 변수를 공통적으로 var나 let으로 선언 가능하다. 변수 선언 후 재할당할 때 형변환이 가능하다.
느슨한 타입(loosely typed)의 동적(dynamic) 언어
JavaScript는 느슨한 타입(loosely typed)의 동적(dynamic)언어이다. JavaScript의 변수는 어떤 특정 타입과 연결되지 않으며, 모든 타입의 값으로 할당 및 재할당 가능합니다.
JavaScript 형변환
JavaScript는 타입이 매우 유연한 언어이다. 때문에 때로는 JavaScript 엔진이 필요에 따라 '암시적 변환'을 혹은 개발자의 의도에 따라 '명시적 변환' 을 실행한다. Java 같은 경우는
암시적 변환
암시적 변환이란 JavaScript엔진이 필요에 따라 자동으로 데이터타입을 변환시키는 것
명시적 변환
명시적 변환이란 개발자가 의도를 가지고 데이터 타입을 변환시키는 것
문자형을 숫자형으로 변환하기
var 변수 = parseInt(문자); - 문자를 정수형 숫자로 변환해준다.
var 변수 = parseFloat(문자); - 문자를 실수형 숫자로 변환해준다.
var 변수 = Nember(문자); - 문자를 정수 & 실수형 숫자로 변환해준다.
==와 ===의 차이점
JavaScript는 엄격한 비교와 유형변환 비교를 모두 지원하므로, 어떤 연산자가 어떤 비교조건에 사용되는지가 중요하다. ===는 변수 유형을 고려하는 반면, ==는 변수 값을 기반으로 유형을 수정한다.
'=='연산자를 이용하여 서로 다른 유형의 두 변수의 [값] 비교
'==='는 엄격한 비교를 하는 것으로 알려져 있다. ex) 값, 자료형 === 값, 자료형 ->ture
느슨한 타입(loosely typed)의 동적(dynamic) 언어의 문제점과 보완할 수 있는 방법
실행 도중에 변수에 예상치 못한 타입이 들어와 타입에러가 발생할 수 있다. 동적타입 언어는 런타임시 확인할 수 밖에 없기 때문에, 코드가 길고 복잡해질 경우 타입에러를 찾기 어렵다. 이런 불편함을 해소하기 위해 TypeScipt나 Flow 등을 사용할 수 있다.
undefined와 null의 차이
undefined
undefined는 변수를 선언하고 값을 할당하지 않은 상태, null은 변수를 선언하고 빈 값을 할당한 상태(빈 객체)이다. undefined는 자료형이 없는 상태다. 따라서 typeof를 통해 자료형을 확인해보면 null은 object로, undefined는 undefined가 출력되는 것을 확인할 수 있다.
null
어떤 값이 의도적으로 비어있음을 표현한다. undefined는 값이 지정되지 않은 경우를 의미하지만, null의 경우에는 해당 변수가 어떤 객체도 가리키고 있지 않다는 것을 의미한다.
JavaScript 객체와 불변성이란 ?
Immutability(변경불가성)는 객체가 생성된 이후 그 상태를 변경할 수 없는 디자인 패턴을 의미한다. Immutability은 함수형 프로그래밍의 핵심 원리이다. 불변 객체를 사용하면 복제나 비교를 위한 조작을 단순화 할 수 있고 성능 개선에도 도움이 된다. 하지만 객체가 변경 가능한 데이터를 많이 가지고 있는 경우 오히려 부적절한 경우가 있다.
기본형 데이터와 참조형 데이터
기본형 타입(Primitive type)
종류 : 논리형(boolean), 정수형(Int), 실수형(double), 문자형(char)
참조형 타입(Reference type)
종류 : 배열(Array), 클래스(Class), 인터페이스(Interface)
불변한 값 vs 변경 가능한 값
Javascript의 원시 타입(primitive data type)은 변경 불가능한 값(Immutable value)
Boolean
null
undefined
Number
String
Symbol (New in ECMAScript 6)
원시 타입 이외희 모든 값은 객체(Object)타입이며 객체타입은 변경 가능한 값(mutable value)이다. 즉, 객체는 새로운 값을 다시 만들 필요없이 직접 변경이 가능하다.
원시 값의 메소드는 복사본을 리턴하고, 배열(객체)의 메소드는 기존 배열 자체를 변경한다.
불변 객체를 만드는 방법
'불변 객체'란 '변하지 않는 객체' 즉 이미 할당된 객체가 변하지 않는다는 뜻을 가지고 있다.
얕은 복사와 깊은 복사
얕은 복사(Shallow Copy)
객체를 복사할 때, 해당 객체만 복사하여 새 객체를 생성한다.
복사된 객체의 인스턴스 변수는 원본 객체의 인스턴스 변수와 같은 메모리 주소를 참조한다.
따라서, 해당 메모리 주소의 값이 변경되면 원본 객체 및 복사 객체의 인스턴스 변수값은 같이 변경된다.
깊은 복사(Deep Copy)
객체를 복사할 때, 해당 객체와 인스턴스 변수까지 복사하는 방식.
전부를 복사하여 새 주소에 담기 때문에 참조를 공유하지 않는다.
JavaScript 엔진이란?
자바스크립트 엔진은 변수를 3단계로 나눠서 인지한다. 선언단계, 초기화단계, 할당단계로 이루어진다.
선언단계
(var, let, const)로 변수를 선언하는 단계, 이건 변수라고 엔진한테 알려주는 것
초기화단계
자바스크립트 엔진은 그 코드가 마치 전체 코드의 선두인것처럼 끌어올려 그 값을 저장할 메모리 공간을 따로 확보한다. 이를 변수 호이스팅이라 한다. var의 경우 선언시 초기화단계를 암묵적으로 undefined로 실행하고 let과 const는 변수만 저장해놓고 선언하기 전까지 아래에 나올 개념인 TDZ에 넣어둔다.
할당단계
할당단계는 앞에서 선언했던 변수에 값을 할당하는 단계이며 선언과 할당을 한 줄로 할 수 있다. 한 줄로 할 경우 초기화된 공간에 메모리를 넣는 것이 아니라 초기화된 공간을 없애고 새로운 공간에 메모리를 넣는다고 한다. 더이상 메모리를 사용할 필요가 없으면 Null을 할당한다.
호이스팅과 TDZ는 무엇일까 ?
스코프, 호이스팅, TDZ
스코프 : 변수, 함수, 클래스가 접근할 수 있는 유효 범위.
호이스팅 : 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미한다. 작업 실행 전에 변수와 함 수만 골라 따라 모아두는 것이다.
TDZ(Temporal Dead Zone) :
함수 선언문과 함수 표현식에서 호이스팅 방식의 차이
함수 선언식 (function declartion)
함수명이 정의되고 있고, 별도의 할당 명령이 없는 것
함수 전체를 호이스팅 합니다. 정의된 범위의 맨 위로 호이스팅 함수
함수 표현식(function Expression)
정의한 function을 별도의 변수에 할당하는 것
별도의 변수에 할당하게 되는데, 변수는 선언부와 할당부를 나누어 호이스팅하게 된다.
함수 선언식으로 작성한 함수는 함수 전체가 호이스팅 된다고 하는데, 전역적으로 선언하게 되면, 중복적으로 동명의 함수를 쓰게 되었을때, 원치 않는 결과를 초래할 수 있다. 이를 방지하려면 함수 표현식으로 작성하면 된다.
let, const, var, function 의 원리
1. var : 변수 재선언 가능
const, let : 변수 재선언 불가능
2. const : 변수 재할ㄷ랑 불가능(상수)
let : 변수 재할당 가능
3. var : functional-scope로 호이스팅됨
const, let : block-scope로 호이스팅됨
콜 스택(Call Stack)과 실행 컨텍스트(Execution Context)
콜스택(Call Stack)
Call은 호출을 뜻하며, stack은 출입구 하나뿐인 깊은 우물같은 데이터 구조이다. 따라서 callstack은 JavaScript가 함수 호출을 기록하기 위해 사용하는 우물 형태의 데이터 구조이다. 항상 맨 위에 놓은 함수를 우선으로 실행된다. 이런 식으로 JavaScript엔진은 가장 위에 쌓여있는 context와 관련있는 코드들을 실행하는 식으로 전체 코드의 환경과 순서를 보장한다.
실행 컨텍스트(Execution Context)
Execution Context는 JavaScript의 핵심 개념으로, 코드를 실행하기 위해 필요한 환경이다. 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다. JavaScript의 동적 언어로서의 성격을 가장 잘 파악할 수 있는 개념이다. 모든 코드는 특정한 Execution Context 안에서 실행된다. JavaScript는 어떤 Execution Context가 활성화되는 시점에 선언된 변수들을 위로 끌어올리고(Hoisting), 외부 환경 정보를 구성하고, 값을 설정하는 등의 동작을 수행하는데, 이로인해 다른 언어에서는 발생할 수 없는 특이한 현상들이 발생한다. JavaScript의 주요한 Execution Context에는 두가지가 있다. Global Execution Context, Fuction Execution Context
스코프 체인, 변수 은닉화
스코프 체인
스코프에 식별자가 없으면 상위 스코프에서 다시 찾아 나간다. 이 현상을 스포크 체인이라고하며 스코프가 중첩되어 있는 모든 상황에서 발생한다.
변수 은닉화
외부 객체로부터 '속성값(데이터, 멤버 변수값)'을 감추는 특성이다.
실습과제
콘솔에 찍힐 b 값을 예상해보고, 어디에서 선언된 “b”가 몇번째 라인에서 호출한 console.log에 찍혔는지, 왜 그런지 설명해보세요. 주석을 풀어보고 오류가 난다면 왜 오류가 나는 지 설명하고 오류를 수정해보세요.
결과
두 값이 다른 이유를 설명해보세요.
결과
==는 Equal Operator이고 ===는 Strict Equal Operator로 ==는 값이 같은지를 비교해서 같으면 ture, 다르면 fales라 한다.
===는 값과 값의 종류(Data Type)가 모두 같은지를 비교해서 같으면 ture, 다르면 false라 한다. 1=="1"은 숫자형과 문자형으로 형태는 다르지만 값은 같기에 ture이고 1==="1"에서 1은 숫자형이고 "1"은 문자형으로 형이 다르기에 false가 나서 차이가 난다.