당신이 놓친 자바스크립트 - 1. 자바스크립트 기본 (2)

piecemaker·2020년 12월 17일
1
post-thumbnail

'당신이 놓친 자바스크립트' 시리즈는 모던 Javascript 튜토리얼를 공부하며 필자가 자바스크립트에 대해 몰랐던 점이나 헷갈렸던 점들을 정리한 시리즈입니다. 모든 출처는 위 사이트에 있습니다.

본 포스팅에서는 이전 포스팅에 이어서 자바스크립트 기본 문법 중에서 쉽게 놓칠 수 있는 부분들을 다룹니다.

비교 연산자

  • 우리가 자바스크립트에서 '같은지'를 확인하기 위해 주로 사용하는 일치 연산자(===)를 제외한 모든 비교 연산자 (==, >, <, >=, <=)들은 비교하려는 값의 자료형이 다르면 이 값들을 숫자형으로 형변환 후 비교를 진행합니다.
alert( '01' >= 1 ); // true. '01'을 1로 형변환
alert( true < 0 ); // false. true를 1로 형변환
alert( '31' > true ); // true. '31'을 31로 형변환, true를 1로 형변환
  • 비교 연산자 사용 시 null은 0으로 형변환되고, undefined는 NaN으로 형변환됩니다. 하지만 여기에도 예외가 존재하는데, 바로 동등 연산자 ==를 사용할 때에는 피연산자가 undefined일 때에나 null일 때 형 변환을 하지 않는다는 것입니다. 이러한 예외가 == 연산자를 자바스크립트에서 잘 사용하지 않는 이유 중 하나입니다.
alert( null > 0 );  // false
alert( null == 0 ); // false. null이 0으로 형변환 된다면 true여야 한다.
alert( null >= 0 ); // true

논리 연산자

  • OR 연산자 ||를 여러 개 체이닝해서 사용하면, 첫 번째 truthy한 값을 찾았을 때 해당 피연산자의 변환 전 원래 값을 반환합니다. 피연산자를 모두 평가했음에도 truthy한 값을 찾을 수 없었을 경우, 마지막 피연산자를 반환합니다.
console.log( null || 0 || 1 ); // 1
console.log( undefined || 0 || null ); // 0. 모두 falsy이므로, 마지막 값인 null을 그대로 반환한다.

// true. alert 함수는 실행되지 않음.
console.log( true || alert("not printed") );

// undefined. alert 함수가 실행되며, 반환 값이 명시되지 않은 함수는 자동으로 undefined를 리턴한다.
console.log( false || alert("printed") );

// true. alert 함수가 undefined를 리턴하므로, alert 함수가 실행된 후 두 번째 피연산자인 true가 리턴됨.
console.log( alert("printed") || true ); 
  • AND 연산자 &&를 여러개 체이닝해서 사용하면, OR 연산자와는 반대로 첫 번째 falsy한 값을 찾았을 때 해당 피연산자의 변환 전 원래 값을 반환합니다. 모든 피연산자가 truthy한 값을 가지면, 마지막 피연산자를 반환합니다.
console.log( 1 && 0 ); // 0
console.log( 1 && 5 ); // 5

// undefined. alert 함수가 호출되면 falsy한 값을 리턴하므로, 연산자가 true까지 도달하지 않는다.
console.log( alert("printed") && true );

null 병합 연산자

  • null 병합 연산자 ??는 '값이 확정되어 있는 변수'를 찾을 때 사용합니다. 자바스크립트에서 undefined는 값이 할당되지 않았음을 의미하고, null은 값이 비어있음을 의미하죠. 따라서, a ?? b라는 구문은 a가 undefined도 아니고 null도 아니라면 a를 리턴하고, 그 외에는 b를 리턴합니다.

    즉, 위 구문을 풀어서 쓰면 다음과 같을 것입니다.

(a !== null && a !== undefined) ? a : b;
  • null 병합 연산자는 0과 같은 falsy값이 저장될 수 있는 변수를 평가할 때 매우 유용하게 쓰일 수 있습니다. 하지만, 추가된지 얼마 되지 않은 문법이기 때문에 일부 구형 브라우저에서는 호환되지 않습니다. 특히, IE(인터넷 익스플로러)에서는 아예 지원되지 않습니다.

    https://caniuse.com/?search=Nullish%20coalescing%20operator

  • null 병합 연산자는 안정성 관련 이슈로 인해, 괄호 없이는 &&나 ||와 함께 사용할 수 없습니다.

    따라서, 아래와 같이 반드시 괄호와 함께 사용되어야 합니다.

반복문

  • do...while 문법은 조건이 truthy인지에 상관 없이, 반복문을 최소한 한 번은 실행시켜야 할 때 사용합니다. 즉, 처음부터 조건이 falsy값을 가져도, 무조건 한 번은 반복문이 실행됩니다.
let i = 100;

do {
  alert( i ); // alert(100)이 한 번 실행됨.
  i++;
} while (i < 0); // 조건은 이미 false이다.
  • 삼항연산자의 피연산자로 break나 continue와 같은 반복문 지시자를 사용할 수 없습니다.
    예를 들어, 반복문 내부에서 특정 조건이 성립되었을 때 반복문을 나가기 위해서, if문 대신 다음과 같은 삼항연산자를 사용하려고 한다면 문법 에러가 발생합니다.
(i > 5) ? alert(i) : break; // 문법 에러 발생
  • 레이블(label)은 반복문 앞에 콜론과 함께 쓰이는 식별자입니다. 원래 break나 continue와 같은 반복문 지시자들은 해당 지시자가 포함되어있는 가장 가까운 반복문 한 개만을 제어할 수 있습니다. 하지만, 반복문 지시자들을 레이블과 함께 사용하면, 반복문의 중첩 수와 상관 없이 특정 반복문 한개를 선택하여 제어할 수 있습니다.

    예를 들어, 다음과 같이 두 개의 반복문이 중첩되어 있을 때, 내부 반복문에서 break 지시자를 레이블과 함께 사용하여 중첩된 반복문 전체를 빠져나올 수 있습니다.

// 외부 반복문에 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('완료!');

함수

  • 자바스크립트에서는 함수의 매개변수에 기본값을 설정할 수 있습니다. 단순히 숫자나 문자열과 같은 값 뿐만 아니라, 복잡한 표현식도 기본값으로 설정할 수 있습니다. 이는 자바스크립트에서 함수를 호출할 때 마다 매개변수의 기본값을 평가하기 때문에 가능합니다.
let sum = 0;

function anotherFunction() {
  return sum;
}

function showMessage(from, number = anotherFunction()) {     
  console.log(number);
  sum++;
}

showMessage(); // 0
showMessage(); // 1
  • 함수에서 return과 값 사이에 줄을 삽입해서는 안됩니다. 자바스크립트는 return문 끝에 세미콜론을 자동으로 넣기 때문에, 아래와 같은 문제가 발생할 수 있습니다.
return
 (some + long + expression + or + whatever * f(a) + f(b))

----- 위 코드는 다음과 같이 해석됩니다. -----

return;
 (some + long + expression + or + whatever * f(a) + f(b))

----- 따라서, 다음과 같이 작성해야 합니다. -----

return (
  some + long + expression
  + or +
  whatever * f(a) + f(b)
)
  • 함수는 두 가지 방법으로 정의할 수 있습니다. 함수 선언함수 표현식이 그 방법입니다. (화살표 함수도 '함수 표현식' 형태로 정의된다고 볼 수 있습니다)
// 함수 선언
function sayHi() {
  alert( "Hello" );
}

// 함수 표현식
let sayHi = function() {
  alert( "Hello" );
};
  • 자바스크립트에서 함수는 값입니다. 따라서, 함수를 값처럼 취급할 수 있기 때문에 함수를 변수에 저장할 수 있으며, 다른 변수에 함수를 복사하는 것도 가능합니다.

    특이한 점은, 함수를 호출하는 것이 아니라 함수 그 자체를 출력한다면 함수의 소스 코드가 문자열로 형변환되어 출력된다는 것입니다. 따라서, 다음과 같은 이상한 코드도 정상적으로 동작합니다.

  • 함수 선언으로 정의된 함수는, 호이스팅 시 함수 전체가 최상단에 위치하게 됩니다.

console.log("hi");

function sum(a, b) {
  return a + b;
}

----- 호이스팅 이후 -----

function sum(a, b) {
  return a + b;
}

console.log("hi");

이와 달리, 함수 표현식으로 정의된 함수는 호이스팅 시 함수를 저장할 변수 선언만 최상단에 위치하게 되고, 변수에 함수를 할당하는 부분은 위치가 그대로 유지됩니다.

console.log("hi");

let sum = function(a, b) {
  return a + b;
};

----- 호이스팅 이후 -----

let sum;
console.log("hi");

sum = function(a, b) {
  return a + b;
}

이로 인해, 함수 표현식을 사용했을 때에는 함수가 정의되기 전에 함수 호출을 할 시 다음과 같은 에러가 발생할 수 있습니다.

profile
풀스택 지망생

0개의 댓글