Javascript 기본 [2]

WonCheol Park·2021년 2월 3일

Javascript 기본

목록 보기
3/7

2.7 형 변환

String형으로 변환

alert 메서드같은 경우 매개변수로 string형으로 받아 자동 형변환이 일어난다.
또는 String(value) 함수 호출 형태로 직접 형변환 시켜줄 수 있다.

Number 형으로 변환

수학과 관련된 함수나 표현식에서 자동적으로 일어난다.

alert("6"/"2"); // 3

/를 적용하는 경우에 숫자형으로 자동 형변환 된 후 연산이 수행된다.
또는 Number(value)함수로 명시적으로 형변환 가능하다.
숫자 기반으로 사용하는 목적의 값을 문자 기반 폼(form)으로 입력받는 경우 이런 명시적 형변환이 필수다.
숫자 이외의 글자가 들어있는 경우, Number함수로 형변환하려고 하면 NaN을 반환한다.

숫자형 변환 규칙

전달받은 값형 변환 후
undefinedNaN
null0
true/false1, 0
string처음과 끝 공백 제거한다. 공백 제거 후 남은 문자열 없으면 0, 아니면 숫자를 읽는다. 변환에 실패하면 NaN으로 변환한다.

nullundefined 숫자형으로 변환 시 결과 다른 점을 유의해야한다.

Boolean형으로 변환

논리 연산을 수행할 때 발생한다. Boolean(value)를 통해 명시적으로 변환할 수 있다.
0, empty string, null, undefined, NaN 모두 false로 변환된다.
그 외의 값들은 true로 변환된다.

2.8 기본 연산자와 수학

용어

피연산자: 연산자가 연산을 수행하는 대상. ex) 5*2에서 52
단항(unary) 연산자: 피연산자를 하나만 받는 연산자 ex) - 부호 뒤집는 연산자
이항(binary) 연산자: 피연산자를 두 개 받는 연산자 ex) 1+3같은 연산의 연산자

수학

기본 수학 연산 +, -, *, / 사칙 연산에 나머지 연산 %, 거듭제곱 연산 **을 지원한다.

나머지 연산자 %

a%bab로 나눈 나머지를 정수로 반환한다.

거듭제곱 연산자 **

a**bab번 곱한 값을 반환한다. (1/2같은 값을 b에 넣어 제곱근을 구하는데 사용할 수도 있다.)

이항 연산자 '+'와 문자열 연결

+ 피연산자 중 하나라도 문자열이 전달되면 해당 문자열을 연결한 결과를 반환한다.
ex) "my"+"string" -> "mystring"
+가 이런 특별한 기능을 제공하는 것이고, -, /연산같은 경우 두 피연산자를 숫자로 바꾼 후 연산을 진행한다.
ex) alert('6'/'2'); // 3

단항 연산자 '+'와 숫자형으로의 변환

단항 연산자 +Number(...)와 동일하게 숫자형으로 형변환을 해준다.
ex) alert(+true); // 1

연산자 우선순위

하나의 표현식에 여러 연산자가 있는 경우 연산자 우선순위에 의해 실행 순서를 결정한다.
수식에서 *+보다 먼저 계산하는 것과 같다.
연산자 우선순위 테이블을 참고해 연산의 우선순위를 참고할 수 있다.

할당 연산자

할당할 때 쓰이는 = 연산자다. 우선순위가 3으로 아주 낮다.
이러한 표현식도 가끔 볼 수 있다.

let a = 1;
let b = 2;

let c = 3 - (a = b + 1);

alert( a ); // 3
alert( c ); // 0

ab+1을 할당하고, 그 값으로 연산을 추가로 진행한다.
그러나 직접 코드를 작성할 때는 이러한 방식은 가독성을 떨어뜨려 비추한다.

할당 연산자 체이닝으로 다음과 같이 쓸 수도 있다.

let a, b, c;

a = b = c = 2 + 2;

alert( a ); // 4
alert( b ); // 4
alert( c ); // 4

우측부터 연산 후 할당이 진행되어 c, b, a 순서로 값이 할당된다.
그러나 이러한 방식도 가독성을 떨어뜨려 여러 줄로 나눠 코드를 작성하는게 좋다고 한다.

복합 할당 연산자

변수에 연산자를 적용하고 결과를 같은 변수에 저장하는 경우에 사용된다.
n = n + 5n += 5와 동일한 연산이다.
-, / 등 다른 연산도 동일한 방식으로 사용이 가능하다.

증가, 감소 연산자

증가연산자는 ++로 해당 변수를 1 증가시킨다.
감소연산자는 --로 해당 변수를 1 감소시킨다.
증가, 감소 연산자는 각각 변수의 앞과 뒤에 붙일 수 있는데 전위형, 후위형 연산이라고 한다.
++counter와 같이 변수 앞에 붙이는 경우 해당 변수에 대한 증가 연산 수행한 이후의 값을 반환한다.

let counter = 0;
alert( ++counter ); // 1

counter++과 같이 변수 뒤에 붙이는 경우 해당 변수에 대한 증가 연산 수행 전의 기존 값을 반환한다.

let counter = 0;
alert( counter++ ); // 0

처음 이 개념을 배울 때 헷갈렸는데, 전위 연산의 경우 ++가 앞에 붙어있으므로 먼저 값을 더하고 후위 연산의 경우 ++가 뒤에 붙어있으므로 값을 사용 후 나중에 더한다고 생각한 이후로 헷갈리지 않았다.

비트 연산자

인수를 32비트 정수로 변환해 이진 연산을 수행한다.

  • 비트 AND ( & )
  • 비트 OR ( | )
  • 비트 XOR ( ^ )
  • 비트 NOT ( ~ )
  • 왼쪽 시프트(LEFT SHIFT) ( << )
  • 오른쪽 시프트(RIGHT SHIFT) ( >> )
  • 부호 없는 오른쪽 시프트(ZERO-FILL RIGHT SHIFT) ( >>> )
    자주 사용되지는 않지만 암호를 다룰 때 유용하게 사용할 수 있다.

쉼표 연산자

여러 표현식을 코드 한 줄에 작성할 수 있게 해준다.
모두 표현식이 평가되지만, 마지막 표현식의 결과만 반영된다.
보기 힘들고 특이한 연산자인데, 코드를 짧게 쓰려는 의도로 가끔 사용된다.

let a = (1 + 2, 3 + 4);

alert( a ); // 7 (3 + 4의 결과)

쉼표 연산의 우선순위는 매우 낮아 위처럼 괄호를 필수적으로 사용해줘야 한다.
괄호를 사용 안하면 (a=1+2),3+4와 같은 순서로 연산이 되어버린다.

// 한 줄에서 세 개의 연산이 수행됨
for (a = 1, b = 3, c = a * b; a < 10; a++) {
 ...
}

이렇게 한 줄에 여러 연산을 처리해야 하는 경우에 사용되는데, 이 또한 코드 가독성에 도움이 되지 않아 아주 필요한 경우에만 사용하도록 한다.

2.9 비교 연산자

>, <, >=, <=, == 등 과 같은 비교 연산을 말한다.

Boolean형 반환

참인 경우 true를 반환, 거짓인 경우 false를 반환한다.

문자열 비교

문자열은 비교 시 사전순으로 비교한다. 사전순에서 뒤쪽에 있는 문자열이 앞에 있는 문자열보다 크다고 판단한다.
정확히는 사전순이 아니라 유니코드 순이다. 대문자 A와 소문자 a를 비교하면 a가 더 크다.

alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Bee' > 'Be' ); // true

다른 형을 가진 값 간의 비교

비교하려는 값의 자료형이 다르면 이 값들을 숫자형으로 바꿔 비교한다.

alert( '2' > 1 ); // true, 문자열 '2'가 숫자 2로 변환된 후 비교가 진행
alert( '01' == 1 ); // true, 문자열 '01'이 숫자 1로 변환된 후 비교가 진행

Boolean값인 경우 true1, false0으로 변환 후 비교한다.

alert( true == 1 ); // true
alert( false == 0 ); // true

일치 연산자

===로 동등 연산자의 엄격한(strict) 버전이다. 비교 대상의 자료형까지 같아야 true를 반환한다.
일반적으로 두 대상을 비교할 때 일치 연산자를 통해서 엄격한 검사를 해 에러 발생율도 줄어 == 사용은 지양한다.

null과 undefined 비교

alert( null === undefined ); // false
alert( null == undefined ); // true

자료형까지 비교하는 일치 연산자인 경우에만 false를 반환하고, 동등 연산자는 true를 반환한다.

null 과 0 비교

alert( null > 0 );  // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true

기본적으로 null은 숫자형으로 형변환 시 0으로 변환된다.
1, 3의 경우에는 null0으로 형변환 되어 비교해 각각 false, true가 나온다.
그러나 == 동등 연산자는 형변환을 하지 않고 비교한다. nullundefined는 다른 값과 비교할 때 무조건 false를 반환하기 때문에 2의 경우에는 false를 반환한다.

비교 불가능한 undefined

alert( undefined > 0 ); // false (1)
alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)

기본적으로 undefined는 숫자형으로 형변환 시 NaN으로 변환된다.
1, 2의 경우에는 NaN과 비교하게 되는데, NaN이 피연산자인 경우 항상 false를 반환한다.
undefinednull이나 undefined와 같고, 그 외의 값과는 다르기 때문에 3의 경우에는 false를 반환한다.

이러한 점들의 edge case때문에 일치 연산자 ===를 제외하고는 undefinednull이 오지 않도록 주의해야 한다.
undefinednull이 올 수 있는 변수는 >, <, >=, <= 이러한 피연산자를 사용하지 않도록, 혹은 분기 처리 코드를 추가해야 한다.

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

if문

if문은 괄호 안의 조건을 평가해, true면 해당 코드 블록을 실행한다.

if (year == 2015) {
  alert( "정답입니다!" );
  alert( "아주 똑똑하시네요!" );
}

boolean형 변환

if문의 괄호 안은 항상 boolean형으로 형변환된다.

if (0) {
  ...
}

0false로 반환되어 해당 if문 내부의 코드는 절대 실행되지 않는다.

else절

if문 뒤에 else절을 붙여, 조건이 거짓일 때 실행시킬 수 있다.

let year = prompt('ECMAScript-2015 명세는 몇 년도에 출판되었을까요?', '');

if (year == 2015) {
  alert( '정답입니다!' );
} else {
  alert( '오답입니다!' ); // 2015 이외의 값을 입력한 경우
}

else if로 복수 조건 처리하기

if문 이외에 추가적인 조건문을 추가해야 하는 경우 사용한다.

let year = prompt('ECMAScript-2015 명세는 몇 년도에 출판되었을까요?', '');

if (year < 2015) {
  alert( '숫자를 좀 더 올려보세요.' );
} else if (year > 2015) {
  alert( '숫자를 좀 더 내려보세요.' );
} else {
  alert( '정답입니다!' );
}

조건부 연산자 '?'(삼항연산자)

let result = condition ? value1 : value2;

위 처럼 사용되는데 condition조건이 truevalue1을, falsevalue2를 return하는 연산자다.
javascript에서 이렇게 피연산자를 3개나 받는 연산자는 조건부 연산자가 유일하다.

다중 '?'

조건부 연산자도 중첩하여 사용할 수 있다.

let age = prompt('나이를 입력해주세요.', 18);

let message = (age < 3) ? '아기야 안녕?' :
  (age < 18) ? '안녕!' :
  (age < 100) ? '환영합니다!' :
  '나이가 아주 많으시거나, 나이가 아닌 값을 입력 하셨군요!';

alert( message );

해당 예시 if...else문으로 그대로 변환 가능하다. 표현 방법의 차이일 뿐 같은 동작을 한다.

if (age < 3) {
  message = '아기야 안녕?';
} else if (age < 18) {
  message = '안녕!';
} else if (age < 100) {
  message = '환영합니다!';
} else {
  message = '나이가 아주 많으시거나, 나이가 아닌 값을 입력 하셨군요!';
}

부적절한 '?'

  1. 조건부 연산자를 사용해 작성한 코드
let company = prompt('자바스크립트는 어떤 회사가 만들었을까요?', '');

(company == 'Netscape') ?
   alert('정답입니다!') : alert('오답입니다!');
  1. if문을 사용해 작성한 코드
let company = prompt('자바스크립트는 어떤 회사가 만들었을까요?', '');

if (company == 'Netscape') {
  alert('정답입니다!');
} else {
  alert('오답입니다!');
}

조건부 연산자가 코드 길이가 짧아진다는 이유로 이렇게 if문 대용으로 사용하면 코드 가독성이 떨어질 수 있다.

2.11 논리 연산자

3가지 논리연산자가 있다.

  1. ||(OR)
  2. &&(AND)
  3. !(NOT)

||(OR)

인수 중 하나만 true여도 true를 반환한다.

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

첫 번째 truthy를 찾는 OR연산자

result = value1 || value2 || value3;

OR 연산은 다음 순서에 따라 연산을 수행한다.

  1. 가장 왼쪽 -> 오른쪽으로 나아가며 피연산자를 평가한다.
  2. 각 피연산자를 boolean으로 변환해, true면 연산을 멈추고 피연산자의 변환 전 값을 반환한다.
  3. 피연산자를 모두 평가한 경우 마지막 피연산자를 반환한다.

예시)

alert( 1 || 0 ); // 1 (1은 truthy임)

alert( null || 1 ); // 1 (1은 truthy임)
alert( null || 0 || 1 ); // 1 (1은 truthy임)

alert( undefined || null || 0 ); // 0 (모두 falsy이므로, 마지막 값을 반환함)

활용)

  1. 변수 또는 표현식으로 구성된 목록에서 첫 번째 truthy 얻기
let firstName = "";
let lastName = "";
let nickName = "바이올렛";

alert( firstName || lastName || nickName || "익명"); // 바이올렛
  1. 단락 평가
true || alert("not printed");
false || alert("printed");

왼쪽이 falsy인 경우에만 명령어를 실행하고자 할 때 자주 쓰인다.

&&(AND)

result = a && b;

&& 연산자는 두 피연산자 모두 true일 때 true를 반환한다.

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

첫 번째 falsy를 찾는 AND 연산자

result = value1 && value2 && value3;

AND 연산자는 다음 순서에 따라 동작한다.

  1. 가장 왼쪽 -> 오른쪽으로 진행하며 피연산자를 평가한다.
  2. 각 피연산자 모두 boolean형으로 변환되어 평가해 false면 평가를 멈추고 해당 피연산자를 변환 전으로 반환한다.
  3. 피연산자 모두 평가되었으면 마지막 피연산자를 반환한다.

여러 개를 연속해서도 사용할 수 있다.

alert( 1 && 2 && null && 3 ); // null

모두 만족하는 경우 마지막 피연산자가 반환된다.

alert( 1 && 2 && 3 ); // 마지막 값, 3

&&의 우선순위가 ||보다 높다.
a && b || c && d(a && b) || (c && d)와 동일하게 동작한다.

!(NOT)

result = !value;

NOT 연산자는 인수를 하나만 받고, 다음 순서대로 연산을 수행한다.

  1. 피연산자를 boolean형으로 변환한다.
  2. 1에서 변환된 값의 역을 반환한다.

예시)

alert( !true ); // false
alert( !0 ); // true

NOT을 두 번 연속으로 사용하면 boolean형으로 변환할 수 있다.

alert( !!"non-empty string" ); // true
alert( !!null ); // false

true, false를 판단하는 용도로 사용되는 경우 !!을 붙여 명시하면 좋다.

!! 연산자는 모든 논리 연산자 중 우선순위가 가장 높아, &&||보다 먼저 실행된다.

2.12 null 병합 연산자 '??'

스펙에 추가된 지 얼마 안 된 문법이라, 구버전 브라우저에서는 polyfill이 필요하다.

여러 피연산자 중 값이 확정되어 있는 변수를 찾을 수 있다.

a ?? b의 결과는 다음과 같다.

  • anull도 아니고 undefined도 아니면 a
  • 그 외의 경우는 b

해당 코드를 ??연산자 없이 작성하면 다음과 같다.

x = (a !== null && a !== undefined) ? a : b;

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

null 병합 연산자와 || 연산자의 동작이 매우 유사해 보이지만 차이점이 있다.

  • ||는 첫 번째 truthy한 값을 반환한다.
  • ??는 첫 번째 정의된 값을 반환한다.

예시)

let height = 0;

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

다음과 같이 0이 할당될 수 있는 부분에서는 ??를 사용하는게 적합하다.

연산자 우선순위

?? 연산자는 우선순위 5로 꽤 낮다.
복잡한 표현식에서 ??를 사용할 때는 보통 괄호를 추가해주는 것이 좋다.

let height = null;
let width = null;

// 괄호를 추가!
let area = (height ?? 100) * (width ?? 50);

alert(area); // 5000

추가로 안정성 관련 이슈로 ??&&||와 함께 사용할 수 없다.

let x = 1 && 2 ?? 3; // SyntaxError: Unexpected token '??'

이 부분에 대해서는 아직 많은 논쟁이 있지만, ||??로 바꾸는 과정에서의 실수를 방지하고자 명세서에 제약이 추가되었다고 한다. 제약을 피하려면 괄호를 사용해야 한다.

let x = (1 && 2) ?? 3; // 제대로 동작합니다.
profile
신입 개발자입니다~

0개의 댓글