2. 자바스크립트 기본 (2)

protect-me·2021년 5월 28일
0
post-thumbnail

2.10 if와 '?'를 사용한 조건 처리


'if'문

if (true) alert( 'true' );
if (true) {
    alert( 'true' );
}

불린형으로의 변환

if (…) 문은 괄호 안의 표현식을 평가하고 그 결과를 불린값으로 변환

if (0) { // 0은 falsy 
  ...
}
if (1) { // 1은 truthy
  ...
}

조건부 연산자 ‘?’ (삼항 연산자)

'물음표(question mark) 연산자’라고도 불리는 '조건부(conditional) 연산자’를 사용하면 더 짧고 간결하게 변형할 수 있음
let result = condition ? value1 : value2;
평가 대상인 condition이 truthy라면 value1이, 그렇지 않으면 value2가 반환

다중 ‘?’(지양)

부적절한 ‘?’ (지양)

물음표?를 if 대용으로 쓰는 경우는 지양


2.11 논리 연산자


||(OR), &&(AND), !(NOT)

|| (OR)

인수 중 하나라도 true이면 true를 반환하고, 그렇지 않으면 false를 반환

alert( true || true );   // true
alert( false || true );  // true
alert( true || false );  // true
alert( false || false ); // false

첫 번째 truthy를 찾는 OR 연산자 ‘||’

🚨 왼쪽부터 피연산자를 불린형으로 변환 후 그 값이 true이면 연산을 멈추고 해당 피연산자의 변환 전 원래 값 을 반환.
🚨 피연산자 모두를 평가한 경우(모든 피연산자가 false로 평가되는 경우)엔 마지막 피연산자를 반환

1. 변수 또는 표현식으로 구성된 목록에서 첫 번째 truthy 얻기

let firstName = "";
let lastName = "";
let nickName = "바이올렛";

alert( firstName || lastName || nickName || "익명"); // 바이올렛

2. 단락 평가
truthy를 만나면 나머지 값들은 건드리지 않은 채 평가를 멈춤

true || alert("not printed"); // 출력 X
false || alert("printed"); // 출력 O

&& (AND)

alert( true && true );   // true
alert( false && true );  // false
alert( true && false );  // false
alert( false && false ); // false

첫 번째 falsy를 찾는 AND 연산자 ‘&&’

🚨 왼쪽부터 피연산자를 불린형으로 변환 후 값이 false이면 평가를 멈추고 해당 피연산자의 변환 전 원래 값 을 반환
🚨 피연산자 모두가 평가되는 경우(모든 피연산자가 true로 평가되는 경우)엔 마지막 피연산자가 반환

AND 연산자 &&의 우선순위는 OR 연산자 ||보다 높음
따라서 a && b || c && d(a && b) || (c && d)와 동일하게 동작합니다.

! (NOT)

  1. 피연산자를 불린형(true / false)으로 변환
  2. 1에서 변환된 값의 역을 반환

NOT을 두 개 연달아 사용(!!)하면 값을 불린형으로 변환


2.12 null 병합 연산자 '??'


요약
null 병합 연산자 ??를 사용하면 피연산자 중 ‘값이 할당된’ 변수를 빠르게 찾을 수 있습니다.
??는 변수에 기본값을 할당하는 용도로 사용할 수 있습니다.

// height가 null이나 undefined인 경우, 100을 할당
height = height ?? 100;

??의 연산자 우선순위는 대다수의 연산자보다 낮고 ?와 = 보다는 높습니다.
괄호 없이 ??를 ||나 &&와 함께 사용하는 것은 금지되어있습니다.

null 병합 연산자(nullish coalescing operator) ??를 사용하면 짧은 문법으로 여러 피연산자 중 그 값이 ‘확정되어있는’ 변수를 찾을 수 있음

a ?? b

  1. a가 null도 아니고 undefined도 아니면 a
  2. 그 외의 경우는 b
    x = (a !== null && a !== undefined) ? a : b;

즉, a가 확정되어있는 변수면 a 아니면 b

let firstName = null;
let lastName = null;
let nickName = "바이올렛";

// null이나 undefined가 아닌 첫 번째 피연산자
alert(firstName ?? lastName ?? nickName ?? "익명의 사용자"); // 바이올렛

'??'와 '||'의 차이

  • ||는 첫 번째 truthy 값을 반환
  • ??는 첫 번째 정의된(defined) 값을 반환

null과 undefined, 숫자 0을 구분 지어 다뤄야 할 때 이 차이점은 매우 중요한 역할

let height = 0;

alert(height || 100); // 100
alert(height ?? 100); // 0

연산자 우선순위

  • ??의 연산자 우선순위는 5로 꽤 낮음
  • 때문에 복잡한 표현식 안에서 ??를 사용해 값을 하나 선택할 땐 괄호를 추가하도록 권장
  • 안정성 관련 이슈 때문에 ??는 &&나 ||와 함께 사용하지 못함

2.13 while과 for 반복문


요약
while – 각 반복이 시작하기 전에 조건을 확인합니다.
do..while – 각 반복이 끝난 후에 조건을 확인합니다.
for (;;) – 각 반복이 시작하기 전에 조건을 확인합니다. 추가 세팅을 할 수 있습니다.
‘무한’ 반복문은 보통 while(true)를 써서 만듭니다. 무한 반복문은 여타 반복문과 마찬가지로 break 지시자를 사용해 멈출 수 있습니다.
현재 실행 중인 반복에서 더는 무언가를 하지 않고 다음 반복으로 넘어가고 싶다면 continue 지시자를 사용할 수 있습니다.
반복문 앞에 레이블을 붙이고, break/continue에 이 레이블을 함께 사용할 수 있습니다. 레이블은 중첩 반복문을 빠져나와 바깥의 반복문으로 갈 수 있게 해주는 유일한 방법입니다.

‘while’ 반복문

while (condition) {
  // 코드
  // '반복문 본문(body)'
}

condition(조건)이 truthy 이면 반복문 본문의 코드가 실행

‘do…while’ 반복문

do {
  // 반복문 본문
} while (condition);
  • 본문이 먼저 실행되고, 조건을 확인한 후 조건이 truthy인 동안엔 본문이 계속 실행
  • 본문을 최소한 한번이라도 실행

‘for’ 반복문

for (begin; condition; step) {
  // ... 반복문 본문 ...
}

for (let i = 0; i < 3; i++) { // 0, 1, 2
  alert(i);
}
  • begin이 한 차례 실행된 이후에, condition 확인과 body, step이 계속해서 반복 실행

구성 요소 생략하기

begin 또는 step 생략 가능

반복문 빠져나오기

  • 대개는 반복문의 조건이 falsy가 되면 반복문이 종료
  • 특별한 지시자인 break를 사용하면 언제든 원하는 때에 반복문을 빠져나올 수 있음

다음 반복으로 넘어가기

  • continue는 전체 반복문을 멈추지 않음
  • 대신에 현재 실행 중인 이터레이션을 멈추고 반복문이 다음 이터레이션을 강제로 실행(조건을 통과할 때).

break나 continue 같은 지시자는 삼항 연산자에 사용이 불가함

break/continue와 레이블

  • 여러 개의 중첩 반복문을 한 번에 빠져나와야 하는 경우
  • 아래 예시에서 break outer는 outer라는 레이블이 붙은 반복문을 찾고, 해당 반복문을 빠져나오게 함
outer: for (let i = 0; i < 3; i++) {
  for (let j = 0; j < 3; j++) {
    let input = prompt(`(${i},${j})의 값`, '');
    // 사용자가 아무것도 입력하지 않거나 Cancel 버튼을 누르면 두 반복문 모두를 빠져나옵니다.
    if (!input) break outer; // (*)
    // 입력받은 값을 가지고 무언가를 함
  }
}
alert('완료!');
  • continue 지시자를 레이블과 함께 사용하는 것도 가능. 두 가지를 같이 사용하면 레이블이 붙은 반복문의 다음 이터레이션이 실행

break와 continue는 반복문 안에서만 사용할 수 있고, 레이블은 반드시 break이나 continue 지시자 위에 있어야 함


2.14 switch문


예시

switch(x) {
  case 'value1':  // if (x === 'value1')
    ...
    [break]

  case 'value2':  // if (x === 'value2')
    ...
    [break]

  default:
    ...
    [break]
}

🚨 case문 안에 break문이 없으면 조건에 부합하는지 여부를 따지지 않고 이어지는 case문을 실행

여러 개의 "case"문 묶기

  • 코드가 같은 case문은 한데 묶을 수 있음
let a = 3;

switch (a) {
  case 4:
    alert('계산이 맞습니다!');
    break;

  case 3: // (*) 두 case문을 묶음
  case 5:
    alert('계산이 틀립니다!');
    alert("수학 수업을 다시 들어보는걸 권유 드립니다.");
    break;

  default:
    alert('계산 결과가 이상하네요.');
}

자료형의 중요성

  • switch문은 동등 비교(==)가 아닌 일치 비교(===)로 조건을 확인함
  • 때문에 자료형을 일치시킬 필요가 있음

2.15 함수


요약
함수 선언 방식으로 함수를 만들 수 있습니다.

function 함수이름(복수의, 매개변수는, 콤마로, 구분) {
  /* 함수 본문 */
}

함수에 전달된 매개변수는 복사된 후 함수의 지역변수가 됩니다.
함수는 외부 변수에 접근할 수 있습니다. 하지만 함수 바깥에서 함수 내부의 지역변수에 접근하는 건 불가능합니다.
함수는 값을 반환할 수 있습니다. 값을 반환하지 않는 경우는 반환 값이 undefined가 됩니다.
깔끔하고 이해하기 쉬운 코드를 작성하려면 함수 내부에서 외부 변수를 사용하는 방법 대신 지역 변수와 매개변수를 활용하는 게 좋습니다.
개발자는 매개변수를 받아서 그 변수를 가지고 반환 값을 만들어 내는 함수를 더 쉽게 이해할 수 있습니다. 매개변수 없이 함수 내부에서 외부 변수를 수정해 반환 값을 만들어 내는 함수는 쉽게 이해하기 힘듭니다.
함수 이름을 지을 땐 아래와 같은 규칙을 따르는 것이 좋습니다.
함수 이름은 함수가 어떤 동작을 하는지 설명할 수 있어야 합니다. 이렇게 이름을 지으면 함수 호출 코드만 보아도 해당 함수가 무엇을 하고 어떤 값을 반환할지 바로 알 수 있습니다.
함수는 동작을 수행하기 때문에 이름이 주로 동사입니다.
create…, show…, get…, check… 등의 잘 알려진 접두어를 사용해 이름을 지을 수 있습니다. 접두어를 사용하면 함수 이름만 보고도 해당 함수가 어떤 동작을 하는지 파악할 수 있습니다.

  • 함수를 이용하면 중복 없이 유사한 동작을 하는 코드를 여러 번 호출할 수 있음

함수 선언

function name(parameters) {
  ...함수 본문...
}
  
name(); // 함수 호출

지역 변수

  • 함수 내에서 선언한 변수인 지역 변수(local variable)는 함수 안에서만 접근 가능

외부 변수

  • 함수 내부에서 함수 외부의 변수인 외부 변수(outer variable)에 접근 가능, 수정 가능
  • 외부 변수는 지역 변수가 없는 경우에만 사용 가능
  • 함수 내부에 외부 변수와 동일한 이름을 가진 변수가 선언되었다면, 내부 변수는 외부 변수를 가림

매개변수

  • 함수에 전달된 인자는 지역변수에 복사 후 사용됨
  • 따라서 함수 내부에서 인자를 수정하더라도 변경 사항은 외부 변수에 반영되지 않음

인수(Argument)와 인자(Parameter, 매개변수) *추가

Argument | 인수
함수를 호출할 때, 사용되는 값

Parameter | 인자 | 매개변수
함수를 정의할 때, 외부로부터 받아들이는 임의의 값

function name(parameter) {
  ...함수 본문...
}
name(argument)

기본값

  • 매개변수에 값을 전달하지 않으면 그 값은 undefined
  • 매개변수에 값을 전달하지 않아도 그 값이 undefined가 되지 않게 하려면 '기본값(default value)'을 설정
function showMessage(from, text = "no text given") {
  alert( from + ": " + text );
}
showMessage("Ann"); // Ann: no text given

function showMessage2(from, text = anotherFunction()) {
  // anotherFunction()은 text값이 없을 때만 호출됨
  // anotherFunction()의 반환 값이 text의 값이 됨
}

매개변수 기본값을 설정할 수 있는 또 다른 방법

function showMessage(text) {
  if (text === undefined) {
    text = '빈 문자열';
  }
  ...
}

function showMessage2(text) {
  text = text || '빈 문자열';
  ...
}
  
function showCount(count) {
  alert(count ?? "unknown");
}

반환 값

  • 함수를 호출했을 때 함수를 호출한 그곳에 특정 값을 반환할 수 있음(return)
  • 실행 흐름이 지시자 return을 만나면 함수 실행은 즉시 중단되고 함수를 호출한 곳에 값을 반환

🚨 return과 값 사이에 줄을 삽입하면 return;으로 인식되어 undefined가 반환

함수 이름짓기

"show" – 무언가를 보여줌
"get…" – 값을 반환함
"calc…" – 무언가를 계산함
"create…" – 무언가를 생성함
"check…" – 무언가를 확인하고 불린값을 반환함

함수는 동작 하나만 담당
그 이외의 동작은 수행해선 안됨

함수 == 주석

  • 수를 간결하게 만들면 테스트와 디버깅이 쉬워집니다. 그리고 함수 그 자체로 주석의 역할까지 함
  • 함수를 활용하면 코드가 정돈되고 가독성이 높아짐

    이름만 보고도 어떤 동작을 하는지 알 수 있는 코드를 자기 설명적(self-describing) 코드라고 함


2.16 함수 표현식


요약
함수는 값입니다. 따라서 함수도 값처럼 할당, 복사, 선언할 수 있습니다.
“함수 선언(문)” 방식으로 함수를 생성하면, 함수가 독립된 구문 형태로 존재하게 됩니다.
“함수 표현식” 방식으로 함수를 생성하면, 함수가 표현식의 일부로 존재하게 됩니다.
함수 선언문은 코드 블록이 실행되기도 전에 처리됩니다. 따라서 블록 내 어디서든 활용 가능합니다.
함수 표현식은 실행 흐름이 표현식에 다다랐을 때 만들어집니다.
함수를 선언해야 한다면 함수가 선언되기 이전에도 함수를 활용할 수 있기 때문에, 함수 선언문 방식을 따르는 게 좋습니다. 함수 선언 방식은 코드를 유연하게 구성할 수 있도록 해주고, 가독성도 좋습니다.
함수 표현식은 함수 선언문을 사용하는게 부적절할 때에 사용하는 것이 좋습니다.

  • 자바스크립트는 함수를 특별한 종류의 값으로 취급합니다. 다른 언어에서처럼 "특별한 동작을 하는 구조"로 취급되지 않음
// 함수 선언
function sayHi() {
  alert( "Hello" );
}

// 함수 표현식
let sayHi = function() {
  alert( "Hello" );
};
  • 함수는 값이기 때문에 alert를 이용하여 함수 코드를 출력할 수 있음
function sayHi() {
  alert( "Hello" );
}

alert( sayHi ); // 함수 코드가 보임
  • 자바스크립트는 괄호가 있어야만 함수가 호출
function sayHi() {
  alert( "Hello" );
}

alert( sayHi() ); // Hello, undefined
// 함수 내부에서 'Hello'를 alert하고, 
// sayHi()의 return 값이 없기 때문에 undefined를 alert 

콜백 함수

  • 함수를 값처럼 전달하는 예시
function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

function showOk() {
  alert( "동의하셨습니다." );
}

function showCancel() {
  alert( "취소 버튼을 누르셨습니다." );
}

// 사용법: 함수 showOk와 showCancel가 ask 함수의 인수로 전달됨
ask("동의하십니까?", showOk, showCancel);
  • 익명함수 : 이름 없이 선언한 함수
function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

ask(
  "동의하십니까?",
  function() { alert("동의하셨습니다."); },
  function() { alert("취소 버튼을 누르셨습니다."); }
);

함수 표현식 vs 함수 선언문

  • 함수 표현식은 실제 실행 흐름이 해당 함수에 도달했을 때 함수를 생성. 따라서 실행 흐름이 함수에 도달했을 때부터 해당 함수를 사용할 수 있음.

  • 함수 선언문은 함수 선언문이 정의되기 전에도 호출할 수 있음. 따라서 전역 함수 선언문은 스크립트 어디에 있느냐에 상관없이 어디에서든 사용할 수 있음

  • 엄격 모드에서 함수 선언문이 코드 블록 내에 위치하면 해당 함수는 블록 내 어디서든 접근할 수 있음. 하지만 블록 밖에서는 함수에 접근하지 못함

조건에 따라 함수를 선언해야 한다면 함수 표현식을 사용


2.17 화살표 함수 기본


요약
화살표 함수는 본문이 한 줄인 함수를 작성할 때 유용합니다. 본문이 한 줄이 아니라면 다른 방법으로 화살표 함수를 작성해야 합니다.
중괄호 없이 작성: (...args) => expression – 화살표 오른쪽에 표현식을 둡니다. 함수는 이 표현식을 평가하고, 평가 결과를 반환합니다.
중괄호와 함께 작성: (...args) => { body } – 본문이 여러 줄로 구성되었다면 중괄호를 사용해야 합니다. 다만, 이 경우는 반드시 return 지시자를 사용해 반환 값을 명기해 주어야 합니다.

  • 인자 arg1..argN를 받는 함수 func. 함수 func는 화살표(=>) 우측의 표현식(expression)을 평가하고, 평가 결과를 반환
// 기존 함수
let func = function(arg1, arg2, ...argN) {
  return expression;
};

// 화살표 함수
let func = (arg1, arg2, ...argN) => expression
  • 인수가 하나밖에 없다면 인수를 감싸는 괄호를 생략
    let double = n => n * 2;

  • 인수가 하나도 없을 땐 괄호를 비워놓음. 다만, 이 때 괄호는 생략할 수 없음
    let sayHi = () => alert("안녕하세요!");

본문이 여러 줄인 화살표 함수

let sum = (a, b) => {  // 중괄호는 본문 여러 줄로 구성되어 있음을 알림
  let result = a + b;
  return result; // 중괄호를 사용했다면, return 지시자로 결괏값을 반환해야 함
};

2.18 기본 문법 요약


코드 구조

  • 여러 개의 구문은 세미콜론을 기준으로 구분할
  • 세미콜론 자동 삽입(automatic semicolon insertion)
  • 세미콜론 자동 삽입 예외 : []의 앞

엄격 모드

  • 코드 최상단 'use strict'

변수

  • let
  • const – 한 번 값을 할당하면 더는 값을 바꿀 수 없는 상수를 정의
  • var – 과거에 쓰이던 키워드로 자세한 내용은 추후에 다룰 예정
  • 명명 규칙 : 숫자와 문자를 사용하되 첫 글자는 숫자가 될 수 없으며 특수기호는 $와 _만 사용할 수 있음

8가지 기본 자료형

  • 정수와 부동 소수점을 저장하는 데 쓰이는 숫자형
  • 아주 큰 숫자를 저장할 수 있는 BigInt형
  • 문자열을 저장하는 데 쓰이는 문자형
  • 논리값 true/false을 저장하는 데 쓰이는 불린형
  • ‘비어있음’, '존재하지 않음’을 나타내는 null 값만을 위한 독립 자료형 null
  • 값이 할당되지 않은 상태를 나타내는 undefined 값만을 위한 독립 자료형 undefined
  • 복잡한 자료구조를 저장하는 데 쓰이는 객체형과 고유한 식별자를 만들 때 사용되는 심볼형

typeof 연산자는 값의 자료형을 반환

typeof의 예외 사항 두가지
1. typeof null == "object" // 언어 자체의 오류
2. typeof function(){} == "function" // 함수는 특별하게 취급

상호작용

  • prompt(question, [default])
  • confirm(question)
  • alert(message)

연산자

산술 연산자

* + - /와 나머지 연산자 %, 거듭제곱 연산자 **

할당 연산자

a = b 형태의 할당 연산자와 a *= 2 형태의 복합 할당 연산자

비트 연산자

32비트 정수로 변환하여 이진 연산을 수행

조건부 연산자

cond ? resultA : resultB

논리 연산자

AND 연산자 &&와 OR 연산자 ||은 단락 평가를 수행하고, 평가가 멈춘 시점의 값을 반환(꼭 true나 false일 필요는 없습니다).
NOT 연산자 !는피연산자의 자료형을 불린형으로 바꾼 후 그 역을 반환

null 병합 연산자

??는 피연산자 중 실제 값이 정의된 피연산자를 찾는 데 쓰임
a가 null이나 undefined가 아니면 a ?? b의 평가 결과는 a이고,
a가 null이나 undefined이면 a ?? b의 평가 결과는 b가 됨

비교 연산자

== 동등 연산자는 형이 다른 값끼리 비교할 때 피연산자의 자료형을 숫자형으로 바꾼 후 비교
< > <= >=도 마찬가지
일치 연산자 ===는 피연산자의 형을 변환하지 않고 비교

기타 연산자

반복문

while, do-while, for

while (condition) {
  ...
}

do {
  ...
} while (condition);

for(let i = 0; i < 10; i++) {
  ...
}

지시자 breakcontinue는 반복문 전체나 현재 실행 중인 반복을 빠져나가는 데 사용
레이블은 중첩 반복문을 빠져나갈 때 사용

'switch’문

'switch’문은 조건을 확인할 때 내부적으로 일치 연산자 === 를 사용해 비교를 진행

let age = prompt('나이를 알려주세요.', 18);

switch (age) {
 case 18:
   alert("Won't work"); // prompt 함수는 항상 문자열을 반환하므로, 이 case문엔 절대 도달할 수 없습니다.
   break;

 case "18":
   alert("낭랑 18세이시군요!");
   break;

 default:
   alert("어떤 case문에도 해당하지 않습니다.");
}

함수

  • 함수 선언문: 주요 코드 흐름을 차지하는 방식
  • 함수 표현식: 표현식 형태로 선언된 함수
  • 화살표 함수: =>
  • Argument | 인수 : 함수 사용
  • Parameter | 인자 | 매개변수 : 함수 정의



📚 참고 : javascript.info

profile
protect me from what i want

0개의 댓글