정환님의 인프런 [한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지]강좌를 참고하여 작성하였습니다. 

https://www.inflearn.com/course/%ED%95%9C%EC%9E%85-%EB%A6%AC%EC%95%A1%ED%8A%B8#

 

한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지 - 인프런 | 강의

개념부터 독특한 프로젝트까지 함께 다뤄보며 자바스크립트와 리액트를 이 강의로 한 번에 끝내요. 학습은 짧게, 응용은 길게 17시간 분량의 All-in-one 강의!, 리액트, 한 강의로 끝장낼 수 있어요.

www.inflearn.com


Why React?

🍅첫 번째 이유 - 컴포넌트 기반 제작

  • 만약, 모든 요소가 다 같지만 딱 한 섹션만 서로 다른 페이지 100개가 있을 경우, 페이지들을 대조했을때 중복되는 코드가 너무 많다. 
  • 중복된 부분 중 수정해야 할 부분이 생긴다면 우리는 100개의 페이지를 전부 수정해야 하는 문제 발생 -1
    • -> Shotgun Surgery🧨(산탄총 수술)이라고 한다.
  • 컴포넌트화 : 다른 페이지에서도 공통적으로 같이 사용해야 하는 요소들을 컴포넌트로 만어 사용하는 방식. 
    • 공통으로 사용되는 요소에 수정 사항이나 문제가 발생했을 때 수정이 훨씬 수월해지고 쉬워진다. 
    • = 유지보수가 쉬워진다.
  • 리액트는 컴포넌트 기반의 UI 라이브러리
    • html 요소들을 컴포넌트화 해서 재사용할 수 있는 기술이 있다. 

🍅두 번째 이유 - 선언형 프로그래밍

명령형 프로그래밍
(절차를 하나하나 다 나열 해야함)
선언형 프로그래밍
(그냥 목적을 바로 말함)
1. 결과를 표시할 요소를 가져온다. 
(id=result)

2. 현재 결과값을 10진수 기준, 숫자형으로 변환해서 가져와 current라는 상수에 저장한다. 

3. Current상수테 저장된 값을 결과를 표시할 요소의 값에 plus라면
+1 해서 넣고, minus라면 -1해서 넣는다. 
1. Plus를 누르면 result값에 +1 한다. 
Minus를 눌렀다면 반대로 한다. 
  • 명령형 프로그래밍 방식에는 jQuery가 있고, 선언형 프로그래밍 방식에는 React.js가 있다. 

🍅세 번째 이유 - Virtual DOM

  • DOM(document object model): 문서 객체 모델

  • HTML을 트리 형태로 변환시켜 놓은 객체

  • 변환된 DOM은 이런 흐름에 따라 눈에 보이게 된다. 
  • 이런식으로 브라우저가 많은 일을 수행하기 때문에 노드의 수가 많아질수록, 변경이 잦아질수록 성능 저하로 이어질 수 있다.

  • Virtual DOM이란 실제 DOM에서 처리하는 방식이 아닌 Virtual DOM과 메모리에서 미리 처리하고 저장한 후, 실제 DOM과 동기화하는 프로그래밍 개념이다. 
  • 5번 업데이트 할 것을 한번만 업데이트 한다 정도의 개념. 

Create React App

🍅프로젝트 생성

  • npx create-react-app [프로젝트 이름] 명령어를 이용해서 리액트 프로젝트를 생성한다. 
  • 프로젝트 구조는 다음과 같다. 

🍅프로젝트 실행

  • pakage.json을 확인해보면 긴 문자열 명령을 별명을 붙여서 부를 수 있는 기능인 scripts가 있다.

  • npm start 명령어를 입력하면 프로젝트가 실행된다. 
  • 프로그램을 종료하고 싶다면 터미널에 ctrl(^)+c를 입력한다. 

🍅src > App.js

//App.js

import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
  • App.js의 초기 상태.
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <h2>Hello World</h2>
      </header>
    </div>
  );
}

export default App;

  • App.js의 header안의 내용을 지우고 h2태그를 추가했더니 화면이 다음과 같이 바꼈다. 

  • 개발자 도구로 확인본 결과는 다음과 같다. 
  • 결론적으로 App.js 파일에 있는 App()이라는 함수가 리턴하는 html들이 id가 root인 div 아래로 자식 요소로 들어갔다고 유추가 가능하다. 

🍅src > index.js

//index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
  • index.js의 초기 상태이다. 
  • 확인해 볼 수 있는 것 
    • root.render이라고 해서 root를 화면에 그리고 있다. 
    • React.StricMode태그 안에 <App />이라고 되어 있는데 상단의 import로 App을 불러와서 사용하고 있는 것이다. 
    • ** 강의에선 React.render으로 되어있지만 강의 수강 기준 현재는 createRoot를 이용하는 방법을 사용한다. 
  • 즉 아까 봤던 App.js에 있던 App()함수가 return하는 값이 id가 root인 div아래로 들어가게 된다. 

🍅public > index.html

<!-- index.html-->

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>
  • 그렇다면 id가 root인 div는 어디에 위치할까?
  • 바로 public안에 있는 index.html안에 있다. 
  • 💡정리:
    • 리액트 앱이 실행이 되면 src밑에 index.js가 실행이 되면서 index.html안에 있는 id가 root인 div아래로 app.js 안에 있는 App()함수의 리턴값이 들어가게 되는 것. 

📁node_modules

일부 모듈만 캡쳐.

  • src, public 외의 또 다른 패키지. 
  • node.js 패키지의 구성 요소 중 하나로 외부 모듈을 저장하고 있는 폴더. 
  • 상당히 많은 모듈들을 가지고 있기 때문에 하나하나 설치할 수 없기에 create-react-app을 이용하여 한번에 설치를 했다. 
  • 사이즈가 상당히 크기 때문에 배포나 전송시 많은 시간이 소요될 수 있다. 
  • node-modules는 삭제해도 문제가 없다. 왜냐하면 pakage.json에 필요한 모듈이 명시가 되어있으며,  npm i (npm install)를 이용하여 설치할 수 있기 때문이다. 

📁public

  • favicon.ico : 웹사이트의 아이콘
  • index.html : 위에서 확인
  • logo192.png, logo512.png, manifest.jspn : 해당 강의에서 사용하지 않을 파일.
  • robots.txt : 구글이나 네이버가 웹사이트를 수집할 때, 수집이 가능/불가능한 경로를 명시하는 파일.

📁src

  • App.css : 스타일파일
  • App.js : 위에서 확인
  • App.test.js : 테스트를 위한 파일. 해당 강의에선 사용x
  • index.css : 스타일 파일
  • index.js : 위에서 확인
  • logo.svg : 해당 강의에선 사용x
  • reportWebVitals.js : 해당 강의에선 사용x
  • setupTests.js : 해당 강의에선 사용x

🍅JSX

//App.js

import './App.css';

function App() {
  let name = "cloudmato";
  return (
    <div className="App">
      <header className="App-header">
        <h2>Hello {name} World</h2>
      </header>
    </div>
  );
}

export default App;

  • app.js파일로 돌아가서 App함수 밑에 지역변수인 name을 선언해주고 중괄호{ }를 사용해서 <h2>안에 넣어주면 화면에 반영이 된다.
  • JSX :  javascript형식과 html형식을 합쳐서 사용할 수 있는 Javascript의 확장 문법 
  • React는 이렇게 App()이라는 함수를 만들고 return으로 JSX 문법의 html을 리턴해주면서 컴포넌트를 만든다. 

🍅 export default App;

  • common.js 모듈 시스템에서는 module.exports를 이용해서 모듈을 내보냈었다. 
  • ES 모듈 시스템에서는 export default 를 이용해서 모듈을 내보내게 된다. 
  • 내보낸 모듈은 다른 파일에서 import [이름] from [경로] 이런 식으로 사용하게 된다. 
    • [이름]은 다른 이름으로 변경이 가능하다. 

JSX

🍅컴포넌트 만들기 - header역할을 할 컴포넌트

  • src 디렉토리 아래 myheader.js 파일 생성
//myHeader.js

const MyHeader = () => {};

export default MyHeader;
//App.js

import './App.css';

import MyHeader from './MyHeader';

function App() {
  let name = "cloudmato";
  return (
    <div className="App">
      <MyHeader />
      <header className="App-header">
        <h2>Hello {name} World</h2>
      </header>
    </div>
  );
}

export default App;

  •  화살표함수로 MyHeader를 만든 후에 export default로 내보낸 후 App.js에 불러와주었다. 
//Myfooter.js

const MyFooter = () => {
    return <footer>MyFooter</footer>;
};

export default MyFooter;
  • Myfooter.js 파일을 생성한 후 export default를 이용해 내보내 주었다. 
//index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import MyFooter from './MyFooter';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <MyFooter />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals

  • index.js 에 <MyFooter />를 넣어주면 MyFooter가 렌더링 된다. 
  • 즉, index.js에서는 최상위 컴포넌트를 정의해줄 수 있다. 

🍅JSX 문법 - 1. 닫힘규칙

  • 예를 들어 <div></div> 등과 같이 닫힘 태그를 꼭 써주어야 한다. 
  • <br>, <hr> 같은 경우 <br /><hr /> 등과 같이 self-closing해주어야 한다. 

🍅JSX 문법 - 2. 최상위 태그 규칙

  • JSX로 컴포넌트를 만들어서 리턴하려면 반드시 하나의 최상위 태그로 다른 모든 태그들을 감싸주어야 한다. 
  • 최상위 태그: 가장 바깥에 있는 태그
//App.js

import './App.css';
import React from 'react';

import MyHeader from './MyHeader';

function App() {
  let name = "cloudmato";
  return (
    <React.Fragment>
      <MyHeader />
      <header className="App-header">
        <h2>Hello {name} World</h2>
      </header>
      </React.Fragment>
  );
}

export default App;
  • 만약 최상위 태그로 묶고 싶지 않다면 react.fragment라는 기능을 사용해주면 된다. 
//App.js

import './App.css';

import MyHeader from './MyHeader';

function App() {
  let name = "cloudmato";
  return (
    <>
      <MyHeader />
      <header className="App-header">
        <h2>Hello {name} World</h2>
      </header>
      </>
  );
}

export default App;
  • 이런 식으로 빈 태그를 만들어 줘도 된다. 

🍅JSX문법과 CSS 결합하기 - 1. css파일 이용하기

//App.js

import './App.css';

import MyHeader from './MyHeader';

function App() {
  let name = "cloudmato";
  return (
    <div className="App">
      <MyHeader />
      <h2>Hello {name} World</h2>
      <b id='boldText'>react.js</b>
    </div>
  );
}

export default App;
  • import를 이용하여 css파일을 불러와 사용할 수 있다. 
  • jsx문법에서는 <div className="App">처럼 className 속성을 사용해주어야 한다. 
/* App.css */

.App {
  text-align: center;
  background-color: orangered;
}


h2 {
  color: white;
}

#boldText {
  color: green;
}

  • 클래스, 태그, 아이디 수준의 css가 변경된 것을 확인할 수 있다. 

🍅JSX문법과 CSS 결합하기 - 1. 인라인 스타일링 방식 이용하기

//App.js

// import './App.css';

import MyHeader from './MyHeader';

function App() {
  let name = "cloudmato";

  const style = {
    App : {
      backgroundColor : "red",
    },
    h2 : {
      color: "black",
    },
    bold_text: {
      color: "green",
    },
  };

  return (
    <div className="App" style={style.App}>
      <MyHeader />
      <h2 style={style.h2}>Hello {name} World</h2>
      <b id='boldText' style={style.bold_text}>react.js</b>
    </div>
  );
}

export default App;

  • 스타일 객체를 만들어서 태그 안에 style 속성으로 넣어줘 스타일을 적용시킬 수 있다. 

🍅JSX의 JavaScript값 사용하기

  const func = () => {
    return 'func';
  }

  return (
    <div className="App" style={style.App}>
      <MyHeader />
      <h2 style={style.h2}>{func()} {name} {1+2}</h2>
      <b id='boldText' style={style.bold_text}>react.js</b>
    </div>
  );

  • { } 중괄호를 이용해서 함수, 변수, 계산식 등 문자열을 표현될 수 있다. 
  const number = 5;

  return (
    <div className="App" style={style.App}>
      <MyHeader />
      <h2 style={style.h2}>{func()} {name} {1+2}</h2>
      <b id='boldText' style={style.bold_text}>{number}는 {number % 2 === 0 ? "짝수" : "홀수"}</b>
    </div>
  );
}

  • 다음과 같이 조건부 렌더링도 가능하다. 

State(상태)

  • 계속해서 변화하는 특정 상태
  • 상태에 따라 각각 다른 동작을 함

  • React에서 말하는 상태, 즉 state는 컴포넌트가 갖는 계속 값이 바뀔 동적인 데이터. 
  • 이 상태를 바꾸는 관리는 컴포넌트가 하게 된다. 

🍅Counter 예제

// Counter.js

const Counter = () => {
    return (
        <div>
            <h2>0</h2>
            <button>+</button>
            <button>-</button>
        </div>
    )
}

export default Counter;
//App.js

import Counter from './Counter';
import MyHeader from './MyHeader';

function App() {
  return (
  <div>
    <MyHeader />
    <Counter />
  </div>
  );
}

export default App;

  • Counter.js파일을 만들어주고 App.js에 불러와 준 화면이다. 
  • 현재는 버튼을 눌러도 아무런 변화가 일어나지 않는다. 
// Counter.js

import React, {useState} from "react";  //state는 react의 기능이기 때문에 React를 import해야한다. 


const Counter = () => {

    const [count, setCount] = useState(0);

    const onIncrease = () => {
        setCount(count + 1);
    };
    
    const onDecrease = () => {
        setCount(count - 1);
    };


    return (
        <div>
            <h2>{count}</h2>
            <button onClick={onIncrease}>+</button>
            <button onClick={onDecrease}>-</button>
        </div>
    )
}

export default Counter;
  
  • 버튼을 누를 때(=count state가 변경될 때)마다 숫자가 변경되는 것을 확인할 수 있다. 
  • rerender : 컴포넌트는 자신이 가진 state, 상태가 변화하면 화면을 다시 그린다. 
    • 즉, 함수가 다시 호출 된다. 
  • 여러개의 state를 하나의 컴포넌트가 가져도 된다. 

Props

  • 컴포넌트에 데이터를 전달하는 방법

🍅실습

// Counter.js

import React, {useState} from "react";  //state는 react의 기능이기 때문에 React를 import해야한다. 


const Counter = () => {

    const [count, setCount] = useState(0);

    const onIncrease = () => {
        setCount(count + 1);
    };
    
    const onDecrease = () => {
        setCount(count - 1);
    };


    return (
        <div>
            <h2>{count}</h2>
            <button onClick={onIncrease}>+</button>
            <button onClick={onDecrease}>-</button>
        </div>
    )
}

export default Counter;
  • 이전 영상에서 만든 count.js 파일이다. 
//App.js

import Counter from './Counter';
import MyHeader from './MyHeader';

function App() {
  return (
  <div>
    <MyHeader />
    <Counter initialValue = {5}/>
  </div>
  );
}

export default App;
  • 여기서 Counter 컴포넌트는 App컴포넌트의 자식 요소로 배치되어 있다. 
  • 이때 App컴포넌트가 전달한 값을 Counter의 초기값으로 사용하려면 어떻게 해야 할까?
  • initailValue 속성을 이용한다. 다만, 이렇게 값을 준다고 바로 적용되진 않는다. 
// Counter.js

import React, {useState} from "react";  //state는 react의 기능이기 때문에 React를 import해야한다. 


const Counter = (props) => {
    console.log(props);

    const [count, setCount] = useState(0);

    const onIncrease = () => {
        setCount(count + 1);
    };
    
    const onDecrease = () => {
        setCount(count - 1);
    };


    return (
        <div>
            <h2>{count}</h2>
            <button onClick={onIncrease}>+</button>
            <button onClick={onDecrease}>-</button>
        </div>
    )
}

export default Counter;

  • props로 값을 받아오고 콘솔을 찍어보면 객체 안에 initialValue가 담겨서 온다. 
    <Counter a = {1} b = {2} initialValue = {5}/>

  • 이런 식으로 여러개의 prop을 전달해도 전부 객체에 담겨서 전달된다. 
  • 하지만 이렇게 전달하게 되면 굉장히 길어지기 때문에 불편하다. 
//App.js

import Counter from './Counter';
import MyHeader from './MyHeader';

function App() {

  const counterProps = {
    a : 1,
    b : 2,
    initialValue : 5
  };

  return (
  <div>
    <MyHeader />
    <Counter {...counterProps}/>
  </div>
  );
}

export default App;

  • 이렇게 객체에 담아서 스프레드 연산자(...)에 담아 전달을 하게 되도 이전 방법과 같이 객체에 담겨서 전달된다. 
// Counter.js

import React, {useState} from "react";  //state는 react의 기능이기 때문에 React를 import해야한다. 


const Counter = ({initialValue}) => {

    const [count, setCount] = useState(initialValue);

    const onIncrease = () => {
        setCount(count + 1);
    };
    
    const onDecrease = () => {
        setCount(count - 1);
    };


    return (
        <div>
            <h2>{count}</h2>
            <button onClick={onIncrease}>+</button>
            <button onClick={onDecrease}>-</button>
        </div>
    )
}

export default Counter;
  • 이런식으로 비구조적 할당을 해준다. 
// Counter.js

import React, {useState} from "react";  //state는 react의 기능이기 때문에 React를 import해야한다. 


const Counter = ({initialValue}) => {

    const [count, setCount] = useState(initialValue);

    const onIncrease = () => {
        setCount(count + 1);
    };
    
    const onDecrease = () => {
        setCount(count - 1);
    };


    return (
        <div>
            <h2>{count}</h2>
            <button onClick={onIncrease}>+</button>
            <button onClick={onDecrease}>-</button>
        </div>
    )
}

Counter.defaultProps = {
    initialValue: 0,
}

export default Counter;
  • defaultProps를 이용하여 기본값을 지정해 주었을 때, 필요한 정보가 유실되었어도 기본값을 할당해준다. 

🍅실습 - 홀/짝 판별

const OddEvenResult  = () => {
    return <></>
};

export default OddEvenResult;
  • 홀수를 판별해줄 컴포넌트를 다른 파일에 만들어준다. 
// Counter.js

import React, {useState} from "react";  //state는 react의 기능이기 때문에 React를 import해야한다. 
import OddEvenResult from "./OddEvenResult";


const Counter = ({initialValue}) => {

    const [count, setCount] = useState(initialValue);

    const onIncrease = () => {
        setCount(count + 1);
    };
    
    const onDecrease = () => {
        setCount(count - 1);
    };


    return (
        <div>
            <h2>{count}</h2>
            <button onClick={onIncrease}>+</button>
            <button onClick={onDecrease}>-</button>
            <OddEvenResult count = {count}/>
        </div>
    );
};

Counter.defaultProps = {
    initialValue: 1,
}

export default Counter;
  • 이때 판별할 수를 Counter에서 받아와야 하기 때문에 props전달을 위해 OddEvenResult를 Counter의 자식요소로 배치한 후, count값을 전달해준다. 
const OddEvenResult = ({count}) => {
    // console.log(count);
    console.log("RENDER!");

    return <>{count % 2 ===0 ? "짝수" : "홀수" }</>
};

export default OddEvenResult;
  • 받아온 count값으로 홀짝 여부를 반환해주는 컴포넌트이다. 

  • 이런 결과값이 나온다. 미관상의 이유로 더 수정해주도록 하자. 
const Container = ({children}) => {
    return (
    <div style={{ margin: 20, padding: 20, border: "1px solid gray"}}>
        {children}
    </div>
    );
};

export default Container;
  • Container 컴포넌트를 만들어주는데, 이때 children이라는 자식요소들을 props로 받아준다. 
//App.js

import Counter from './Counter';
import MyHeader from './MyHeader';
import Container from './Container';

function App() {

  const counterProps = {
    a : 1,
    b : 2,
    // initialValue : 5
  };

  return (
    <Container>
      <div>
        <MyHeader />
        <Counter {...counterProps}/>
      </div>
     </Container>
  );
}

export default App;
  • App.js에서 요소들을 Container으로 묶어주면 다음과 같은 결과물이 나온다. 

이정환님의 인프런 [한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지]강좌를 참고하여 작성하였습니다. 

https://www.inflearn.com/course/%ED%95%9C%EC%9E%85-%EB%A6%AC%EC%95%A1%ED%8A%B8#

 

한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지 - 인프런 | 강의

개념부터 독특한 프로젝트까지 함께 다뤄보며 자바스크립트와 리액트를 이 강의로 한 번에 끝내요. 학습은 짧게, 응용은 길게 17시간 분량의 All-in-one 강의!, 리액트, 한 강의로 끝장낼 수 있어요.

www.inflearn.com


Hello World

🍅 자바 스크립트란?

  • HTML
  • CSS
  • Javascript

🍅 자바 스크립트의 실행 환경

  • 엔진

🍅 실습

  • 개발자 도구 이용(F12)
  • codesandbox 이용(해당 강의에선 Vanilla  템플릿 사용)

변수와 상수

  • 변수는 let을 이용하여 선언할 수 있다. 

🍅 변수명 명명 규칙

  • 기호 사용은 불가능하다. (단, _$ 기호는 사용 가능하다.)
  • 변수명은 문자로 시작해야 한다. 즉, 숫자로 시작하는 것은 불가능하다. 
  • javascript의 예약어는 변수명으로 사용할 수 없다. 

🍅 var을 이용한 변수 선언

  • 같은 변수명으로 새로운 값을 새롭게 선언하여도 오류가 나지 않는다. 
  • 그래서 앞으로 실수는 let으로 선언. 

🍅 상수

  • 상수는 선언 이후에 값을 변경하는 것이 불가능하다. 

자료형과 형 변환

🍅 자바스크립트의 자료형

  • Primitive Type (원시타입) :
    • 한 번에 하나의 값만 가질 수 있음. 하나의 고정된 저장 공간 이용
  • Non - Primitive Type (비 원시 타입)
    • 한번에 여러 개의 값을 가질 수 있음 여러 개의 고정되지 않은 동적 공간 사용

🍅 원시타입

  • 숫자형

  • 문자형

  •  boolean 형

  • Null 

  • undefined

🍅 형변환

  • 묵시적 형 변환

  •  명시적 형 변환


연산자

🍅 대입 연산자

🍅 산술 연산자

🍅 연결 연산자

🍅 복합 연산자

🍅 증감 연산자

  • 숫자형에만 사용할 수 있다. 

🍅 논리 연산자

🍅 비교 연산자

== 자료형에 관계없이 값이 같다. 
=== 엄격하게 같다. (자료형과 값이 같다.)
!= 자료형에 관계없이 같지 않다. 
!== 엄격하게 같지 않다. (자료형과 값이 다르다.)

< 작다
<= 작거나 같다
> 크다
>= 크거나 같다

🍅 typeof  연산자

🍅 Null 병합 연산자

  • a 가  null이거나 undefined 이면  a, 아니면 10을 할당한다. 

조건문

  • 참 거짓에 따라서 각자 다른 지시를 내리기 위해 사용

🍅if - else if - else 문

🍅 switch  문


함수


함수표현식 & 화살표 함수


콜백함수

매개변수에 함수를 넣는다. 


객체

객체는 여러가지 데이터를 담을 수 있는 Non-Primitive Type(비 원시 타입)이다. 

🍅 객체를 생성

let person1 = new Object(); //생성자 방식

let person2 = {};    //객체 리터럴 방식

 

let person = {
    key: "value",   //프로퍼티 (객체 프로퍼티)
    key1: 123,
    key2: true,
    key3: undefined,
    key4: [1,2],
    key5: function () {}
};    //객체 리터럴 방식

console.log(person);    
//{
//  key: 'value',
//  key1: 123,
//  key2: true,
//  key3: undefined,
//  key4: [ 1, 2 ],
//  key5: [Function: key5]
//} 출력
  • 객체는 key와 value로 이루어진 프로퍼티로 이루어진다. 
  • 어떠한 자료형이라도 value값으로 들어갈 수 있으며, key는 문자열이여야만 한다. 

🍅 객체의 값을 이용하는 방법

let person = {
    name: "cloudmato",
    age: 24
};

console.log(person["name"]);    //괄호 표기법 cloudmato
console.log(person.age);        //점 표기법 24
  • 괄호 표기법과 점 표기법이 있다. 
  • 다만 괄호 표기법으로 객체의 값을 이용할 때에는 반드시 문자열("")형태로 이용해야 한다. 
  • 문자열로 이용하지 않을 경우 변수로 인식하기 때문. 
//괄호 표기법에 ""사용을 안하려고 할 경우 변수를 만들어 사용하면 된다. 
const nameV = "name";
console.log(person[nameV]);
// 동적으로 파라미터를 넣을 상황에는 괄호 표기법이 적절하다. 

let person = {
    name: "cloudmato",
    age: 24
};

console.log(getPropertyValue("name"));

function getPropertyValue (key){
    return person[key];
}

🍅 객체 생성 이후에 프로퍼티 추가/수정

let person = {
    name: "cloudmato",
    age: 24
};

//주소지를 프로퍼티로 넣고 싶은 상황. 
person.location = "korea";  //점 표기법 이용. 
person["gender"] = "female" //괄호 표기법 이용

//프로퍼티의 값 수정. 
person.name = "cloudmato00";
person["age"] = 25;

console.log(person);
  • 생성된 객체는 점 표기법과, 괄호 표기법을 이용해서 값을 추가/수정 가능하다.
// let person = {
//     name: "cloudmato",
//     age: 24
// };

const person = {
    name: "cloudmato",
    age: 24
};

//주소지를 프로퍼티로 넣고 싶은 상황. 
person.location = "korea";  //점 표기법 이용. 
person["gender"] = "female" //괄호 표기법 이용

//프로퍼티의 값 수정. 
person.name = "cloudmato00";
person["age"] = 25;

console.log(person);
  • 이때, 객체를 let에서 const로 바꿔도 오류가 나지 않는다.
  • 왜냐하면 person이라는 상수가 갖는 객체(Object)를 수정한 것이지, person이라는 상수 자체를 바꾼 것이 아니기 때문.
person = {
    age: 20
}
  • 상수를 변경하는 경우는 다음과 같이 대입연산자(=)를 통하여  상수 자체에 새로운 객체를 대입하는 것이다. 
  • 따라서 자유로운 추가/수정이 가능하다. 

🍅프로퍼티의 삭제 - 

delete 사용

const person = {
    name: "cloudmato",
    age: 24
};
console.log(person);    //{ name: 'cloudmato', age: 24 }

delete person.age;      //점 표기법 사용
console.log(person);    //{ name: 'cloudmato' }

delete person["name"];  //괄호 표기법 사용
console.log(person);    //{}
  • 그러나 이런 방법은 객체인 person과 이 property간의 연결만 끊을 뿐 실제 메모리는 그대로 사용하게 된다.

= null 사용

const person = {
    name: "cloudmato",
    age: 24
};

person.name = null;

console.log(person);
  • null을 대입할 경우 메모리에서도 삭제할 수 있으므로 이런 방법을 추천해주셨다.  

🍅 객체의 메서드

const person = {
    name: "cloudmato",  //member
    age: 24,            //member
    say: function () {
        console.log("hello");
    }   //method -> 방법
};

person.say();
person["say"]();
  • 객체의 프로퍼티 중 함수를 메서드, 함수가 아닌 것을 멤버라고 한다. 
const person = {
    name: "cloudmato", 
    age: 24,           
    say: function () {
        console.log(`안녕 나는 ${this.name}`);
        console.log(`안녕 내 나이는 ${this["age"]}`);
    }  
};

person.say();
// 안녕 나는 cloudmato
// 안녕 내 나이는 24
  • this를 사용하여 객체의 메서드에서 멤버를 접근할 수 있다. 

🍅 존재하지 않는 프로퍼티에 접근한 경우

const person = {
    name: "cloudmato", 
    age: 24,           
    say: function () {
        console.log(`안녕 나는 ${this.name}`);
        console.log(`안녕 내 나이는 ${this["age"]}`);
    }  
};

console.log(person.gender); //undefined
  • 에러를 일으키지 않고 undefined를 띄운다. 
  • 이러한 방식은 유연한 프로그래밍을 가능하게 하지만 잘못된 연산을 하게 할 수도 있다. 
const person = {
    name: "cloudmato", 
    age: 24,           
    say: function () {
        console.log(`안녕 나는 ${this.name}`);
        console.log(`안녕 내 나이는 ${this["age"]}`);
    }  
};

console.log(`name : ${"name" in person}`);   //true
console.log(`name : ${"hobby" in person}`);  //false
  • in 연산자를 객체와 함께 활용하면 프로퍼티의 존재 여부를 boolean형태로 알 수 있다. 

배열

🍅배열

  • 배열은 비원지 자료형에 해당하며, 순서 있는 요소들의 집합, 즉 여러개의 항목이 들어있는 리스트이다. 
  • 여러가지 자료형이 들어갈 수 있는 특징이 있다. 
let arr = new Array();  //생성자를 이용한 생성
let arr1 = [];          //배열 리터럴

console.log(arr);  //[]

🍅배열의 각 인덱스에 접근하기

let arr = [1,2,3,4,5];
console.log(arr);

console.log(arr[0]);    //1
console.log(arr[1]);    //2
console.log(arr[2]);    //3
console.log(arr[3]);    //4
console.log(arr[4]);    //5
  • 배열의 이름을 쓰고 대괄호 안에 인덱스를 사용하여 접근한다. 

🍅배열 요소 추가 - push

let arr = [1,2,3,4,5];

arr.push(6);
console.log(arr);   //[ 1, 2, 3, 4, 5, 6 ]

arr.push({key: "value"});
console.log(arr);   //[ 1, 2, 3, 4, 5, 6, { key: 'value' } ]
  • push를 이용하여 요소를 추가하면 마지막 인덱스 그 다음 인덱스에 요소가 추가된다. 
  • 이때, 어떤 자료형이라도 추가할 수 있다. 

🍅배열의 길이

let arr = [1,2,3,4,5];

console.log(arr.length);    //5

반복문

  • 반복문이란 특정 명령을 반복해서 수행해야 할 때 사용하는 문법이다. 

🍅for 반복문

for(let i = 0; i < 5; i++) {
    console.log("cloudmato");
}

🍅for 반복문을 이용한 배열 순회

const arr = ["a", "b", "c"];

for(let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

🍅for 반복문을 이용한 객체 순회

let person = {
    name: "cloudmato",
    age: 24,
    tall: 164
};

const personKeys = Object.keys(person);

for(let i = 0; i < personKeys.length; i++) {
    const curKey = personKeys[i];
    const curValue = person[curKey];

    console.log(`${curKey} : ${curValue}`);
}
  • keys, values 등을 이용하여 객체를 배열처럼 만들어 순회가 가능하다. 

배열 내장함수

🍅 forEach

const arr = [1,2,3,4];

for (let i = 0; i < 4; i++) {
    console.log(arr[i]);
}
  • 해당 코드를 줄여보자. 
const arr = [1,2,3,4];

arr.forEach((elm) => console.log(elm));
  • 배열의 모든 요소를 한 번씩 순회할 수 있도록 해준다. 
  • 즉, arr이라는 배열에 forEach라는 내장함수를 사용하게 되면 이 내장함수에 전달하는 콜백 함수를 각각의 요소들에 대해서 실행한다. 

🍅map

const arr = [1,2,3,4];
const newArr = [];

arr.forEach((elm) => newArr.push(elm));

console.log(newArr);    //[ 1, 2, 3, 4 ]
  • 해당 코드를 줄여보자
const arr = [1,2,3,4];
const newArr = arr.map((elm) => {
    return elm * 2;
});

console.log(newArr);    //[ 2, 4, 6, 8 ]
  • map은 원본 배열의 모든 요소를 순회하면서 리턴된 값을 따로 배열로 반환한다. 

🍅 includes

const arr = [1,2,3,4];

console.log(arr.includes(1));   //true
console.log(arr.includes(8));   //false

🍅indexOf

const arr = [1,2,3,4];

console.log(arr.indexOf(3));     //2
console.log(arr.indexOf(10));    //-1 존재하지 않는 값
  • indexOf는 주어진 인자에 일치하는 인덱스를 반환하는 내장함수이다. 

🍅findIndex

const arr = [
    { color: "red"},
    { color: "black"},
    { color: "blue"},
    { color: "green"}
];

console.log(arr.findIndex((elm) => elm.color === "black")); //1
  • findIndex 메서드를 이용하면 콜백 함수를 전달해서 해당 콜백 함수가 true를 반환하는 첫 번째 요소를 반환한다. 

🍅filter

const arr = [
    { num: 1, color: "red"},
    { num: 2, color: "black"},
    { num: 3, color: "blue"},
    { num: 4, color: "green"}
];

console.log(arr.filter((elm) => elm.color === "blue"));
  • filter메서드는 배열에서 어떤 특정한 조건을 만족하는 요소들을 배열로 다시 반환받을 수 있도록 해준다. 

🍅slice

const arr = [
    { num: 1, color: "red"},
    { num: 2, color: "black"},
    { num: 3, color: "blue"},
    { num: 4, color: "green"}
];

console.log(arr.slice());       //배열 그대로 반환
console.log(arr.slice(1,2));    //[ { num: 2, color: 'black' } ]
  • slice메서드는 begin인덱스부터 end-1번째 인덱스까지 잘라 배열로 반환한다. 
  • 즉 begin번째 인덱스에 해당하는 요소는 반환되지 않는다. 

🍅concat

const arr = [
    { num: 1, color: "red"},
    { num: 2, color: "black"},
];

const arr1 = [
    { num: 3, color: "blue"},
    { num: 4, color: "green"}
]

console.log(arr.concat(arr1));

// [
//     { num: 1, color: 'red' },
//     { num: 2, color: 'black' },
//     { num: 3, color: 'blue' },
//     { num: 4, color: 'green' }
// ]
  • concat 메서드를 사용하면 서로 다른 배열을 붙일 수 있다. 

🍅sort

let chars = ["나", "다", "가"];

chars.sort();

console.log(chars); //[ '가', '나', '다' ]
  • sort 메서드는 원본 배열을 정렬해준다. 
let numbers = [3, 20, 1, 2, 2, 4];

numbers.sort();

console.log(numbers);   //[ 1, 2, 2, 20, 3, 4 ]
  • 하지만 sort메서드는 사전순으로 정렬을 해주기 때문에 숫자 배열 정렬을 시도하면 이런 결과가 나온다. 
let numbers = [3, 20, 1, 2, 2, 4];

const compare = (a,b) => {
    if(a > b) {
        return 1;
    }
    
    if(a < b) {
        return -1;
    }

    return 0;
}

numbers.sort(compare);
console.log(numbers);   //[ 1, 2, 2, 3, 4, 20 ]

🍅join

const arr = ["cloud", "mato"];

console.log(arr);               //[ 'cloud', 'mato' ]
console.log(arr.join());        //cloud,mato
console.log(arr.join(" "));     //cloud mato
console.log(arr.join("바보"));     //cloud바보mato

 

+ Recent posts