• 코어자바스크립트 - 자바스크립트 기본

    2022. 1. 2.

    by. 나나 (nykim)

    320x100
    자바스크립트 기본
    https://ko.javascript.info/first-steps

     

     

    엄격 모드

    • 자바스크립트는 기존 기능을 변경하지 않고 추가만 하는 식으로 호환성 문제를 회피했습니다.
    • 그런데 ES5(2009)에서 기존 기능 일부를 변경하게 되었는데요, 혹시나 싶은 문제를 피하기 위해 이 새로운 기능들은 기본적으로 비활성화 상태입니다.
    • 새롭게 추가된 기능을 쓰고 싶다면, use strict라고 외쳐주세요. 그럼 '엄격 모드'가 됩니다.
    • 이 주문은 주로 스크립트 최상단에서 외칩니다. 그래야 스크립트 전체가 엄격 모드로 적용되니까요.
    • 만약 클래스와 모듈을 사용해 스크립트를 작성했다면 이미 엄격모드가 적용된 거나 다름 없어서 굳이 적지 않아도 됩니다.

     

     

    기본 연산자와 수학

    • %(나머지 연산자): x % b 는 x를 b로 나누고 그 나머지를 정수로 반환합니다.
    • **(거듭제곱 연산자): x ** b는 x를 b번 곱한 값을 반환합니다. (2**3 = 8) 단, 이는 ES7에서 추가된 스펙입니다.
    • 이항 연산자(+)와 함께 쓰인 피연산자 중 문자열이 있으면 문자열로 변환됩니다.
      alert( 2+2+'1' ) //결과: '41'
    • 덧셈 연산자(+)가 숫자가 아닌 경우 숫자형으로 변환됩니다.
      alert( +"" ); //결과: 0
      let a=5; let b=1; alert( +a + +b ); //결과: 6
    • ++/--는 피연산자의 앞뒤 어디에도 위치할 수 있습니다. 전위형은 증가/감소 후 새로운 값을 반환하고, 후위형은 증가/감소 전 기존값을 반환합니다.
      let counter = 1; let a = ++counter; alert(a); //결과: 2
      let counter = 1; let a = counter++; alert(a); //결과: 1
    • 따라서 값을 증가시키고 증가한 값을 바로 사용하려면 전위형을, 값을 증가시키되 기존 값을 사용하려면 후위형을 사용합니다.

     

    비교 연산자

    • 문자열 비교: JS는 대소문자를 따져 비교합니다. "A"와 "a" 중 "a"가 더 크다고 판단하며, 이는 JS 내부에서 사용되는 인코딩 표인 유니코드에서 소문자가 더 큰 인덱스를 갖고 있기 때문입니다.
    • 비교하려는 값의 자료형이 다르면 관대하신 JS는 이들을 숫자형으로 바꿔줍니다.
      alert( '2' > 1 ); //결과: true
    • null과 undefined는 ===를 사용하면 false, ==를 사용하면 true가 반환됩니다.
      null === undefined //결과: false
      null == undefined //결과: true
    • 만약 산술 연산자나 기타 비교 연산자(<, > 등)을 사용할 경우 숫자형으로 변환되는데, null은 0, undefined는 NaN이 됩니다. 단, 동등 연산자(==)는 피연산자가 null 또는 undefined일 때 형 변환을 하지 않습니다.
      null == 0 //결과: false

     

     

    논리 연산자

    1. OR (||)
      • 인수 중 하나라도 true라면 true를 반환. 그렇지 않다면 false를 반환합니다.
        if (1 || 0) {}; //결과: true
      • OR 연산자가 여러 개라면 왼쪽부터 시작해 순서대로 평가합니다. 이때, 피연산자를 불린형으로 변환하는데 그 값이 true면 연산을 멈추고 변환 전 원래 값을 반환합니다. 모두 평가한 후에도 false라면 마지막 피연산자를 반환합니다.
        alert(null || 0 || 1); //결과: 1 (1은 truthy임)
        alert(undefined || null || 0); //결과: 0 (모두 falsy임)
    2. AND (&&)
      • 피연산자 모두가 참일 때 true를 반환. 그렇지 않다면 false를 반환합니다.
        if (1 && 0) {}; //결과: false
      • AND 연산자가 여러 개라면 왼쪽부터 시작해 순서대로 평가합니다. 이 과정은 OR 연산자와 유사하며, 변환된 값이 false면 연산을 멈추고 변환 전 원래 값을 반환합니다.
        alert( 1 && null && 5 ); //결과: null
        alert( 1 && 2 && 3 ); //결과: 3
    3. NOT (!)
      • 피연산자를 불린형으로 변환한 뒤 그 값의 역을 반환합니다.
        alert ( !true ); //결과: flase
      • NOT을 연달아 두 개 사용(!!)하면 값을 불린형으로 변환할 수 있습니다. 이는 내장 함수인 Boolean을 사용한 것과 동일합니다.
        alert ( !!"non-empty string" ); //결과: true
        alert ( Boolean(null) ); //결과: false

     

    예제

    [1] ` alert( alert(1) || 2 || alert(3) ); ` 의 결과는?

    • 답: 얼럿 창엔 1, 2가 차례대로 출력됩니다.
    • 먼저 alert(1)을 평가합니다. 이때 첫 번째 얼럿 창에 1이 출력되죠.
    • alert() 메서드는 undefined를 반환합니다. 이는 falsy 이므로 OR 연산자는 다음 피연산자를 평가합니다.
    • 다음으로 평가되는 2는 truthy이므로 실행이 멈추고 2가 반환됩니다. 반환된 2는 바깥쪽 alert() 메서드의 피연산자가 되어 얼럿 창에 2가 출력됩니다.
    • 평가가 alert(3)까지 진행되지 않으므로 3은 출력되지 않습니다.

     

    [2] `alert( alert(1) && alert(2) ); `의 결과는?

    • 답: 얼럿 창엔 1, undefined가 차례대로 출력됩니다.
    • 먼저 alert(1)을 평가합니다. 이때 첫 번째 얼럿 창에 1이 출력되죠.
    • alert() 메서드는 undefined를 반환합니다. 이는 falsy 이므로 AND 연산자는 평가를 멈춥니다.
    • 반환된 undefined는 바깥쪽 alert() 메서드의 피연산자가 되어 얼럿 창에 undefined가 출력됩니다.

     

    [3] `alert( null || 2 && 3 || 4 );`의 결과는? ✔️

    • 답: 얼럿 창엔 3이 출력됩니다.
    • &&의 우선순위가 높으므로 우선 2 && 3이 실행됩니다. 둘 다 truthy이므로 3이 반환됩니다.
    • 먼저 null을 평가합니다. 이는 falsy이므로 OR연산자는 다음 피연산자를 평가합니다.
    • 이후 3을 평가합니다. 이는 truthy이므로 OR연산자는 평가를 멈춥니다.
    • 반환된 3은 바깥쪽 alert() 메서드의 피연산자가 되어 얼럿 창에 3이 출력됩니다.

     

     

    null 병합 연산자 '??'

    • ES2020(ES11)에 추가된 스펙입니다.
      ??를 사용하면 여러 피연산자 중 그 값이 '확정된' 변수를 찾을 수 있습니다. (=값이 null 또는 undefined가 아닌 변수)
      ex) a ?? b 평가 시, a가 null 또는 undefined가 아니라면 a. 그 외의 경우는 b
    • 따라서 아래 두 코드는 동일한 기능을 합니다.
      [1] let name = ( realName !== null && realName !== undefined ) ? realName : nickName;
      [2] let name = realName ?? nickName 으로 줄여서 표현할 수 있습니다.
    • 이는 || 연산자와 유사하지만 차이점이 있습니다. ||는 첫 번째 truthy의 값을 반환하고, ??는 첫 번째 truthy의 '정의된' 값을 반환합니다.
      let height = 0;
      let myHeight = height || 180; //결과: 180
      let yourHeight = height ?? 180; //결과: 0
      • height || 180은 0을 falsy 값으로 판단하여 이를 null이나 undefined와 동일하게 취급합니다. 따라서 첫 번째 truthy는 180이 됩니다.
      • 하지만 height ?? 180은 height가 정확하게 null이나 undefined일 때만을 falsy라고 판단합니다. 따라서 첫 번째 truthy는 height이며 여기에 정의된 0이 됩니다.
      •  이러한 특징 때문에 0이 할당될 수 있는 변수를 사용할 때는 ??가 적합합니다.
    • 현재 JS에서는 안정성 관련 이슈 때문에 ??를 ||나 &&와 함께 사용하지 못하도록 제약이 걸려 있습니다. 단, 괄호로 묶으면 함께 사용할 수 있습니다.

     

     

     

    반복문

    1. while
      • 조건이 truhty인 동안 반복문 본문 내용을 반복합니다.
      • 반복문 본문이 한 번 실행되는 것을 iteration이라고 부릅니다.
        let i = 0;
        while (i < 3) {
          alert( i ); // 0, 1, 2가 출력됩니다.
          i++;
        }
       
    2. do..while
      • condition이 본문 다음에 나오는 형태로, 본문이 '최소한 한 번 이상 실행되어야'할 때 사용합니다.
        let i = 0;
        do {
          alert( i ); // 0, 1, 2가 출력됩니다.
          i++;
        } while (i < 3);​
       
    3. for
      • begin; condition; step;으로 이뤄진 반복문입니다.
        for (begin; condition; step) {
          // ... 반복문 본문 ...
        }
      • 세미콜론 `;` 만 남기고 불필요한 내용을 생략할 수도 있습니다.
        let i = 0;
        for (; i < 3; i++) {
          alert( i );
        }
       
    4. 반복문 빠져나오기
      • `break`를 사용하면 반복문을 종료합니다.
      • 본문 가운데나 본문 여러 곳에서 조건을 확인해야 하는 경우, '무한 반복문 + break' 조합을 사용하면 좋습니다.
      • 여러 개의 중첩 반복문을 빠져나와야 한다면, 단순히 break 선언만으론 부족합니다. 이럴 때는 `{라벨이름}:`을 사용합니다. 반복문 앞에 식별자를 붙이고, 해당 반복문을 종료시킬 수 있습니다.
        outer: for (let i = 0; i < 3; i++) {
          for (let j = 0; j < 3; j++) {
            let input = prompt(`(${i},${j})의 값`, '');
            if (!input) break outer; 
            // 사용자가 아무것도 입력하지 않거나 Cancel 버튼을 누르면 두 반복문 모두를 빠져나옵니다.
          }
        }
        alert('완료!');​
       
    5. 다음 반복으로 넘어가기
      • `continue`는 전체 반복문을 멈추지 않고, 현재 실행 중인 이터레이션만 종료시킨 뒤 다음 이터레이션으로 넘어가도록 합니다.
      • 예를 들어 홀수만 출력시키고 싶은 경우,
        for (let i=0; i<10; i++) {
          if (i % 2) {
            alert(i);
          }
        }​

        위와 같이 사용할 수 있지만, continue를 쓸 수도 있습니다.
        for (let i=0; i<10; i++) {
          if (i % 2 ==) continue;
        }​

     

    예제

    [1] 아래 코드의 실행 결과는?

    let i = 0;
    while (i++ < 5) alert( i );
    • 답: 얼럿 창에 1,2,3,4,5가 출력됩니다.
    • ++가 뒤에 나오는 경우는 값을 증가하되 기존값을 반환합니다. 따라서 비교는 (0<5)가 되며 이는 참입니다. 한편, alert()는 조건문과 별개이므로 이미 증가해서 넘어온 i를 받고 1을 출력합니다.

     

    [2] 아래 두 코드의 실행 결과는 동일할까요?

    //1
    for (let i = 0; i < 5; i++) alert( i );
    
    //2
    for (let i = 0; i < 5; ++i) alert( i );
    • 답: 동일하게 0,1,2,3,4를 출력합니다.
    • 왜냐하면 i++나 ++i는 조건 확인과 별개의 구문이기 때문입니다. for문은 그저 증가된 i를 조건 확인에 사용할 뿐입니다. 따라서 증가 연산자가 반환한 값은 어디에도 쓰이지 않습니다.

     

    [3] 사용자가 100보다 큰 숫자를 입력할 때까지 프롬프트 창을 띄우고, 아무것도 입력하지 않거나 취소한 경우 프롬프트 창을 취소하는 코드를 작성해 보세요.

    • 답:
      let num;
      do {
        num = prompt("100을 초과하는 숫자를 입력해주세요.", 0);
      } while (num <= 100 && num​
    • num이 null인 경우 num <= 100은 true가 되므로 두 번째 조건이 없으면 취소 버튼을 눌러도 반복문이 계속해서 실행됩니다. 따라서 위 두 조건을 모두 확인해야 합니다.

     

     

     

     

    함수

    1. 매개변수
      • 매개변수와 인자는 다릅니다!
        • (1) 매개변수/파라미터(parameter): 함수를 실행하기 위해 필요하다고 지정하는 값
          👉 입장을 위해 마련해두는 의자
        • (2) 인수/인자(arguments): 함수를 호출할 때 매개변수로 넘기는 값
          👉 실제로 입장한 사람
      • 함수는 복사된 값을 사용하기 때문에 외부 변수에 영향을 주지 않습니다. 즉, 함수에 전달된 매개변수는 복사된 후 함수의 지역변수가 됩니다.
      • 함수는 외부 변수에 접근할 수 있지만, 바깥에서 함수 내부의 지역변수에는 접근할 수 있습니다.
        let num = 22;
        add = (x, y) => { return x + y; } //(x,y)는 매개변수
        add(num,2); //(num,2)는 인수​
      • 매개변수에 값을 전달하지 않으면 그 값은 `undefined`가 됩니다.
      • 함수를 정의할 때 매개 변수 오른쪽에 `=`을 붙여 기본값을 설정할 수 있습니다.
        someFunc = () => { return 'hello' };
        showMsg = (name, msg = someFunc()) => { alert(name+' says '+msg); };
        showMsg('nana'); //결과: 'nana says hello'​
      • 또는 선언부 대신, 함수 실행 도중에 기본값을 설정할 수도 있습니다.
        showMsg = (text) => {
          text = text || 'Hey!';
          ...
        }​
       
    2. 리턴
      • 함수는 무조건 뭔가를 돌려줍니다. (네! 항상 무언가를 싸요! 💩)
      • return문이 없거나 return 지시자만 있는 경우라도 undefined를 반환합니다.
        (즉, return; === return undefined;인 거죠)
       
    3. 함수 이름짓기
      • 함수 이름은 대개 동사로 짓습니다. 함수 이름만 보고도 함수가 어떤 기능을 하는지 알 수 있어야 합니다.
        • get: 값 반환
        • calc: 계산
        • create: 생성
        • check: 확인 후 불린값 반환
        • show: 무언가를 표시함
      • 함수는 동작 하나만 담당해야 합니다. 즉, 이름에 언급된 동작만 수행해야 합니다.
        • ex) getAge() 함수는 나이를 얻어오기만 해야 합니다. alert()로 출력해주는 동작은 다른 함수가 해야 합니다.
        • ex) createForm() 함수는 form 생성 후 반환하기만 해야 합니다. form을 문서에 출력하는 동작은 다른 함수가 해야 합니다.
      • 함수는 주석이 없어도 그 존재 자체가 무슨 역할을 하는지 설명할 수 있어야 합니다. 코드를 분리해 작성하면 더 나은 코드 구조가 됩니다.
       
    4. 함수 표현식 vs. 함수 선언문
      • 함수 선언문은 독자적인 구문 형태로 존재합니다.
        function sum(a, b) {
          return a + b;
        }​
      •  함수 표현식은 구문 구성(syntax construct) 내부에 생성됩니다. 이때 실제 실행 흐름이 해당 함수에 도달했을 때 함수를 생성합니다.
        let sum = function(a, b) {
          return a + b;
        };​
      • 따라서 함수 선언문은 정의 전에 호출할 수 있습니다. 왜냐면 JS는 스크립트를 실행하기 전, 전역에 선언된 함수 선언문을 찾아 해당 함수를 생성하기 때문입니다.
      • 또한 '엄격 모드'를 사용 중이라면, 함수 선언문으로 선언된 코드는 블록 내에서만 유효하고, 블록 밖(중괄호 밖)에서는 호출할 수 없습니다.

     

     

     

    +++

    prompt()
    - 확인을 누르면 해당 값(문자열)을 반환
    - 취소를 누르면 null을 반환
    - 아무 것도 입력하지 않으면 빈 문자열을 반환

    confirm()
    - 확인을 누르면 true를 반환
    - 취소를 누르면 false를 반환
    728x90

    '🐿 > JS' 카테고리의 다른 글

    코어자바스크립트 - 자바스크립트 기본  (0) 2022.01.02

    댓글 0