사용자는 컴퓨터에게 명령을 하고, 컴퓨터는 수행한다.
이 과정을 flow라고 하고, 이것을 제어하는 것을 flow control이라고 생각하면 될 것 같다.
제어흐름의 종류
표현식(expression) : 유효한 코드 단위표현식 평가 -> 새로운 값을 생성 OR 기존 값을 참조
리터럴 표현식 : const a = "a"
함수 표현식 : const fun = function(){}
문 (statement) : 프로그램을 구성하는 최소 실행 단위ex)
변수 선언문 : let a ;
할당문 : a = "a"
함수선언문 : function 함수() {}
조건문 : if (true){}
블럭문 : { }
명령문들을 그룹으로 묶을 수 있는 블럭문
한 쌍의 중괄호로 묶어 표현
제어문 :
choice : if-else , switch
loop early exit : break
loop continuation : continue
subroutine exit : return
non-local control flow : try-catch , throw, generator, async
반복문 :
conditinal loop : while, do..while
general loop : for
collection loop : for...in , for...of
조건문 : 일부 조건이 충족되는 경우에만 명령문을 수행한다.
if-else , switch 이 있다.
조건문에서, false, undefined, null, 0 , NaN, "" 은 모두 False의 값으로 평가된다.
또한, 조건문을 중첩해서 사용하면 가독성이 떨어지고 이해하기 어려워지므로,
return 등을 이용하여 guard clauses 형태로 구현한다.
while문 :
시작할때 조건을 평가 : while( ) { } - 본문이 실행되기 전, 조건을 평가한다.
마지막에 조건을 평가 : do { } while( ) - 본문이 실행된 후에, 조건을 평가한다.
for문 :
for(초기화 ; 조건식 ; 증감문;) 형태
ex)
for( let i = 0 ; i < 10 ; i++ ) {}
collection loop (Foreach):
for문과 다르게, 루프변수(카운터 ex. i )를 관리하지 않는다.
코드가 더 단순해질 수 있다.
for of, for in 등이 있다.
break문 : 프로그램 실행의 중단 기능을 수행한다.
가장 가까운 반복문, switch문을 종료시킨다.
continue문 : 현재 반복을 종료하고 (전체 루프를 종료시키는 게 아님), 다음 loop를 실행한다.
Exception : 런타임 때 발생할 수 있는 의도치 않은 상황
여기서 핸들링(handling)은 대응한다는 의미를 가지고,
컨트롤(control)은 예외를 예상하고 처리를 한다는 의미를 가진다.
즉, 개발자는 예외 상황을 핸들링하고 컨트롤해야한다.
예외의 원인은 주로 다음과 같다.
코드레벨에서 발생하는 Exception :
ECMAScript Error : 자바스크립트에서 발생하는 에러타입 - RangeError , ReferenceError, SyntaxError, TypeError 등
DOMException : Web API 에서 발생하는 에러타입 - NetworkError, AbortError, TimeoutError 등
그 외의 예외 :
개발자도 예상하지 못한 예외 상황에 대해서는, Error객체를 사용하여 직접 에러를 정의(new Error())하고 발생(throw)시킨다.
throw와 error 객체
throw : 예외를 발생시킬 때 사용한다. catch블럭에서, 발생한 에러를 핸들링한다.
throw가 실행되면, 에러 객체와 함께 에러가 throw되고, 현재 블럭의 실행이 중단되며, catch 블록으로 이동한다.
catch블록이 없으면 프로그램을 종료한다.
Error 객체 : Error객체를 정의하여 사용 가능하다.
사용방법 : new Error("에러 메시지")
속성 :
Error.message
Error.name
ex)
const customError = new Error("customError")
customError.message = "에러메시지"
customError.name = "에러이름"
try ...catch
try-catch는 이전 포스트에서 공부하였었다.
try-catch를 통해 Error가 발생했을 때, 에러를 핸들링한다.
객체 : 속성을 가진 독립적인 개체 ( = 속성으로 구성된 집합 )
객체는 키와 값을 가진다. (key-value)
값을 사용할 땐, 다음의 2가지 방법을 사용할 수 있다.
메서드 : 객체에 속해있는 함수이다. 다음의 방법으로 정의가 가능하다.
const obj = {
property1 : function() {
console.log("1")
}
property2() {
console.log("2")
}
}
obj.property1( ) ;
obj.property2( ) ;
객체의 생성 방법 3가지
function Person (name, age) {
this.name = name ;
this.age = age ;
}
let a = new String() // 인스턴스 생성
let b = new Person() // 인스턴스 생성
const Person = {
name : "Lee",
age : 25,
getName : function() {}
}
const Lee = Object.create(Person) ;
객체의 특징 :
객체 속성(properties) 나열 방법 :
for...in 사용
Object.keys(객체) : 열거 가능한 속성 이름을 배열로 반환
Object.getOwnPropertyNames(객체) : 모든 속성 이름을 배열로 반환
ex)
const parent = {
age : 55,
gender : 'male'
}
function Child(name) {
this.name = name ;
}
Child.prototype = parent ;
const child = new Child('Kim') ;
Object.keys(child) // ['name']
Object.getOwnPropertyNames(child) // ['name']
for ( Const key in child ) {
console.log(key);
} // name , age, gender
속성을 삭제하는 방법 - delete
delete 속성이름
delete는 반환값으로 true(성공), false(실패)을 반환한다.
데이터 처리 - 객체와 빌트인 객체 : 객체간 비교와 복사
객체의 비교와 복사
객체는 참조타입이므로, 객체를 비교 및 복사할 때 고려해야할 사항이 있다.
속성이 같지만, 다른 메모리를 참조하는 객체를 서로 비교하면, false가 나온다. 다음의 예시를 보자.
ex)
let foo = {
name = "lee"
}
let bar = {
name = "lee"
}
console.log( foo === bar ) // false
console.log( foo === foo ) // true
또한, 동일한 객체를 생성하고 싶을 때, 단순히 다른 변수에 객체를 할당하게 되면 동일한 메모리주소가 할당된다.
let a = {
name : "lee"
}
let b = a
b.name = "kim"
console.log(a.name) // kim
따라서, 객체의 값을 복사해서 사용하고 싶을 때에는, 얕은 복사와 깊은 복사를 사용한다.
얕은 복사 : 복사된 객체의 속성 중 한 개 이상 같은 참조를 하고 있을 때 사용한다.
방법 : Object.assign({ }, 객체) 또는 { ...객체 }
얕은 복사의 경우, 객체안의 객체(중첩된 객체 - Nested Object)의 경우에는 같은 메모리를 참조하므로 주의해야 한다.
ex)
let person = {
name : " ",
address : { country : "Korea" }
}
let a = Object.assign({ }, person)
let b = {...person}
a.name = "kim" //
b.name = "park" // a.name = "kim", b.name = "park"
a.address.country = "Japan" // a.address.country = "Japan" , b.address.country = "Japan"
깊은 복사 : 복사된 객체의 속석 중 같은 참조를 하고있는 속성이 아예 없을 때 사용한다.
방법 :
자바스크립트 객체의 분류 :
ECMAScirpt의 표준 빌트인 객체 :
기초 객체 : Object, Function , Boolean , Symbol
오류 객체 : Error
숫자 및 날짜 : Number, BigInt, Math, Date
텍스트 처리 : Regex(정규표현식), String(문자열)
Collection : Array(index기반), Map, Set (Key 기반) 등
구조화된 데이터 객체 : JSON
정규표현식은, 문자열에서 특정 문자 조합을 찾기 위한 패턴이다. 정규식이라고도 부른다.
형태는 다음과 같다.
/pattern/flags
ex)
/\w+\s/g
pattern 부분은, 단순패턴과 특수문자(assertion, 문자클래스, 그룹과 범위, 수량자, 유니코드 속성 이스케이프)를 사용할 수 있다.
flag부분에는 flag속성값을 작성한다.
정규표현식 생성방법 :
리터럴표기법 :
평가할때 정규 표현식을 컴파일한다.
정규식이 변하지 않을 때 사용한다.
형태 : /pattern/flag
RegExp 객체 :
런타임 때 컴파일된다.
패턴이 변할 가능성이 있을때, 알수없는 데이터에서 정규식을 가져올 때 사용한다.
형태 : new RegExp(/pattern/, flag)
RegExp 객체는, String의 메소드인 match, matchAll, search, replace, replaceAll, split 등을 사용할 수 있다.
collection이란, 데이터 항목들의 그룹을 의미한다.
프로그래밍에서는 전반적으로 list, set, tree, graph 등이 있고,
자바스크립트에서는 indexed collection, keyed collection이 존재한다.
indexed collection : index값을 기준으로 정렬된 데이터 집합을 의미한다. - Array, TypedArray
keyed collection : Key값을 기준으로 정렬된 데이터 집합을 의미한다. - Map, Set
indexed collection - Array :
new Array(arrayLength) 를 통해 길이가 지정된 빈 배열 만들 수 있다.
new Array(val1, val2) 를 통해 요소가 지정된 배열을 만들 수 있다.
자바스크립트는 배열을 Object처럼 사용하여,
index값을 속성(property)이름으로 사용하고,
그에 매핑되는 값을 이용하는 key-value처럼 사용한다.
keyed collection - Map, WeakMap
Map은 Key와 Value가 매핑되어있다.
const foo = new Map() ;
foo.set(key, value) ;
이 때, Key는 유니크한 값을 가진다.
Map과 Object의 차이
Map :
모든 값을 키로 활용 가능하다.
기본 속성들이 없으므로, default 속성과의 충돌이 발생할 일이 없다.
size 인스턴스 속성으로 객체의 크기를 얻을 수 있다.
Map은 추가된 순서대로 반복된다.
Map은 iterable이 가능하다. (forEach 사용 가능)
키,값의 추가/제거에 성능이 좋다.
직렬화, 구문분석을 제공하지 않는다.
Object :
string, Symbol 데이터 타입만 속성과 데이터로 가질 수 있다.
Object prototype의 기본속성과 동일한 키를 생성할 때 충돌이 발생한다.
객체의 크기는 수동으로 추적해야 한다.
순서의 보장이 안된다.
iterable이 불가능하다.
키,값의 추가 및 제거에 성능이 좋지 않다.
직렬화, 구문분석을 제공한다. (JSON.stringfy, JSON.parse)
map은 get과 set을 이용하여 데이터에 접근하고, 변경한다.
WeakMap : 키에 대한 강력한 참조를 생성하지 않는 map 자료형이다.
키는 object만을 허용하고, 객체 정보를 노출하지 않는다.
따라서, 객체의 사적인 정보를 저장하거나, 상세 구현내용을 숨기기 위해 사용한다.
keyed collection - Set, WeakSet
Set : 모든 값들의 집합
입력된 순서에 따라 요소의 반복처리가 가능하다. 즉, for...of 를 통해 순회가 가능하다.
배열->Set / Set-> 배열로 변환이 가능하다.
배열의 경우에는 indexOf를 사용하여 값의 포함 여부를 확인하는데, 퍼포먼스가 느리고,
Set의 has method가 퍼포먼스가 더 좋음.
또한, 배열은 요소를 제거할 때 배열을 잘라내고 이동시켜야한다. ( 배열의 요소를 삭제하면, 뒤의 요소들을 옮기는 과정 필요)
Set은 delete method를 이용해 키를 바로 삭제가 가능하다.
요소를 찾을 때에도,
배열은 NaN을 indexOf로 확인 불가능하고,
Set은 NaN의 포함여부를 확인 가능하다.
WeakSet : 객체 컬렉션. 인자로 object값만을 허용한다.
다양한 환경 간에 데이터를 주고 받기 위해 직렬화 작업이 필요한데,
JSON은 직렬화를 지원한다.
직렬화(serialization) : 문자열로 변환하는 것 -> JSON.stringfy()
역직렬화(deserialization) : Object로 변환하는 것 -> JSON.parse()