ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바스크립트 기본 문법 복습
    JS&React 2024. 8. 21. 17:33

    1. const, let을 이용한 변수 선언

     

    var 변수를 선언 시 문제점

    1) 변수를 덮어 쓸 수 있다.

    2) 다시 선언(재선언)할 수 있다.

    3) 함수 스코프와 호이스팅 (Function Scope & Hoisting)

    var는 블록 스코프를 무시하고 함수 스코프만 따른다.

    이는 if, for 같은 블록 내에서 선언된 변수가 블록 외부에서도 접근 가능하게 된다.

    또한 var로 선언된 변수는 호이스팅(hoisting)이라는 메커니즘에 의해 변수 선언이 스코프의 최상단으로 끌어올려진다.

    function test() {
        if (true) {
            var number = 10; // 블록 내에서 선언
        }
        console.log(number); // 출력: 10 (블록 밖에서 접근 가능)
    }
    
    test();

     

     

    var는 변수를 덮어쓸 수 있고 재선언할 수 있으며, 함수 스코프를 가지고, 전역 객체의 속성이 될 수 있다.
    이러한 특성 때문에 코드의 예측 가능성이 줄어들고, 버그가 발생할 가능성이 커지므로, let과 const를 사용하는 것이 좋다.

     

    let은 블록 스코프, 재선언 불가능, 변수 덮어 쓰기 가능
    const는 블록 스코프, 재선언과 덮어 쓰기 모두 불가능하지만 객체나 배열 등 오브젝트 타입은 값을 변경할 수 있다.

    리액트 개발에서는 const를 가장 많이 사용한다.

    대부분은 const를 이용하고 State로 관리하지 않으면서 처리 도중 값을 덮어 써야하는 변수만 let으로 선언한다.

    // 객체 속성값 변경 및 추가
    // 객체 정의
    const obj1 = {
      name: "흠냐링",
      age: 23,
    };
    
    console.log(obj1);
    
    // 속성 값 변경
    obj1.name = "휴닝카이";
    console.log(obj1);
    
    // 속성 추가
    obj1.address = "Seoul";
    console.log(obj1);
    
    // 배열값 변경, 추가
    // 배열 정의
    const arr1 = ["rabbit", "cat"];
    console.log(arr1);
    // 첫번째 값 변경
    arr1[0] = "bear";
    console.log(arr1);
    
    // 값 추가
    arr1.push("penguin")
    console.log(arr1);

     

    2. 템플릿 문자열

    // 문자열 안에서 자바스크립트 값을 다룰 때는 템플릿 문자열을 이용 하는 것이 좋다.
    const team = "투바투"
    const name = "휴닝카이";
    const age = 23;
    const hobby = "GAME";
    
    const idol = "나는 " + team + "의 막내 " + name; 
    const message = `내 이름은 ${name} 나이는 ${age}세 취미는 ${hobby}입니다.`;
    console.log(idol);
    console.log(message);
    
    function sayHello() {
      return "안녕하세요!";
    }
    
    const month = 2;
    const message2 = `여러분 ${sayHello()}! 오늘부터 ${month * 4}월 입니다.`;
    
    console.log(message2);
    console.log(sayHello());

     

    3. 화살표 함수 () => {}

    // 화살표 함수() => {}
    
    // 기존 함수 1
    // 기존 함수 정의
    function func1(value) {
      return value;
    }
    
    console.log(func1("func1 입니다."));
    
    // 함수를 정의하고 변수에 저장
    // 기존 함수 2
    const func2 = function (value) {
      return value;
    };
    
    console.log(func1("func2 입니다."));
    
    // 화살표 함수
    const func3 = (value) => {
      return value;
    };
    
    console.log(func3("func3 입니다."));
    
    // 화살표 함수 생략 표기법
    // 화살표 함수 정의(인수가 한개이므로 소괄호 생략)
    const func4 = value => {
      return value;
    };
    
    console.log(func4("func4 입니다."));  
    
    // 인수가 두 개인 경우
    // 인수가 두개 이상이면 소괄호로 감싼다.
    const func5 = (value1, value2) => {
      return value1 + value2
    };
    
    console.log(func5(20,30));
    
    // return 생략
    // 처리를 한 행으로 반환하는 경우 {}, return 생략 가능
    const func6 = (num1, num2) => num1 + num2;
    console.log(func6(30,40));
    
    // 반환 값이 여러 행일 경우 ()로 감싼 뒤 단일 행과 같이 모아서 반환 
    // ()를 이용해 한 행으로 모으기
    const func7 = (val1, val2) => (
      {
        name: val1,
        age: val2,
      }
    )
    console.log(func7("휴닝카이", 23));

     

    4. 분할 대입 === 구조분해할당

    https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

     

    구조 분해 할당 - JavaScript | MDN

    구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식입니다.

    developer.mozilla.org

    // 분할 대입 {}[]
    // 분할 대입은 객체나 배열로부터 값을 추출하기 위한 방법이다.
    
    // 분할 대입 사용하지 않는 예제
    // 객체 속성 수가 많아지거나, 객체 변수 명이 길어지면 myProfile.~이라고 입력하기 번거롭다. 이러한 경우 분할 대입 사용.
    const myProfile1 = {
      name: "휴닝카이",
      age: 23,
    };
    
    const message1 = `내 이름은 ${myProfile1.name} 나이는 ${myProfile1.age}세입니다.`;
    console.log(message1);
    
    // 객체 분할 대입 사용
    const myProfile2 = {
      name: "흠냐링",
      age: 23,
    };
    
    // 객체 분할 대입
    // {}를 변수 선언부에 이용하면 객체 안에서 일치하는 속성을 추출할 수 있다.
    // 일부만 추출하거나 순서가 달라도 된다.
    const { name, age } = myProfile2;
    const message2 = `내 이름은 ${name} 나이는 ${age}세입니다.`;
    console.log(message2);
    
    // 속성에 alias 사용
    const myProfile3 = {
      name: "최용멍",
      age: 25,
    };
    
    // 속성에 콜론으로 다른 변수명 이용
    const { name: newName, age: newAge } = myProfile3;
    const message3 = `내 이름은 ${newName} 나이는 ${newAge}세입니다.`;
    console.log(message3);
    
    // 배열 분할 대입
    // 1. 배열 인덱스를 지정해서 대입
    const myProfile4 = ["최밤긋", 24];
    const message4 = `내 이름은 ${myProfile4[0]} 나이는 ${myProfile4[1]}세입니다.`;
    console.log(message4);
    
    // 2. 배열 분할 대입
    // 객체와 달리 순서를 변경할 수 없으며 직접 임의로 설정한 변수명을 이용한다.
    const myProfile5 = ["다고냥", 23];
    const [name1, age1] = myProfile5;
    const message5 = `내 이름은 ${name1} 나이는 ${age1}세입니다.`;
    console.log(message5);
    
    // 인덱스 중간 까지만 필요한 경우 이후 요소를 생략할 수 있다.
    // const [name1] = myProfile5;

     

    5. 디폴트 값 =

    // 디폴트 값은 함수의 인수나 객체를 분할 대입할 경우 설정해 사용한다.
    // 값이 존재하지 않을 때 초깃값을 설정할 수 있어 처리를 더욱 안전하게 할 수 있다.
    
    const sayHello = (name = "투바투") => console.log(`${name}님, 안녕하세요!`);
    
    sayHello();
    sayHello("휴닝카이");
    
    // 객체 분할 대입의 디폴트 값
    const myProfile = {
      age: 23,
    };
    
    // 인수와 마찬가지로 변수명 뒤에 =로 값을 설정하면 속성이 존재하지 않을 경우 설정 값을 지정할 수 있다. 속성이 존재할 때는 해당 속성을 우선한다.
    const { name_ = "모아" } = myProfile;
    const message = `${name_}님, 안녕하세요!`;
    console.log(message); // 게스트님, 안녕하세요!

     

    6. 스프레드 구문 ...

    /* 스프레드 구문 */
    // 일반적인 함수와 스프레드 구문 비교
    const arr1 = [1, 2];
    // 요소 전개
    console.log(arr1); // [1, 2]
    console.log(...arr1); // 1 2
    
    const summaryFunc = (num1, num2) => console.log(num1 + num2);
    
    // 일반적으로 배열 값을 전달하는 경우
    summaryFunc(arr1[0], arr1[1]); // 3
    // 스프레드 구분을 이용하는 방법
    summaryFunc(...arr1); // 3
    
    // 요소 모으기
    const arr2 = [1, 2, 3, 4, 5];
    const [num1, num2, ...arr3] = arr2;
    
    console.log(num1); // 1
    console.log(num2); // 2
    console.log(arr3); // [3, 4, 5]
    
    
    // 스프레드 구문을 이용해 새로운 배열 생성
    const arr4 = [10, 20];
    const arr5 = [30, 40];
    
    // 스프레드 구문을 이용해 복사
    const arr6 = [...arr4];
    console.log(arr4);
    console.log(arr6);
    
    // 두개의 배열 결합
    const arr7 = [...arr4, ...arr5];
    console.log(arr7);
    
    // 여러 객체 결합
    const obj4 = {val1: 10, val2: 20};
    const obj5 = {val3: 30, val4: 40};
    
    // 스프레드 구문을 이용해 복사
    const obj6 = {...obj4};
    // 스프레드 구문을 이용해 결합
    const obj7 = {...obj4, ...obj5};
    
    console.log(obj6);
    console.log(obj7);

    • 등호를 이용해서 복사하는 안되는 이유
    • 배열이나 객체 등 오브젝트 타입이라 불리는 변수는 등호로 복사하면 참조값(변수를 실제로 저장하고 있는 위치) 역시 상속 되기 때문에 예상치 못한 동작을 일으킬 수 있다.
    • 스프레드 구문을 사용하면 완전히 새로운 배열을 만들기 때문에 원래 배열에 영향을 주지 않는다.
    // 복사할 때 예상치 못한 작동
    const arr4 =[10, 20];
    // = 로 복사
    const arr8 = arr4;
    // arr8의 처음 요소를 100으로 덮어 씀
    arr8[0] = 100;
    
    // 복사 후 배열에 대한 조작이 복사 전 배열에도 영향을 준다.
    console.log(arr4);  // [100, 20]
    console.log(arr8);  // [100, 20]
    
    // 스프레드 구문을 이용한 복사
    const arr5 = [10, 20];
    const arr7 = [...arr5];
    
    // arr7의 처음 요소를 100으로 덮어 씀
    arr7[0] = 100;
    console.log(arr5);  // [10, 20]
    console.log(arr7);  // [100, 20]

     

     

    7. 객체 생략 표기법

    // 객체 생략 표기법
    // 객체 속성명과 설정할 변수명이 같으면 생략할 수 있다.
    // 속성과 변수명이 같은 경우 ①
    const name = "휴닝카이";
    const age = 23;
    
    // user 객체 정의(속성은 name, age)
    const user = {
      name: name,
      age: age,
    };
    
    console.log(user);
    
    // 속성과 변수명이 같은 경우 ②
    // 객체 설정에서 :(콜론) 이후를 생략하고 하나로 모을 수 있다.
    // 객체 분할 대입에서 alias를 붙이는 방법의 반대 형태이다.
    const name1 = "최수빈";
    const age1 = 25;
    const user1 = {
      name1,
      age1,
    };
    
    console.log(user1);

     

    8. map, filter

    // 기존 for문
    const nameArr = ["휴닝카이", "최수빈", "강태현"]
    
    // for문을 이용한 배열 처리
    for(let index = 0; index < nameArr.length; index++) {
      console.log(nameArr[index]);
    }
    
    // map() 에서는 배열을 순서대로 처리한 결과를 배열로 밭을 수 있다.
    // 배열.map() 
    const nameArr1 = ["휴닝카이", "최수빈", "강태현"]
    
    // 화살표 함수는 배열의 각 요소를 인수로 받아 처리할 수 있으며, 이 인수는 콜백 함수 내에서 사용할 수 있다.
    // 배열의 각 요소는 map 메서드의 콜백 함수로 전달되어 처리되며, 콜백 함수는 처리된 값을 반환한다.
    const nameArr2 = nameArr1.map((name) => { return name });
    console.log(nameArr2);
    // for문을 map() 사용
    const nameArr3 = nameArr2.map((name) => console.log(name));
    
    console.log('--------------');
    
    // filter 함수는 return 뒤의 조건식을 입력해서 일치는 것만 반환한다.
    // 홀수 추출하기
    const numArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    const newArr = numArr.filter((num) => { return num % 2 === 1; });
    console.log(newArr);   // [1, 3, 5, 7, 9]

    // for문을 index를 이용해 요소를 순서대로 출력
    const nameArr = ["휴닝카이", "최수빈", "강태현"]
    
    for(let index = 0; index < nameArr.length; index++) {
      console.log(`${index + 1}번째는 ${nameArr[index]}입니다.`);
    }
    
    // map()의 인수를 이용해 요소 순서대로 추출
    // 두번째에 인수의 index를 넣는다.
    console.log("========================")
    nameArr.map((name, index) => console.log(`${index + 1}번째는 ${name}입니다.`));
    
    // 님을 붙인 새로운 배열 생성
    const newArr = nameArr.map((name) => {
      if(name === "휴닝카이") {
        return `${name}님`;
      } else {
        return `${name}님`;
      }
    });
    console.log(newArr);

     

    9. 삼항연산자

    // 삼항 연산자 조건 ? 조건이 true 일 때 처리 : 조건이 false 일 때 처리
    // 입력값에 대한 메시지 출력
    // 수치를 변환해 출력하는 함수
    const printFormattedNum = (num) => {
      // num의 타입이 문자열이면 toLocaleString() : 숫자를 세자리 씩 콤마로 구분
      // 입력값을 포맷한 결과를 저장하는 변수
      const formattedNum = typeof num === "number" ? num.toLocaleString() : "숫자를 입력하십시오";
      console.log(formattedNum);
    }
    
    printFormattedNum(1500);
    printFormattedNum("1500");
    
    // 함수 return 부분에 삼항 연산자 이용
    // 두 인수의 합이 100을 넘는지 판정하는 함수
    const checkSumOver100 = (num1, num2) => {
      return num1 + num2 > 100 ? "100을 넘었습니다!" : "100 이하입니다."
    }
    console.log(checkSumOver100(80, 40));
    console.log(checkSumOver100(70, 30));

     

    10. 논리 연산자의 원래 의미 && ||

    논리연산자 &&와 ||는 보통 '그리고(AND)' 와 '또는(OR)' 으로 알고 있다.

    논리 연산자의 구조는 리액트 개발에서도 중요하다.

    // || (OR)
    // 논리 연산자 ||이 연산자의 왼쪽이 false라고 판정하면 오른쪽을 반환
    // 반대로 왼쪽이 true이면 왼쪽을 반환한다.
    // 자바스크립트에서 false 판정 (null, undefined, 0)
    const num = null;
    const fee = num || "금액을 설정하지 않았습니다.";
    
    console.log(fee); // 금액을 설정하지 않았습니다.
    
    // 논리 연산자를 이용한 조건 분기
    const flag1 = true;
    const flag2 = false;
    // const flag1 = false;
    // const flag2 = true;
    // 왼쪽이 false이면 오른쪽은 반환(왼쪽이 true이면 왼쪽 반환)
    // 결과적으로 '또는(OR)' 같은 동작을 하게 된다.
    if(flag1 || flag2) {
      console.log("두 플래그 중 어느 하나는 true입니다.");
    }

    // && (AND)
    // 논리연산자 &&는 왼쪽을 true로 판정하면 오른쪽을 반환(||과 반대)
    const num2 = 100;
    const fee2 = num2 && "금액이 설정되었습니다.";
    
    console.log(fee2);  // 금액이 설정되었습니다.
    
    // 왼쪽이 false로 판정하면 왼쪽 반환
    // 왼쪽이 false로 판정되면 그 값을 즉시 반환하고 연산을 종료한다.
    const num3 = 0; // 0은 false로 평가됨
    const fee3 = num3 && "금액이 설정되었습니다."; // num3가 false로 평가되므로 0 반환
    
    console.log(fee3); // 0
    
    // 논리 연산자를 이용한 조건 분기
    // const flag3 = false;
    // const flag4 = true;
    const flag3 = true;
    const flag4 = false;
    // && 연산자는 첫번째 조건이 true 일때만 두번째 조건을 평가한다.
    // flag3와 flag4 중 하나라도 falsy이면 전체 결과는 falsy가 된다.
    
    if(flag3 && flag4) {
      console.log("둘 다 ture입니다.");
    } else {
      console.log("둘 중 하나가 true입니다.");
    }

     

    • falsy, truthy, nullish
    • 자바스크립트에서는 문자열도 암묵적으로 boolean 으로 변환할 수 있다.
    • 그래서 if("고양이") { ~ } 같은 처리를 할 수 있다.
    • 암묵적으로 true로 변환되는 값을 truthy, false로 변환되는 값을 falsy라고 부른다.

    1. Falsy
    "Falsy" 값은 JavaScript에서 논리적 컨텍스트(예: 조건문)에서 false로 평가되는 값

    Falsy 값의 종류 :
    false
    0 (숫자 0)
    "" (빈 문자열)
    null
    undefined
    NaN (Not a Number)

    if (0) {
      console.log("이 메시지는 출력되지 않습니다."); // 0은 falsy
    }
    
    if ("") {
      console.log("이 메시지도 출력되지 않습니다."); // 빈 문자열은 falsy
    }

     

    2. Truthy
    "Truthy" 값은 falsy가 아닌 모든 값으로, 논리적 컨텍스트에서 true로 평가된다.

     

    Truthy 값의 예 :
    true
    모든 숫자 (0을 제외한 모든 숫자, 음수 포함)
    "hello" (비어 있지 않은 문자열)
    [] (빈 배열)
    {} (빈 객체)
    모든 객체 또는 배열
    "false" (문자열로서의 "false"도 truthy)

    if (42) {
      console.log("이 메시지는 출력됩니다."); // 42는 truthy
    }
    
    if ("hello") {
      console.log("이 메시지도 출력됩니다."); // "hello"는 truthy
    }

     

    3. Nullish
    "Nullish" 값은 null과 undefined를 의미한다. 이 두 값은 ?? (nullish coalescing operator)와 같은 연산자에서 사용된다.

    Nullish 값의 종류 :
    null
    undefined


    **Nullish 병합 연산자(??)**는 피연산자가 nullish 값이면 오른쪽 피연산자를 반환하고, 그렇지 않으면 왼쪽 피연산자를 반환한다.

    let foo = null;
    let bar = foo ?? "기본값";
    console.log(bar); // "기본값" 출력 (foo가 null이기 때문)
    
    foo = 0;
    bar = foo ?? "기본값";
    console.log(bar); // 0 출력 (0은 nullish가 아니므로 foo 값이 반환됨)

     

    참고

    모던 자바스크립트로 배우는 리액트 입문

    ChatGPT

    'JS&React' 카테고리의 다른 글

    리액트 기본 - Props  (0) 2024.08.29
    리액트 기본 - JSX, 컴포넌트, 이벤트와 스타일  (0) 2024.08.29
    자바스크립트 DOM 조작(1)  (0) 2024.08.24
    [기술 면접] 호이스팅의 문제점  (0) 2024.08.22
    React 설치  (0) 2024.07.03
Designed by Tistory.