Published on

모던 자바스크립트 Deep Dive 복습 3

Authors
  • avatar
    Name
    Byeong Jun An
    Twitter

제어문

제어문은 일반적으로 위에서 아래로 흐르는 코드를 인위적으로 변경하는 문을 말한다.

제어문의 종류

블록문: 0개 이상의 문을 중괄호()로 묶은 것으로, 블록문은 일반적으로 제어문이나 함수를 정의할 때 사용한다.

조건문: if ... else문과 switch문이 있으며 조건식의 평가 결과에 따라 코드 블럭의 실행을 결정할 수 있는 문이고 조건식은 불리언 값으로 평가될수 있는 표현식이다.

반복문: 반복문의 종류로는 for문, while문, do...while문이 있으며 조건식의 평가 결과가 참인 경우 코드 블록을 실행하고, 이후 조건식이 거짓이 될 때까지 코드 블록을 반복실행하게 되는데 이를 반복문이라 한다.

break문: 레이블 문, 반복문 또는 switch문의 코드 블록을 탈출하는 문이다.

참고로 레이블 문이란 식별자가 붙은 문을 말하고 아래 예시를 보자

// outer 라는 식별자가 붙은 레이블 for문
outer: for (var i = 0; i < 3; i++) {
  for (var j = 0; j < 3; j++) {
    //i+j > 3 이 조건에 들어오는 순간 break로 코드블록을 탈출하게 되는데
    //outer라는 식별자가 붙은 레이블 for문을 탈출한다.
    if (i + j > 3) break outer

    console.log(`inner [${i}, ${j}]`)
  }
}

console.log(`끝!`)

continue문: 반복문의 코드 블록 실행을 현 지점에서 중단하고 반복문의 증감식으로 실행 흐름을 이동시켜 continue문의 다음 코드를 실행시키지 않도록 한다. 단, break문처럼 반복문을 탈출하지는 않는다..

var string = '기러기 기지개 펴기'
var search = '기'
var count = 0

for (var i = 0; i < string.length; i++) {
  if (string[i] !== search) continue
  count++
}

console.log(count) // 4

Q&A

Q. 자바스크립트에서 for문이 중요한데 그 이유는?

A: 반복적인 작업을 효율적으로 처리 할 수 있고 배열이나 리스트의 요소를 순회하거나 특정 조건을 만족하는 요소를 찾는 용도로 쓸 수 있음

Q. for 문과 while문은 반복문이라는 점에서 동일합니다. 어떻게 구분해 사용해야 하나요?

A: for문은 몇번 돌아야 하는지 알때, while문은 몇번돌아야 하는 지 모를 때 써야합니다

Q. break 문과 continue 문의 차이는?

A: 둘 다 반복문 내에서 흐름을 제어하는 데 사용하는데 break문은 특정 조건이 됐을때 반복문을 완전히 종료시키고 싶을때, continue문은 특정 조건이 만족됐을때, 해당 반복 주기를 건너띄고 싶을 때 사용합니다.

타입 변환과 단축 평가

값의 타입을 변경하는걸 타입 변환이라고 하는데 기존 원시 값을 사용해 다른 타입의 새로운 원시 값을 생성한다. 그 이유는 원시 값은 변경 불가능한 값이기 때문에 기존 타입은 그대로 두고 다른 타입의 새로운 원시 값을 생성하게 된다.

암묵적 타입변환

개발자의 의도와는 상관없이 표현식을 평가하는 도중에 자바스크립트 엔진에 의해 암묵적으로 타입이 자동되는걸 암묵적 타입변환(implicit coercion) 또는 타입 강제 변환(type coercion) 이라고 한다.

문자열 타입으로 변환: 자바스크립트 엔진은 표현식을 평가할 때 코드 문맥에 부합하도록 암묵적 타입 변환을 실행한다. +연산자는 피연산자 중 하나 이상이 문자열일 때, 문자열 연결 연산자로 동작하고 자바스크립트 엔진은 문자열 연결 연산자 표현식을 평가하기 위해 문자열이 아닌 피 연산자를 문자열 타입으로 암묵적 타입 변환 한다. 문자열 타입으로 암묵적 타입 변환하는 대표적인 예는 변환할 원시값에 "" 와 같은 빈 문자열을 +해주는 것이다.

숫자 타입으로 변환: 산술 연산자의 역할은 숫자 값을 만드는 것이다. 따라서 산술 연산자의 모든 피연산자는 코드 문맥상 모두 숫자 타입이어야 한다. 그래서 자바스크립트 엔진은 산술 연산자의 피연산자 중에 숫자 타입이 아닌 피연산자를 숫자 타입으로 암묵적 타입 변환한다. 만약, 숫자 타입으로 변환이 불가능한 경우에는 산술 연산을 하지 못하기 때문에 표현식의 평가는 NaN이 된다. 숫자 타입으로 암묵적 타입 변환하는 대표적인 예는 +단항 연산자가 있다.

불리언 타입으로 변환: 제어문 또는 삼항 조건 연산자의 조건식은 불리언 값, 즉 논리적 참/거짓으로 평가 되어야 하는 표현식이다. 이에 자바스크립트 엔진은 조건식의 평가 결과를 불리언 타입으로 암묵적 타입 변환 한다. 이때, 자바스크립트 엔진은 불리언 타입이 아닌 값을 Truthy(참으로 평가되는 값) 또는 Falsy 값(거짓으로 평가되는 값)으로 구분한다. Falsy 값은 false, undefined, 0, null, NaN, 빈 문자열('')이 있다. 나머지는 Truthy한 값이다. 참고로 , []는 자바스크립트에서 참조 타입인데 빈 객체도 메모리 상에 존재하는 실제 객체로 간주된다. 따라서 객체는 항상 참조를 갖고 있으므로 Truthy한 값으로 보면 된다. 배열도 마찬가지

명시적 타입변환

개발자의 의도에 따라 명시적으로 타입을 변경하는 방법이다. String, Number, Boolean과 같은 표준 빌트인 함수를 new 연산자 없이 호출하는 방법,표준 빌트인 메서드를 사용하는 방법, 그리고 앞에서 본 암묵적 타입 변환을 이용하는 방법이 있다.

문자열 타입으로 변환: 문자열 타입이 아닌 값을 문자열로 변환하는 방법

  • String 생성자 함수를 new 연산자 없이 호출하는 방법,
  • object.prototype.toString
  • 문자열 연결 연산자를 이용하는 방법

숫자 타입으로 변환: 숫자 타입이 아닌 값을 숫자 타입으로 변환하는 방법

  • Number 생성자 함수를 new 연산자 없이 호출하는 방법,
  • parseInt, parseFloat 함수를 사용하는 방법(문자열만 숫자 타입으로 변환 가능)
  • +단항 산술 연산자를 이용하는 방법
  • *산술 연산자를 이용하는 방법

불리언 타입으로 변환: 불리언 타입이 아닌 값을 불리언 타입으로 변환하는 방법

  • Boolean 생성자 함수를 new 연산자 없이 호출하는 방법
  • !부정 논리 연산자를 두 번 사용하는 방법

단축평가

단축평가는 표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정을 생략하는 것을 말한다.

논리합(||) 은 두 개의 피연산자 중 하나만 true로 평가되어도 true를 반환한다.
만약 첫번째 피연산자가 true가 되면 두번째 피연산자가 true든 false든 상관없이 전체 표현식이 true로 평가된다. 따라서 두번째 연산을 할 필요가 없으므로 첫번째 피연산자를 그대로 반환한다.
그것과는 반대로 첫번째 피연산자가 false가 되면 두번째 피연산자에 따라 전체 표현식이 결정되니까 두번째 피연산자를 그대로 반환한다.
아래는 논리합의 단축평가 예시이다.

'red' || 'blue' // "red"
false || 'blue' // "blue"
'red' || false // "red"

논리곱(&&) 은 두 개의 피연산자가 모두 true로 평가 될때, true를 반환한다.
만약 첫번째 피연산자가 true가 되면 두번째 피연산자가 true인지 false 인지에 따라 전체 표현식이 평가되므로 두번째 피연산자를 그대로 반환한다. 반대로 첫번째 피연산자가 false가 되면 두번째 피연사자가 true인지 false인지 상관없이 무조건 false를 반환하므로 첫번째 피연산자를 반환한다.
아래는 논리곱의 단축평가 예시이다.

'red' && 'blue' // "blue"
false && 'blue' // "false"
'red' && false // "false"

결론적으로 논리합(||), 논리곱(&&) 연산자 표현식은 언제나 2개의 피연산자 중 어느 한쪽으로 평가됨을 알 수 있다.

단축평가로 if문 대체하기 어떤 조건이 Truthy 값(참으로 평가되는 값)일 때, 무언가를 해야한다면 논리곱(&&) 연산자 표현식으로 대체할 수 있다.

var cat = true
var message = ''

//주어진 조건이 true일 때
if (cat) message = '야옹'

//if문은 단축 평가로 대체 가능하다.
//hi가 true라면 message에 '야옹'를 할당
message = cat && '야옹'
console.log(message) // 야옹

어떤 조건식이 Falsy 값(거짓으로 평가되는 값)일 때, 무언가를 해야 한다면 논리합(||) 연산자 표현식으로 if문을 대체할 수 있다.

var cat = false
var message = ''

//주어진 조건이 false일 때
if (!cat) message = '멍멍'

//if문은 단축 평가로 대체 가능하다.
//catdl false라면 message에 '멍멍'을 할당
message = cat || '멍멍'
console.log(message)

옵셔널 체이닝 연산자: 옵셔널 체이닝 연산자인 (?.)는 좌항의 피연산자가 null 또는 undefined인 경우 undefined를 반환하고, 그렇지 않으면 우항의 프로퍼티 참조를 이어간다.

var elem = null

//elem이 null 또는 undefined이면 undefined를 반환하고,
//그렇지 않으면 우항의 프로퍼티 참조를 이어간다.
var value = elem?.value
console.log(value) // undefined

null 병합 연산자 null 병합 연산자 ??는 좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환한다. 주로 변수에 기본값을 설정할 때 유용하다.

//좌항의 피연산자가 null 또는 undefined이면 우항의 피연산자를 반환하고,
//그렇지 않으면 좌항의 피연산자를 반환한다.
var foo = null ?? 'default string'
console.log(foo) // "default string"

Q&A

Q. 문자열 타입으로 변환하는 방법은?

A:

  • new 없이 String 생성자 함수 사용
  • +연산자와 빈 문자열('') 사용
  • toString() 사용

Q. 숫자 타입으로 변환하는 방법은?

A:

  • new 없이 Number 생성자 함수 사용
  • +단항 산술 연산자 사용
  • *산술 연산자 사용

Q. Boolean 타입으로 변환하는 방법은?

A:

  • new 없이 Boolean 생성자 함수 사용
  • ! 부정연산자 두개 사용

Q. truthy값과 falsy 값이란? 모두 나열해 보세요

A: 조건문이나 논리 연산에서 값이 참 또는 거짓으로 평가되는 방식을 truthy, falsy값이라고 한다. falsy 값은 0, false, ''(빈 문자열), ull, undefined, NaN이 있다.

Q. 단축평가란?

A: &&(논리곱)연산자나 ||(논리합)연산자가 있을 때, 좌항과 우항의 피연산자 중에 하나의 항을 보고 반환되는 값을 찾아낼 수 있다면 더 이상의 찾는 과정을 안하고 해당 값을 반환하는 것

객체 리터럴

객체란 프로퍼티와 매개변수로 이루어진 집합체다.

프로퍼티

객체는 프로퍼티의 집합이며, 프로퍼티는 키와 값으로 구성된다. 프로퍼티 키의 경우 빈 문자열을 포함하는 모든 문자열 또는 심벌값으로 키 이름을 지을 수 있고 프로퍼티 값의 경우 자바스크립트에서 사용할 수 있는 모든 값을 사용할 수 있다.

단, 프로퍼티 키의 경우 왠만하면 식별자 네이밍 규칙을 준수하도록 짓는것이 좋은데 그렇게 하지 않으면 키 값을 ""로 묶어야 하고 키에 접근할때 []로만 접근 할 수 있기 때문이다.

메서드

자바스크립트에서 함수는 일급 객체로 값으로 취급할 수 있다. 때문에 프로퍼티 값으로 함수를 사용할 수 있는데 단순히 일반적인 프로퍼티와 구분하기 위해 객체에 묶여있는 함수를 메서드라 부르고 있다. 사실 그냥 프로퍼티로 불러도 된다.

프로퍼티 접근

프로퍼티에 접근하는 방법은 마침표 프로퍼티 접근 연산자(.)를 사용하는 마침표 표기법, 대괄호([]) 프로퍼티 접근 연산자를 사용하는 대괄호 표기법이 있다. 대괄호 표기법의 경우 대괄호 프로퍼티 접근 연산자 내에 따옴표로 감싸지 않은 이름은 식별자로 해석하기 때문에 반드시 따옴표로 감싼 문자열로 써야한다.

var person = {
  name: 'kim',
}

console.log(person[name]) //ReferenceError : name is not defined

Q&A

Q. 객체란?

A: 프로퍼티와 매개변수로 이루어진 집합체이며 프로퍼티는 키와 값으로 이루어져 있고 매개변수는 객체 내의 함수 프로퍼티를 말합니다.

Q. 객체는 왜 필요할까?

A: 관련있는 상태를 나타내는 값인 프로퍼티랑 그 프로퍼티를 사용하는 함수인 메서드를 하나로 묶어 사용하니까 구조적으로 쓰기 좋아지기 때문에

Q. 프로퍼티 키로 사용할 수 있는 값은?

A: 빈 문자열('')을 포함하는 모든 문자열과 심벌 값