<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>lsm_0084.log</title>
        <link>https://velog.io/</link>
        <description>도전자</description>
        <lastBuildDate>Tue, 13 Jun 2023 07:37:14 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>lsm_0084.log</title>
            <url>https://velog.velcdn.com/images/lsm_0084/profile/46430ba2-c197-4e94-954d-a604773f58f8/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. lsm_0084.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/lsm_0084" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[UI / UX]]></title>
            <link>https://velog.io/@lsm_0084/UI-UX</link>
            <guid>https://velog.io/@lsm_0084/UI-UX</guid>
            <pubDate>Tue, 13 Jun 2023 07:37:14 GMT</pubDate>
            <description><![CDATA[<h2 id="uiuser-interface">UI(User Interface)</h2>
<blockquote>
<p>사람과 컴퓨터가 상호작용하는 시스템 (화면, 마우스, 전원 등)</p>
</blockquote>
<h2 id="uxuser-experience">UX(User Experience)</h2>
<blockquote>
<p>사용자가 서비스를 직간접적으로 이용하면서 느끼는 총체적 경험</p>
</blockquote>
<h3 id="ui-디자인">UI 디자인</h3>
<ul>
<li><p>UI 디자인 패턴(자주 사용하는 UI패턴)
모달, 토글, 탭, 태그, 자동완성, 드롭다운, 아코디언, 캐러셀, 페이지네이션 등</p>
</li>
<li><p>UI 레이아웃(그리드 시스템 (Grid System))
화면을 격자로 나눈 다음 그 격자에 맞춰 콘텐츠를 배치하는 방법
margin, column, gutter로 구성됨</p>
</li>
</ul>
<h2 id="좋은-ux를-만드는-요소">좋은 UX를 만드는 요소</h2>
<p>피터모빌의 좋은UX를 만들기 위한 7가지 요소를 참고할 것
<img src="https://velog.velcdn.com/images/lsm_0084/post/591d3d0b-7cbd-4b2b-b3dc-7bbe0bb6390e/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[과제 - StatesAirline Server]]></title>
            <link>https://velog.io/@lsm_0084/%EA%B3%BC%EC%A0%9C-StatesAirline-Server</link>
            <guid>https://velog.io/@lsm_0084/%EA%B3%BC%EC%A0%9C-StatesAirline-Server</guid>
            <pubDate>Mon, 05 Jun 2023 04:41:30 GMT</pubDate>
            <description><![CDATA[<p>이번과제는 Express 프레임워크를 이용해 만들고, 로컬 호스트와 연결해 클라이언트의 요청에 따라 항공편과 예약 데이터를 조회, 생성, 수정, 그리고 삭제하는 기능을 만든다.</p>
<h3 id="flightcontrollerjs">flightController.js</h3>
<pre><code>const flights = require(&#39;../repository/flightList&#39;);
const fs = require(&#39;fs&#39;);

module.exports = {
  // [GET] /flight
  // 요청 된 파라미터 departure_times, arrival_times 값과 동일한 값을 가진 항공편 데이터를 조회합니다.
  // 요청 된 파라미터 departure, destination 값과 동일한 값을 가진 항공편 데이터를 조회합니다.
  findAll: (req, res) =&gt; {
    const { departure_times, arrival_times, destination, departure } = req.query;
    // TODO:
    if (departure_times &amp;&amp; arrival_times) {
      let r = flights.filter(i =&gt; i.departure_times === departure_times &amp;&amp; i.arrival_times === arrival_times);
      return res.json(r);
    }
    else if (departure &amp;&amp; destination) {
      let r = flights.filter(i =&gt; i.departure === departure &amp;&amp; i.destination === destination);
      return res.json(r);
    }
    return res.json(flights);
  },
  // [GET] /flight/:uuid
  // 요청 된 uuid 값과 동일한 uuid 값을 가진 항공편 데이터를 조회합니다.
  findById: (req, res) =&gt; {
    const { uuid } = req.params;
    // TODO:
    let r = flights.filter(i =&gt; i.uuid === uuid);
    return res.json(r);
  },

  // Advanced
  // [PUT] /flight/:uuid 요청을 수행합니다.
  // 요청 된 uuid 값과 동일한 uuid 값을 가진 항공편 데이터를 요쳥 된 Body 데이터로 수정합니다.
  update: (req, res) =&gt; {
    const { uuid } = req.params;
    const bodyData = req.body;
     // TODO:
     let r = null;  //업데이트된 항공편 선언
      flights.forEach((i, j) =&gt; { //foreach로 순회
      if (i.uuid === uuid){
         flights[j] = { ...i, ...bodyData }; //인덱스에 기존 항공편 속성과 요청된데이터로 넣음
         r = flights[j]; //업데이트된 객체 할당
      }
    });
      if (r) {
      return res.json(r);
     } else { //아니면 에러
      return res.status(404);
    }
  }}</code></pre><h3 id="bookcontrollerjs">bookController.js</h3>
<pre><code>// POST /book에서 사용할 uuid입니다.
const { v4: uuid } = require(&#39;uuid&#39;);
// 항공편 예약 데이터를 저장합니다.
let booking = [];

module.exports = {
  // [GET] /book 요청을 수행합니다.
  // 전체 예약 데이터를 조회합니다.
  findAll: (req, res) =&gt; {
    return res.status(200).json(booking);
  },
  // [GET] /book/:phone 요청을 수행합니다.
  // 요청 된 phone과 동일한 phone 예약 데이터를 조회합니다.
  findByPhone: (req, res) =&gt; {
    const {phone} = req.params;
    const r = booking.filter(book =&gt; book.phone === phone); //todo??
    return res.json(r);
  },
  // [GET] /book/:phone/:flight_uuid 요청을 수행합니다.
  // 요청 된 id, phone과 동일한 uuid, phone 예약 데이터를 조회합니다.
  findByPhoneAndFlightId: (req,res) =&gt; {
    const {phone, flight_uuid} = req.params;
    // TODO:
    const r = booking.filter(i =&gt; i.phone === phone &amp;&amp; i.flight_uuid === flight_uuid); //:flight_uuid 요청
    return res.json(r);
  },
  // [POST] /book 요청을 수행합니다.
  // 요청 된 예약 데이터를 저장합니다.
  create: (req, res) =&gt; {
    // POST /book에서 사용할 booking_uuid입니다.
    const booking_uuid = uuid();
    // TODO:
    const r = {booking_uuid, ...req.body}; //예약 객체 생성 후 예약데이터랑, 요청 바디 속성 복사함
    booking.push(r);
    return res.json(r);
  },
  // Optional
  // [DELETE] /book/:booking_uuid 요청을 수행합니다.
  // 요청 된 id, phone 값과 동일한 예약 데이터를 삭제합니다.
  deleteByBookingId: (req, res) =&gt; {
    const {booking_uuid} = req.params;
    // TODO:
    const r = booking.filter((booking) =&gt; booking.phone === phone);
    return res.json(r);
}
};</code></pre><p>어려운부분은 없었다. 또 종합퀴즈가 틀려서 문제다 ㅠㅠ</p>
<pre><code>다음 Express 서버 코드에 대한 설명 중 옳지 않은 것을 고르세요.

const express = require(&#39;express&#39;)
const app = express()
const port = 3000

const logger1 = (req, res, next) =&gt; {
  console.log(&quot;logger1&quot;);
  next();
}

const logger2 = (req, res, next) =&gt; {
  console.log(&quot;logger2&quot;);
  next();
}

const codestates = (req, res) =&gt; {
  res.send(&#39;Hello CodeStates!&#39;);
}

app.get(&#39;/&#39;, (req, res) =&gt; {
  res.send(&#39;Hello World!&#39;)
})

app.use(logger1, logger2);

app.get(&#39;/codestates&#39;, codestates);

app.listen(port, () =&gt; {
  console.log(`Example app listening on port ${port}`)
})

A.
GET /요청을 서버에 보내면 &#39;Hello World!&#39;가 응답으로 온다.


B.
GET /codestates요청을 서버에 보내면 &#39;Hello CodeStates!&#39;가 응답으로 온다.


C.
GET /요청을 서버에 보내면 &quot;logger1&quot;, &quot;logger2&quot;가 콘솔에 출력된다.


D.
GET /codestates요청을 서버에 보내면 &quot;logger1&quot;, &quot;logger2&quot;가 콘솔에 출력된다.


E.
logger1, logger2는 미들웨어(middleware)다.
</code></pre><p><strong>해설</strong>
app.use(logger1, logger2) 코드가 app.get(&#39;/&#39;, //생략) 보다 밑에 있기 때문에 미들웨어 적용이 되어있지 않습니다.
따라서 GET /요청을 서버에 보내면 &quot;logger1&quot;, &quot;logger2&quot;가 콘솔에 출력되지 않습니다.
반면에, app.get(&#39;/codestates&#39;, codestates) 코드는 app.use(logger1, logger2)보다 아래에 있기 때문에 미들웨어 적용이 됩니다.
따라서 GET /codestates요청을 서버에 보내면 &quot;logger1&quot;, &quot;logger2&quot;가 콘솔에 출력됩니다.</p>
<pre><code>
app.get(&#39;/&#39;, (req, res) =&gt; {
  res.send(&#39;Hello World!&#39;)
})

app.use(logger1, logger2);

app.get(&#39;/codestates&#39;, codestates);</code></pre><p>??미들웨어가 저런건가..?뭔말인지 대충은 알겠는데..아직 헷갈리는 느낌이 든다.
항상 이렇다. 프로그래머스나 과제는 큰어려움없이 잘 진행되는데, 개념문제만 보면 헷갈린다. 내일 쉬는날에 한번 쫙 정리해야지...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Uncaught (in promise) SyntaxError: Unexpected token 'h', "hello mini"... is not valid JSON]]></title>
            <link>https://velog.io/@lsm_0084/Uncaught-in-promise-SyntaxError-Unexpected-token-h-hello-mini...-is-not-valid-JSON</link>
            <guid>https://velog.io/@lsm_0084/Uncaught-in-promise-SyntaxError-Unexpected-token-h-hello-mini...-is-not-valid-JSON</guid>
            <pubDate>Thu, 01 Jun 2023 06:04:20 GMT</pubDate>
            <description><![CDATA[<p><strong>오늘은 mini-node-server</strong>과제가 주어졌다. 영문자를 요청 시 대소문자로 변경하여 응답하는 과제다.</p>
<ul>
<li>POST에 문자열을 담아 요청을 보낼 때는 HTTP 메시지의 body(payload)를 이용합니다.</li>
<li>서버는 요청에 따른 적절한 응답을 클라이언트로 보내야 합니다.</li>
<li>CORS 관련 헤더를 OPTIONS 응답에 적용해야 합니다.</li>
<li>클라이언트의 preflight request에 대한 응답을 돌려줘야 합니다.
라는 조건이 주어졌고...<blockquote>
<pre><code>const http = require(&#39;http&#39;);
const PORT = 4999;
const ip = &#39;localhost&#39;;
const server = http.createServer((request, response) =&gt; { //서버생성
if(request.method === &#39;OPTIONS&#39;) { //사전요청 preflight request
  response.writeHead(200, defaultCorsHeader); //응답 헤더 작성 메서드(상태코드, 헤더정보 객체)
  response.end(); //응답 종료
}
if(request.method === &#39;POST&#39;){ //포스트메서드 요청시
  let body = []; //데이터 저장 빈배열
  request.on(&#39;data&#39;, (chunk) =&gt; { //데이터를 받을 때
      body.push(chunk); //배열에 추가
    }).on(&#39;end&#39;, () =&gt; { //데이터 받아오기 완료 시
      body = Buffer.concat(body).toString();  //청크를 하나의 문자열로 합치고 변환
      response.writeHead(201, defaultCorsHeader); //성공
      if(request.url === &#39;/lower&#39;){ 
        response.end(body.toLowerCase()); //응답종료(소문자로 변환)
      }else if(request.url === &#39;/upper&#39;){  
        response.end(body.toUpperCase()); //응답종료(대문자로 변환)
      }else{
        response.writeHead(404, defaultCorsHeader); //나머지 실패
        response.end();
      }
    });
}
});
server.listen(PORT, ip, () =&gt; {
console.log(`http server listen on ${ip}:${PORT}`);
});
const defaultCorsHeader = {
&#39;Access-Control-Allow-Origin&#39;: &#39;*&#39;,
&#39;Access-Control-Allow-Methods&#39;: &#39;GET, POST, PUT, DELETE, OPTIONS&#39;,
&#39;Access-Control-Allow-Headers&#39;: &#39;Content-Type, Accept&#39;,
&#39;Access-Control-Max-Age&#39;: 10
};</code></pre></blockquote>
<pre><code></code></pre>공식문서와 1시간정도 싸운결과 큰 어려움없이(?) 풀렸는데....</li>
<li>Uncaught (in promise) SyntaxError: Unexpected token &#39;h&#39;, &quot;hello mini&quot;... is not valid JSON</li>
</ul>
<p>이런 오류가 뜨는것이다....json형식..?응답형식이 잘못됐나 싶어서</p>
<ul>
<li>response.end(JSON.stringify(responseBody))</li>
</ul>
<p>이렇게 바꿔보고....APP.js로 가서 건드려보고...1시간반동안 오류해결만 찾아다녔다.
그렇게 알게된것....맨처음에 서버를 실행하고 변경사항이 있을때마다 저장 &gt; 종료 &gt; 재실행을 해야했다. 이 불편함을 없애기 위해 <strong>npm install nodemon</strong> 을 설치했는데.......
설치하고 기존서버를 닫고 nodemon으로 재실행해야 하는거였다.....package.json의 &quot;scripts&quot;에 실행코드를 쓰거나 npx nodemon server/basic-server.js로 실행하면 된다....</p>
<p>정말 어이없는 짓을 1시간반동안 했다...나는 뭘한거지..나같은 바보가 없길 바라면서 안잊을려고 글 쓴다ㅠㅠ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Effect Hook]]></title>
            <link>https://velog.io/@lsm_0084/Effect-Hook</link>
            <guid>https://velog.io/@lsm_0084/Effect-Hook</guid>
            <pubDate>Wed, 31 May 2023 03:59:20 GMT</pubDate>
            <description><![CDATA[<h3 id="side-effect-부수-효과">Side Effect (부수 효과)</h3>
<blockquote>
<p>함수나 프로그램이 실행될 때, 함수 외부의 상태를 변경하거나 다른 외부 동작을 수행하는 것</p>
</blockquote>
<h3 id="pure-function-순수-함수">Pure Function (순수 함수)</h3>
<blockquote>
<p>동일한 입력에 대해 항상 동일한 출력을 반환하며, 외부 상태를 변경하지 않는 함수</p>
</blockquote>
<p>개념학습에 이런 질문이 있다.</p>
<ul>
<li>Math.random()은 순수 함수가 아닙니다. 왜일까요?<blockquote>
<p>동일한 입력에 대해 항상 동일한 출력을 반환하지 않는다: Math.random()은 매번 호출될 때마다 난수(예측할 수 없는, 무작위 수)를 반환한다.</p>
</blockquote>
</li>
</ul>
<ul>
<li>어떤 함수가 fetch API를 이용해 AJAX 요청을 한다고 가정해 봅시다. 이 함수는 순수 함수가 아닙니다. 왜일까요?<blockquote>
<p>동일한 입력에 대해 항상 동일한 출력을 반환하지 않는다: AJAX 요청은 외부 서버로부터 데이터를 비동기적으로 받아오기 때문에 요청마다 다른 결과가 반환된다. </p>
</blockquote>
</li>
</ul>
<h3 id="effect-hook">Effect Hook</h3>
<blockquote>
<p>useEffect는 컴포넌트 내에서 Side effect를 실행할 수 있게 하는 Hook.</p>
</blockquote>
<ul>
<li>useEffect의 첫 번째 인자는 함수. 해당 함수 내에서 side effect를 실행.</li>
</ul>
<p><strong>언제 실행?</strong></p>
<ol>
<li>컴포넌트 생성 후 처음 화면에 렌더링(표시)</li>
<li>컴포넌트에 새로운 props가 전달되며 렌더링</li>
<li>컴포넌트에 상태(state)가 바뀌며 렌더링
매번 컴포넌트가 렌더링 될 때 Effect Hook이 실행.</li>
</ol>
<p><strong>주의</strong>
최상위에서만 Hook을 호출.</p>
<ul>
<li>반복문, 조건문 혹은 중첩된 함수 내에서 Hook을 호출하지 말것 &gt; 컴포넌트가 렌더링 될 때마다 항상 동일한 순서로 Hook이 호출되는 것이 보장됨</li>
</ul>
<p>React 함수 내에서 Hook을 호출.</p>
<h4 id="조건부-effect-발생-dependency-array">조건부 effect 발생 (dependency array)</h4>
<blockquote>
<p>useEffect의 두 번째 인자는 조건을 담은 배열( boolean 형태의 표현식이 아닌, 어떤 값의 변경이 일어날 때). 배열을 종속성 배열이라고 함.</p>
</blockquote>
<pre><code>useEffect(() =&gt; {
  // 실행할 작업
}, [dependency1, dependency2]);</code></pre><p>종속성 배열이 빈 배열([])인 경우, useEffect는 컴포넌트가 처음으로 마운트될 때에만 실행되고, 이후에는 상태나 프로퍼티의 변경에 반응하지 않음.</p>
<h2 id="컴포넌트-내에서의-ajax-요청">컴포넌트 내에서의 Ajax 요청</h2>
<h3 id="http를-이용한-서버요청-2가지-방식의-장단점">HTTP를 이용한 서버요청 2가지 방식의 장단점</h3>
<p><img src="https://velog.velcdn.com/images/lsm_0084/post/3f24f49d-1943-4ccf-af21-38b61efdf972/image.png" alt=""></p>
<p>fetch API를 써서, 서버에 요청해보자 ~~API의 엔드포인트가 http://서버주소/proverbs라고 가정해 보자.</p>
<pre><code>useEffect(() =&gt; {
  fetch(`http://서버주소/proverbs?q=${filter}`)
    .then(resp =&gt; resp.json())
    .then(result =&gt; {
      setProverbs(result);
    });
}, [filter]);</code></pre><p>이런식으로 사용하여 비동기적으로 서버와 데이터를 주고받는다. AJAX를 사용해서 동적인 동작을 구현할 수 있고, 서버와의 데이터 통신을 더욱 유연하게 처리할 수 있다.</p>
<h3 id="로딩-화면loading-indicator">로딩 화면(loading indicator)</h3>
<p>모든 네트워크 요청이 즉각적인 응답이 되진 않는다. 외부 API접속이 느릴 경우 빈화면이 나타나는데 사용자들은 이 화면을 보고 작동이 되는건지 멈춘건지 알 수 없다. 사용자 이탈을 막기 위해서 로딩화면은 필수로 구현해야 한다.
로딩화면 작성코드는 전글에 과제풀면서 적어두었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[과제.[StatesAirline Client]]]></title>
            <link>https://velog.io/@lsm_0084/%EA%B3%BC%EC%A0%9C.StatesAirline-Client</link>
            <guid>https://velog.io/@lsm_0084/%EA%B3%BC%EC%A0%9C.StatesAirline-Client</guid>
            <pubDate>Wed, 31 May 2023 03:20:27 GMT</pubDate>
            <description><![CDATA[<h3 id="로딩-화면-제공하기">로딩 화면 제공하기</h3>
<pre><code> useEffect(() =&gt; {
    const fetchData = async () =&gt; {
      setIsLoading(true); //로딩중
      const data = await getFlight(condition);
      setFlightList(data); // getFlight결과 &gt; flightList 상태로 업데이트.
      setIsLoading(false); 
    };
    fetchData();
  }, [condition]);</code></pre><p>이 코드는 useEffect hook을 사용하여 비동기로 데이터를 가져와 상태를 업데이트하는 동작을 수행한다.
(useEffect 함수는 컴포넌트가 렌더링될 때마다, condition 상태가 변경될 때마다 useEffect의 콜백 함수를 실행.)</p>
<ol>
<li><p>setIsLoading(true)를 호출하여 로딩 상태를 true로 설정 &gt; 로딩 중.</p>
</li>
<li><p>await getFlight(condition)을 호출하여 getFlight 함수를 실행 &gt; 서버 API를 호출하여 ~~데이터를 가져옴. &gt; API 호출이 완료 후 데이터가 반환 &gt; const data = await getFlight(condition)의 data 변수에 데이터가 할당.</p>
</li>
<li><p>setFlightList(data)를 호출 &gt; flightList 상태 업데이트.</p>
</li>
<li><p>setIsLoading(false)를 호출하여 로딩 상태를 false로 설정 &gt; 로딩완료.</p>
</li>
</ol>
<p>즉, useEffect hook은 컴포넌트가 마운트될 때와 condition 상태가 변경될 때마다 데이터를 가져와 상태를 업데이트하는 동작을 수행하며, 그 과정에서 로딩 상태를 관리한다.</p>
<p>const [isLoading, setIsLoading] = useState(false); (usestate초기값 false로 지정해야함!)</p>
<h1 id="종합퀴즈-다-틀렸다">종합퀴즈 다 틀렸다!!!!@<del>@!</del>@@!~</h1>
<p>그래서 정리함..</p>
<h3 id="react-데이터-흐름">React 데이터 흐름</h3>
<p>React에서의 데이터 흐름은 일반적으로 단방향이며, 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달한다. 이를 상위 컴포넌트에서 하위 컴포넌트로의 props 전달이라고 하고 데이터 흐름이 하향식임을 의미한다.</p>
<p>입력에 따라 변하는 값을 상태(state)라고 한다.</p>
<blockquote>
<p>상태 판단 방법</p>
</blockquote>
<ul>
<li>부모로부터 props를 통해 전달되는가? </li>
<li>시간이 지나도 변하지 않는가? </li>
<li>컴포넌트 안의 다른 state나 props를 가지고 계산 가능한가?</li>
</ul>
<p>만약 하나의 상태를 기반으로 여러 컴포넌트가 영향을 받는다면 상태를 어디에 위치시켜야할까?
이때는 공통 소유 컴포넌트 &gt; 즉, 공통 부모 컴포넌트에 상태를 위치해야한다.</p>
<p>근데 또 정하고보니 부모 컴포넌트의 상태가 하위 컴포넌트에 의해 변하는 경우가 있다.
하위 컴포넌트 이벤트가, 부모의 상태를 바꾸어야만 하는 상황이 있을때의 해결 방법이 바로 <strong>State 끌어올리기(Lifting state up)</strong>다.</p>
<h3 id="state-끌어올리기lifting-state-up">State 끌어올리기(Lifting state up)</h3>
<p>콜백함수와 비슷하다. 상태를 변경시키는 함수(handler)를 하위 컴포넌트에 props로 전달해서 해결할 수 있다.</p>
<p><strong>구현방법</strong></p>
<ol>
<li><p>공유할 상태를 결정 &gt; 해당 상태를 상위 컴포넌트에 생성. 이 상태는 하위 컴포넌트들이 사용할 수 있도록 props로 전달됨.</p>
</li>
<li><p>하위 컴포넌트에서 상태를 읽거나 변경해야 할 때, 상위 컴포넌트에서 전달받은 콜백 함수를 호출하여 상태를 업데이트.</p>
</li>
<li><p>상태가 업데이트되면 React가 하위 컴포넌트들에게 자동으로 새로운 상태를 전달하여 화면을 업데이트.</p>
</li>
</ol>
<p>예제도 적을까 하다가 <a href="https://ko.legacy.reactjs.org/docs/lifting-state-up.html">React공식문서</a> 정확하게 나와있는 문서가 있기도 하고...너무 길기도 하고..ㅎㅎ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ PostMan으로 POST요청 보내기
+ API, AJAX, SSR & CSR]]></title>
            <link>https://velog.io/@lsm_0084/PostMan%EC%9C%BC%EB%A1%9C-POST%EC%9A%94%EC%B2%AD-%EB%B3%B4%EB%82%B4%EA%B8%B0-API-AJAX-SSR-CSR</link>
            <guid>https://velog.io/@lsm_0084/PostMan%EC%9C%BC%EB%A1%9C-POST%EC%9A%94%EC%B2%AD-%EB%B3%B4%EB%82%B4%EA%B8%B0-API-AJAX-SSR-CSR</guid>
            <pubDate>Fri, 26 May 2023 09:59:19 GMT</pubDate>
            <description><![CDATA[<h3 id="postman">PostMan?</h3>
<blockquote>
<p>API 개발을 보다 빠르고 쉽게 구현 할 수 있도록 도와주며, 개발된 API를 테스트하여 문서화 또는 공유 할 수 있도록 도와 주는 플랫폼. 
변수 및 환경, request 설명, 테스트 및 사전 요청에 필요한 스크립트 작성 등 현재 워크 플로우를 더 효율적으로 만들 수 있도록 고안.</p>
</blockquote>
<p><a href="https://www.postman.com/">PostMan사이트주소</a></p>
<h3 id="get요청방법">GET요청방법</h3>
<ol>
<li>새로운 탭을 열고 요청/응답 확인가능.</li>
<li>HTTP 메서드 선택가능</li>
<li>URL과 Endpoint입력</li>
<li>HTTP 요청 버튼</li>
<li>HTTP 요청 시 설정할 수 있는 각종 옵션(파라미터나, body등)</li>
<li>HTTP 응답 화면
<img src="https://velog.velcdn.com/images/lsm_0084/post/26e44f04-fdd2-40dc-ac89-45bb90986ebd/image.png" alt=""></li>
</ol>
<h3 id="post요청방법">POST요청방법</h3>
<ol>
<li>본문의 형식 선택 &gt; JSON 형식 = raw선택.</li>
<li>정확한 타입을 선택 &gt; JSON 형식 = JSON선택.</li>
<li>본문 내용 &gt; 유효한 JSON을 적어야함.
{ &quot;username&quot; : &quot;이러쿵&quot;,
&quot;text&quot; : &quot;저러쿵&quot;,
&quot;date&quot; : &quot;11111&quot;
}
<img src="https://velog.velcdn.com/images/lsm_0084/post/dfe1d247-63ca-4c23-8886-307f2fb79100/image.png" alt="">
POST요청 후 다시 GET으로 조회해보면 추가된것을 확인 할  수 있다.</li>
</ol>
<h3 id="apiapplication-programming-interface">API(Application Programming Interface)</h3>
<blockquote>
<p>API는 중간에서 양쪽의 서버를 연결하는 역할을 한다.
가게 점원의 역할인 손님에게 주문을 받고 요리사한테 전달 &gt; 요리사에게 받은 음식을 손님에게 전달과 같다.</p>
</blockquote>
<h3 id="ajaxasynchronous-javascript-and-xmlhttprequest">AJAX(Asynchronous JavaScript And XMLHttpRequest)</h3>
<blockquote>
<p>웹 페이지에서 필요한 데이터만 비동기적으로 받아와 유저의 요구에 따라 변화해야 하는 부분만 렌더링한다.
대표적으로 JavaScript, DOM, Fetch가 있다.</p>
</blockquote>
<ul>
<li>Fetch</li>
</ul>
<ol>
<li>XHR의 단점을 보완한 새로운 Web API로 가볍고 편하며 promise를 지원하고 javascript와 호환되는 JSON을 사용.</li>
<li>페이지 이동 없이 서버로부터 필요한 데이터를 받아온다.</li>
<li>브라우저는 Fetch가 서버에 요청을 보내고 응답을 받을 때까지 멈추지 않고 다른 동작들을 비동기적으로 수행.</li>
</ol>
<h3 id="ssrserver-side-rendering--csrclient-side-rendering">SSR(Server Side Rendering) &amp; CSR(Client Side Rendering)</h3>
<blockquote>
<ul>
<li>SSR
브라우저가 서버의 URI로 GET 요청 &gt; 웹페이지를 브라우저로 보내기 전에 서버에서 렌더링 &gt; 데이터베이스의 데이터를 불러와 렌더링 된 페이지로 변환 후에 브라우저에 응답.
사용자가 브라우저의 다른 경로로 이동할 때마다 서버는 이 작업을 반복.</li>
</ul>
</blockquote>
<ul>
<li>CSR
브라우저가 서버의 URI로 GET 요청 &gt; 웹 페이지의 단일 페이지, JS를 클라이언트에게 보냄 &gt; 데이터베이스에 저장된 데이터를 가져와서 웹 페이지에 렌더링.
사용자가 브라우저의 다른 경로로 이동해도 웹 페이지를 다시 보내지 않음.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[REST API]]></title>
            <link>https://velog.io/@lsm_0084/REST-API</link>
            <guid>https://velog.io/@lsm_0084/REST-API</guid>
            <pubDate>Thu, 25 May 2023 08:46:49 GMT</pubDate>
            <description><![CDATA[<p><strong>REST(Representational State Transfer)</strong>
웹(http)의 장점을 최대한 활용할 수 있는 아키텍처.</p>
<h3 id="rest-api">REST API</h3>
<blockquote>
<p>웹에서 사용되는 데이터나 자원(Resource)을 HTTP URI로 표현하고, HTTP 프로토콜을 통해 요청과 응답을 정의하는 방식.</p>
</blockquote>
<ul>
<li>HTTP 프로토콜을 기반으로 요청과 응답에 따라 리소스를 주고받기 위해서는 알아보기 쉽고 잘 작성된 메뉴판이 필요 </li>
</ul>
<h3 id="rest-api를-디자인하는-방법">REST API를 디자인하는 방법</h3>
<blockquote>
<p>REST API를 작성할 때는 지켜야 할 규칙들이 있다 =&gt; 4단계 성숙도 모델(0~3단계)</p>
</blockquote>
<ul>
<li>하지만 엄밀하게 3단계까지 지키는건 어렵기 때문에 2단계까지만 적용해도 좋은 API 디자인이라고 볼 수 있다. =&gt; HTTP API
<img src="https://velog.velcdn.com/images/lsm_0084/post/5688aee6-4e43-4d71-80c7-6daa351996dd/image.png" alt=""></li>
</ul>
<ul>
<li><h4 id="rest-성숙도-모델---0단계">REST 성숙도 모델 - 0단계</h4>
<ul>
<li>0단계는 REST API를 작성하기 위한 기본 단계다. 단순히 <strong>HTTP 프로토콜을 사용</strong>하기만 해도 된다. 하지만 이 경우의 API를 REST API라고 하진않는다.</li>
</ul>
</li>
<li><h4 id="rest-성숙도-모델---1단계">REST 성숙도 모델 - 1단계</h4>
<ul>
<li><p>1단계에서는 <strong>개별 리소스(Resource)와의 통신을 준수</strong>해야 한다.</p>
</li>
<li><p>모든 자원은 개별 리소스에 맞는 엔드포인트(Endpoint)를 사용해야 하며 요청하고 받는 자원에 대한 정보를 응답으로 전달해야 한다. =&gt; 어떤 리소스를 변화시키는지, 어떤 응답이 제공되는지에 따라 각기 다른 엔드포인트를 사용하기 때문에, <strong>적절한 엔드포인트</strong>를 작성하는 것이 중요! </p>
</li>
<li><p>엔드포인트 작성 시 <strong>동사, HTTP 메서드, 혹은 어떤 행위에 대한 단어 사용은 지양</strong> =&gt; 명사 형태의 단어로 작성하는 것이 좋음.
요청에 따른 응답으로 리소스를 전달 =&gt; 사용한 리소스에 대한 정보, 성공/실패 여부를 반환</p>
</li>
</ul>
</li>
<li><h4 id="rest-성숙도-모델---2단계">REST 성숙도 모델 - 2단계</h4>
<ul>
<li>2단계에서는 CRUD(Create, Read, Update, Delete)에 맞게 HTTP메서드를 사용해야 함.<ul>
<li>주의사항
-<strong>GET</strong> 메서드 = 서버의 데이터를 변화시키지 않는 요청에 사용</li>
</ul>
</li>
<li><strong>POST</strong>메서드 = 매 요청모다 새로운 리소스를 반환하는데, 매 요청마다 같은 리소스를 반환하는 PUT과 구분해서 사용.</li>
</ul>
</li>
<li><p><strong>PUT</strong>은 교체, <strong>PATCH</strong>는 수정의 용도로 사용.</p>
<h3 id="open-api">Open API</h3>
<blockquote>
<p>누구에게나 열려있는 API. 
무제한으로 이용? x =&gt;  API마다 정해진 이용 수칙이 있고, 그 이용 수칙에 따라 제한사항(가격, 정보의 제한 등)이 있을 수 있음.
<a href="https://openweathermap.org/api">날씨 제공 API</a></p>
</blockquote>
</li>
</ul>
<h3 id="api-key">API Key</h3>
<blockquote>
<p>API를 이용하기 위해서는 API Key가 필요.(API key는 서버의 문을 여는 열쇠) 
서버를 운용하는 데에 비용이 발생 =&gt; 서버 입장에서 아무런 조건 없이 익명의 클라이언트에게 데이터를 제공할 의무 x.(API key가 필요하지 않은 경우도 있음.)</p>
</blockquote>
<ul>
<li>API Key가 필요한 경우 
이용자에게 자원에 접근할 수 있는 권한을 API Key의 형태로 제공
데이터를 요청할 때 API key를 같이 전달 =&gt; 원하는 응답</li>
</ul>
<p>이번 개념의 경우 쉬웠던거 같지만 내일 하는 실습을 해봐야 제대로 알거같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTTP 네트워크 기초]]></title>
            <link>https://velog.io/@lsm_0084/HTTP-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88</link>
            <guid>https://velog.io/@lsm_0084/HTTP-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88</guid>
            <pubDate>Wed, 24 May 2023 09:24:24 GMT</pubDate>
            <description><![CDATA[<p>어려울 수 있다고 들은 http. 양이 겁나 많은게 보인다.</p>
<h3 id="urluniform-resource-locator">URL(Uniform Resource Locator)</h3>
<p>네트워크 상에서 웹 페이지, 이미지, 동영상 등의 파일이 위치한 정보를 나타냄
. URL은 scheme, hosts, url-path로 구분. </p>
<h3 id="uriuniform-resource-identifier">URI(Uniform Resource Identifier)</h3>
<p>URL의 기본 요소인 scheme, hosts, url-path에 더해 query, fragment를 포함. </p>
<p>브라우저의 검색창을 클릭하면 나타나는 주소가 URI. URI는 URL을 포함하는 상위개념.
<img src="https://velog.velcdn.com/images/lsm_0084/post/b31fc495-a3d4-4957-b90c-40f5e0ba0af0/image.png" alt=""></p>
<h3 id="ipnternet-protocol">IP(nternet Protocol)</h3>
<p>인터넷상에서 사용하는 주소체계. 네 덩이의 숫자로 구분된 IP 주소체계를 IPv4(Internet Protocol version 4) &gt; IP 주소체계의 네 번째 버전.</p>
<ul>
<li>IPv4는 각 덩어리마다 0부터 255까지 나타낼 수 있다. 따라서 2^(32)인 약 43억 개의 IP 주소를 표현. </li>
<li>IPv4로 할당할 수 있는 PC가 한계를 넘어가면서 <strong>IPv6(IP version 6)</strong>가 나옴. IPv6는 표기법을 달리 책정하여 2^(128)개의 IP 주소를 표현.
(localhost, 127.0.0.1 : 현재 사용 중인 로컬 PC를 지칭.)</li>
</ul>
<h3 id="port">PORT</h3>
<p>IP 주소가 가리키는 PC에 접속할 수 있는 통로(채널)
(<a href="http://localhost:3001">http://localhost:3001</a> &lt; :3001이 port)</p>
<ul>
<li>포트 번호는 0~ 65535까지 사용가능. 그중에서 0 ~ 1024번까지의 포트 번호는 주요 통신을 위한 규약에 따라 이미 정해져 있음.</li>
<li>반드시 알아야 할 잘 알려진 포트 번호 
22 : SSH
80 : HTTP
443: HTTPS</li>
</ul>
<h3 id="domain-name">Domain name</h3>
<p>웹 브라우저를 통해 특정 사이트에 진입을 할 때, IP 주소를 대신하여 사용하는 주소가 있다. 만약 IP 주소가 지번 또는 도로명 주소라면, 도메인 이름은 해당 주소에 위치한 상호로 볼 수 있다.</p>
<h3 id="dns">DNS</h3>
<p>호스트의 도메인 이름을 IP 주소로 변환하거나 반대의 경우를 수행할 수 있도록 개발된 데이터베이스 시스템</p>
<h3 id="크롬-브라우저-에러-읽기">크롬 브라우저 에러 읽기</h3>
<p><img src="https://velog.velcdn.com/images/lsm_0084/post/c0a62d5e-6452-4761-8db7-bde372d7bd45/image.png" alt=""></p>
<h3 id="httphypertext-transfer-protocol">HTTP(HyperText Transfer Protocol)</h3>
<p>HTML과 같은 문서를 전송하기 위한 프로토콜. HTTP는 웹 브라우저와 웹 서버의 소통을 위해 디자인</p>
<ul>
<li>HTTP Messages<blockquote>
<p>클라이언트와 서버 사이에서 데이터가 교환되는 방식. </p>
</blockquote>
</li>
</ul>
<ul>
<li>HTTP Requests<blockquote>
<p>클라이언트가 서버에게 보내는 메시지</p>
</blockquote>
</li>
</ul>
<ul>
<li>HTTP Responses<blockquote>
<p>서버가 클라이언트에게 보내는 메시지</p>
</blockquote>
</li>
</ul>
<p>개념이 더 있고 한참 남았지만 뭐라는지 모르겠어서 정리를 못하겠다...이상해..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[(야자)[React] React State & Props과제]]></title>
            <link>https://velog.io/@lsm_0084/%EC%95%BC%EC%9E%90React-React-State-Props%EA%B3%BC%EC%A0%9C</link>
            <guid>https://velog.io/@lsm_0084/%EC%95%BC%EC%9E%90React-React-State-Props%EA%B3%BC%EC%A0%9C</guid>
            <pubDate>Tue, 23 May 2023 10:05:15 GMT</pubDate>
            <description><![CDATA[<p>오늘은....종합퀴즈 9문제중 3개나 틀려버려서 야자반에 걸렸다....
분명 다 풀 수 있는데 아침에 몽롱한 상태에서 뇌빼고 푼거같다.ㅠㅠ</p>
<p><strong>⭐️ 야간 자율 학습 과제</strong>
[필수] - React Twittler State &amp; Props 과제 레퍼런스의 의사코드를 작성하여 블로깅 하세요.</p>
<h3 id="tweets">Tweets</h3>
<pre><code>const Tweets = () =&gt; { 
  const [tweets, setTweets] = useState(dummyTweets);
  const [username, setUsername] = useState(&#39;&#39;);
  const [message, setMessage] = useState(&#39;&#39;);

   //트윗 작성 함수

  const handleButtonClick = (event) =&gt; {
    if (username &amp;&amp; message) { //값이 있는 경우
      const newTweet = {       //새로운 트윗 객체 생성
        id: tweets.length + 1, //새로운 고유 아이디
        username: username,
        picture: &#39;https://randomuser.me/api/portraits/men/98.jpg&#39;,
        content: message,
        createdAt: new Date().toISOString(),   //yyyy.mm.dd로 반영
        updatedAt: new Date().toISOString(),
      }; 

      setTweets([newTweet, ...tweets]); //기존 트윗에 추가

      setUsername(&#39;&#39;);   //입력값 초기화
      setMessage(&#39;&#39;);
    }
  };
   //트윗 삭제
  const handleDelete = (tweetId) =&gt; {
    const updatedTweets = tweets.filter((tweet) =&gt; tweet.id !== tweetId); 
    //삭제할 트윗을 제외

    setTweets(updatedTweets);
  };
  //유저네임 입력
  const handleChangeUser = (event) =&gt; {
    setUsername(event.target.value);
  };
  //메세지 입력
  const handleChangeMsg = (event) =&gt; {
    setMessage(event.target.value);
  };</code></pre><h3 id="tweet">Tweet</h3>
<pre><code>const Tweet = ({ tweet, onDelete }) =&gt; { //컴포넌트 정의
  const parsedDate = new Date(tweet.createdAt).toLocaleDateString(&#39;ko-kr&#39;);

   // 트윗 삭제 핸들러 함수
  const handleDelete = () =&gt; {
    onDelete(tweet.id);  // onDelete 콜백 함수 호출 &gt; 트윗 ID 전달 &gt; 삭제 요청
  };
</code></pre><p>나머지는 저번시간에 했던 부분이기에 제외, 종합퀴즈 3문제...</p>
<pre><code>import React, { useState } from &quot;react&quot;;

function App() {
  const [showPopup, setShowPopup] = useState(false);

  const togglePopup = () =&gt; {
    // Pop up 의 open/close 상태에 따라
    // 현재 state 가 업데이트 되도록 함수를 완성하세요.
    if(1._______ === false) { //갱신변수가 아닌 저장변수인 showPopup의 상태가 바껴야 한다.
      2._______ (true) //이제 sethowSPopup변수를 호출해서 갱신.
    } else {
      2._______ (false)
    }
  };

  return (
    &lt;div className=&quot;App&quot;&gt;
      &lt;h1&gt;Fix me to open Pop Up&lt;/h1&gt;
      {/* 버튼을 클릭했을 때 Pop up 의 open/close 가 작동하도록
          button tag를 완성하세요. */}
      &lt;button className=&quot;open&quot; 3._______ &gt;Open me&lt;/button&gt;
      //버튼에 있는 onClick={togglePopup}함수를 넣어야 함.
      {showPopup ? (
        &lt;div className=&quot;popup&quot;&gt;
          &lt;div className=&quot;popup_inner&quot;&gt;
            &lt;h2&gt;Success!&lt;/h2&gt;
            &lt;button className=&quot;close&quot; onClick={togglePopup}&gt;
              Close me
            &lt;/button&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      ) : null}
    &lt;/div&gt;
  );
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[React SPA]]></title>
            <link>https://velog.io/@lsm_0084/React-SPA</link>
            <guid>https://velog.io/@lsm_0084/React-SPA</guid>
            <pubDate>Fri, 19 May 2023 02:28:52 GMT</pubDate>
            <description><![CDATA[<h3 id="create-react-app">Create React App</h3>
<blockquote>
<p>리액트SPA를 쉽고 빠르게 개발할 수 있도록 만들어진 툴 체인.
명령어 &gt; npx create-react-app@latest 폴더이름</p>
</blockquote>
<h1 id="react-spasingle-page-aplication">React SPA(Single Page Aplication)</h1>
<blockquote>
<p>서버로부터 필요한 데이터만 받아 업데이트함으로써 사용자와 소통하는 웹 페이지</p>
</blockquote>
<h2 id="장점">장점</h2>
<ul>
<li>전체가 아닌 필요한 부분의 데이터를 받아오기에 사용자와 interation에 빠르게 반응</li>
<li>서버 과부하 줄어듦</li>
<li>전체 페이지 렌더링 x &gt; 더 나은 유저경험 제공</li>
</ul>
<p>(SPA방식으로 만든 서비스 &gt; youtube, facebook, Gmail, airbnb, Netflix 등)</p>
<h2 id="단점">단점</h2>
<ul>
<li>html은 거의 비어있고 대부분의 코드는 js파일에 있음 &gt; 무거워짐 &gt; 첫로딩 느림</li>
<li>html이 거의 비어있기에 검색엔진의 자료수집 힘듦 &gt; 검색엔진 최적화가 안좋음</li>
</ul>
<h1 id="react-router">React Router</h1>
<h3 id="routing">Routing</h3>
<blockquote>
<p> 다른 주소에 따라 다른 뷰를 보여주는 과정을 &quot;경로에 따라 변경한다.&quot;라는 의미로 라우팅(Routing)</p>
</blockquote>
<h2 id="주요-컴포넌트">주요 컴포넌트</h2>
<ul>
<li>라우터 역할을 하는 <strong>BrowserRouter</strong></li>
<li>경로를 매칭해주는 Routes 와 *<em>Route *</em></li>
<li>경로를 변경하는 역할을 하는 <strong>Link</strong></li>
</ul>
<h4 id="browserrouter">BrowserRouter</h4>
<blockquote>
<ul>
<li>웹 애플리케이션에서 HTML5의 History API를 사용해 페이지를 새로고침하지 않고도 주소를 변경할 수 있게 해준다.</li>
<li>상위에 작성되어 있어야 React Router의 컴포넌트들을 사용할 수 있다.</li>
</ul>
</blockquote>
<h4 id="routes-route">Routes, Route</h4>
<blockquote>
</blockquote>
<ul>
<li>Routes 컴포넌트는 여러 Route 컴포넌트를 감싸서 그중 경로가 일치하는 단 하나의 라우터만 렌더링을 시켜주는 역할. </li>
<li>Routes 를 사용하지 않으면 매칭되는 모든 요소를 렌더링.</li>
<li>Route 컴포넌트는 path 속성을 지정하여 해당 path 에서 어떤 컴포넌트를 보여줄지 정함. </li>
<li>Link 컴포넌트가 정해주는 URL 경로와 일치하는 경우에만 작동.</li>
</ul>
<h4 id="link">Link</h4>
<blockquote>
<p> 페이지 전환을 통해 페이지를 새로 불러오지 않고 애플리케이션을 그대로 유지하여 HTML5 History API를 이용해 페이지의 주소만 변경</p>
</blockquote>
<p>이 컴포넌트들을 사용하기 위해서는 React Router 라이브러리에서 따로 불러와야 한다.</p>
<pre><code>import { BrowserRouter, Routes, Route } from &#39;react-router-dom&#39;;</code></pre><h4 id="import는-필요한-모듈을-불러오는-역할로-비구조화-할당destructuring-assignment과-비슷하게-이용할-수-있다">Import는 필요한 모듈을 불러오는 역할로 비구조화 할당(destructuring assignment)과 비슷하게 이용할 수 있다.</h4>
<p>아직까진 재밌고? 할만한거같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[computeSquareRoot]]></title>
            <link>https://velog.io/@lsm_0084/computeSquareRoot</link>
            <guid>https://velog.io/@lsm_0084/computeSquareRoot</guid>
            <pubDate>Thu, 18 May 2023 08:21:42 GMT</pubDate>
            <description><![CDATA[<p>문제가 뭔가 마음에 들어서 그냥 적어둔다. 쉬웠지만 그냥 뭔가 재미있어서 갑자기 올린다.</p>
<h3 id="문제">문제</h3>
<p>수를 입력받아 제곱근 값을 소수점 두 자리까지 리턴해야 합니다.</p>
<h3 id="입력">입력</h3>
<p>인자 1 : num
number 타입의 정수 (num &gt;= 2)</p>
<h3 id="출력">출력</h3>
<p> number 타입을 리턴해야 합니다.
최대 소수점 둘째 짜리까지 구합니다. (소수점 셋째 자리에서 반올림)</p>
<h3 id="주의-사항">주의 사항</h3>
<p>Math.sqrt 사용은 금지됩니다.</p>
<h3 id="입출력-예시">입출력 예시</h3>
<pre><code>let output = computeSquareRoot(9);
console.log(output); // --&gt; 3

output = computeSquareRoot(6);
console.log(output); // --&gt; 2.45</code></pre><h1 id="내가-푼-코드">내가 푼 코드</h1>
<pre><code>function computeSquareRoot(num) {
  let r = 0; 
  while( r*r &lt; num) { //r의 제곱이 num이 될때
    r += 0.001;       //근사값을 찾기 위해 0.001을 더했음
    }
  return Number(r.toFixed(2));   //number타입으로 바꾸고 소수점 2번째까지 자름
}</code></pre><h1 id="레퍼런스-코드">레퍼런스 코드</h1>
<pre><code>function computeSquareRoot(num) {
  const diffs = [1, 0.1, 0.01, 0.001];
  let base = 1;
  for (let i = 0; i &lt; diffs.length; i++) {
    while (base * base &lt; num) {
      base = base + diffs[i];
    }

    if (base * base === num) {
      return base;
    } else {
      base = base - diffs[i];
    }
  }
  return Number(base.toFixed(2));
}
</code></pre><p>뭐가 많길래 순간 당황했지만 비슷하게 푼거같다. 근데 diff배열에 0.01, 0.001은 그렇다치고
1, 0.1은 왜 넣은건지 모르겠다. 저걸 넣을 케이스가 나오는건가?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React-intro]]></title>
            <link>https://velog.io/@lsm_0084/React-intro</link>
            <guid>https://velog.io/@lsm_0084/React-intro</guid>
            <pubDate>Thu, 18 May 2023 08:08:41 GMT</pubDate>
            <description><![CDATA[<p>오늘은 어디서든 한번쯤 꼭 들어봤을법한 리액트를 배웠다. 그동안 배운 html, css, js가 리액트를 쓰기 위해서였다고.....</p>
<h1 id="리액트">리액트</h1>
<blockquote>
<p>javascript 오픈소스 라이브러리</p>
</blockquote>
<h3 id="리액트를-배워야-하는-이유">리액트를 배워야 하는 이유?</h3>
<blockquote>
<p>리액트의 특징때문에 프로트엔트 개발을 더 효율적이고 효과적으로 할 수 있기때문.</p>
</blockquote>
<h3 id="리액트의-특징">리액트의 특징?</h3>
<p>3가지의 특징이 있다.</p>
<ul>
<li>선언형</li>
<li>컴포넌트기반</li>
<li>범용성</li>
</ul>
<h4 id="선언형declarative">선언형(Declarative)</h4>
<blockquote>
<p>한 페이지를 보여주기 위해 html, css, js를 나눠서 적는게 아닌 하나의 파일에 명시적으로 작성할 수 있게 <strong>jsx를</strong> 활용한 *<em>선언형 *</em>프로그래밍을 지향.</p>
</blockquote>
<h4 id="컴포넌트-기반component-based">컴포넌트 기반(Component-Based)</h4>
<blockquote>
<p>리액트는 하나의 기능 구현을 위해 여러종류의 코드를 묶어둔 <strong>컴포넌트</strong> 기반 개발.
컴포넌트로 분리 &gt; 서로 독립적, 재사용 가능 = 기능 자체에 집중 개발.
에러 &gt; 유지보수, 유닛테스트 편함</p>
</blockquote>
<h4 id="범용성learn-once-write-anywhere">범용성(Learn Once, Write Anywhere)</h4>
<blockquote>
<p>js프로젝트 어디서든 유연하게 적용 가능.
facebook에서 관리 &gt; 안정적, 리액트 네이티브 = 모바일 개발 가능.</p>
</blockquote>
<h2 id="jsx">JSX</h2>
<blockquote>
<p>React에서 UI를 구성할 때 사용하는 문법으로 <strong>JavaScript를 확장한 문법</strong>
JSX는 브라우저가 바로 실행할 수 있는 JavaScript 코드가 아니기때문에 JavaScript 코드로 변환을 해주어야 한다.
이때 이용하는 것이 <strong>Babel</strong>. Babel은 JSX를 브라우저가 이해할 수 있는 JavaScript로 컴파일.  이후, JavaScript를 브라우저가 읽고 화면에 렌더링할 수 있다.</p>
</blockquote>
<h3 id="왜-jsx를-써야할까">왜 JSX를 써야할까?</h3>
<ul>
<li>DOM에서 JavaScript를 사용하기 위해서는 JavaScript와 HTML을 연결하기 위한 작업이 필요하다. Inline 방식, script 태그로 외부 JavaScript 파일을 연결할 수 있다.
하지만 React에서는 JSX를 이용해서 DOM 코드보다 명시적으로 코드를 작성할 수 있다.</li>
</ul>
<ul>
<li>JSX를 쓰면 JavaScript 문법과 HTML 문법을 동시에 이용해 기능과 구조를 한눈에 확인할 수 있다. 이때 구조와 동작에 대한 코드를 한 뭉치로 적은 코드셋을 <strong>컴포넌트</strong>라고 한다.</li>
<li>JSX 없이도 React 요소를 만들 수 있지만 코드가 복잡하고, 가독성이 떨어지는 단점이 있기에 편리하고 이해하기 쉽게 JSX를 사용해야 한다.</li>
</ul>
<h3 id="jsx의-규칙필수-암기-이해x">JSX의 규칙(필수 암기. 이해x)</h3>
<blockquote>
<p>여러 엘리먼트를 작성하고자 하는 경우, 최상위에서 opening tag와 closing tag로 감싸야한다.</p>
</blockquote>
<pre><code>&lt;div&gt;                                    &lt;div&gt;
  &lt;h1&gt;안녕&lt;/h1&gt;                             &lt;div&gt;
&lt;/div&gt;                        &gt;&gt;             &lt;h1&gt;안녕&lt;/h1&gt;
&lt;div&gt;                         &gt;&gt;           &lt;/div&gt;
  &lt;h2&gt;ㅎㅇ&lt;/h2&gt;                             &lt;div&gt;
&lt;/div&gt;                                       &lt;h2&gt;ㅎㅇ&lt;/h2&gt;
                                           &lt;/div&gt;
                                         &lt;/div&gt;  </code></pre><blockquote>
<p>React에서 CSS class 속성을 지정하려면
 &quot;className&quot;으로 표기.
class로 작성하게 되면 React에서는 이를 html 클래스 속성 대신 자바스크립트 클래스로 받아들이기 때문.</p>
</blockquote>
<blockquote>
<p>js 표현식 사용 시 중괄호 사용.
미사용 시 일반 텍스트로 인식.</p>
</blockquote>
<blockquote>
<p>React 엘리먼트가 JSX로 작성되면 &quot;대문자&quot;로 시작. 소문자로 시작하게 되면 일반적인 HTML 엘리먼트로 인식. 
대문자로 작성된 JSX 컴포넌트를 <strong>사용자 정의 컴포넌트</strong>라고 부름.</p>
</blockquote>
<blockquote>
<p>조건부 렌더링은 if문이 아닌 삼항연산자 사용.</p>
</blockquote>
<blockquote>
<p>React 에서 여러 개의 HTML 엘리먼트를 표시할 때는 &quot;map()&quot; 함수 사용.
map 함수를 사용할 때는 반드시 &quot;key&quot; JSX 속성을 넣어야 함.
&quot;key&quot; JSX 속성을 넣지 않으면 리스트의 각 항목에 key를 넣어야 한다는 경고가 표시됨.</p>
</blockquote>
<p>너무 길어지기에 내일 이어서 정리해야겠다. 오늘 과제는 쉬웠지만 점점 난이도가 확 오른다는 말이 기억났기에 무서워진다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오늘부터 매일 프로그래머스 풀자]]></title>
            <link>https://velog.io/@lsm_0084/%EC%98%A4%EB%8A%98%EB%B6%80%ED%84%B0-%EB%A7%A4%EC%9D%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%92%80%EC%9E%90</link>
            <guid>https://velog.io/@lsm_0084/%EC%98%A4%EB%8A%98%EB%B6%80%ED%84%B0-%EB%A7%A4%EC%9D%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%92%80%EC%9E%90</guid>
            <pubDate>Fri, 12 May 2023 14:58:51 GMT</pubDate>
            <description><![CDATA[<p>OOP를 배우고 다음에 비동기..?도 나오면서 점점 어려워지는게 느껴진다..1~2일마다 개념정리를 확실하게 해주고, 프로그래머스로 그동안 배운 총 지식들을 다시 정리하면서 복습할겸 매일 조금씩 풀어나가자!
<img src="https://velog.velcdn.com/images/lsm_0084/post/161d9572-d7b7-406f-b194-1dc19da3c7cf/image.png" alt="">
정말 기본의 기본은 제외하고 30문제정도 풀었다. 원래 5문제정도 풀고 OOP개념정리를 거의 할려고 했지만 풀다보니 재미있어서 시간을 다 써버렸다..ㅠㅠ
오래 막히거나 다른분들 풀이에서 정말 좋은 코드를 보면 블로그에 올려서 기억해둬야겠다.</p>
<p>프로토타입은 강사님이 주신 자료가 정말정말로 도움이 많이 됐다. 천천히 집중해서 읽어보니 딱 느낌이 떠올랐다. 고차함수만 다시 돌아보면 될거같다~</p>
<p><a href="https://medium.com/@limsungmook/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%8A%94-%EC%99%9C-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85%EC%9D%84-%EC%84%A0%ED%83%9D%ED%96%88%EC%9D%84%EA%B9%8C-997f985adb42">프로토타입 개념</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로토타입]]></title>
            <link>https://velog.io/@lsm_0084/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85</link>
            <guid>https://velog.io/@lsm_0084/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85</guid>
            <pubDate>Thu, 11 May 2023 04:40:36 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>JavaScript는 프로토타입(Prototype) 기반 언어. 프로토타입은 원형 객체를 의미</strong>
모든 객체들이 메소드와 속성들을 상속 받기 위한 템플릿으로써 프로토타입 객체(prototype object)를 가진다는 의미
상위 프로토타입 객체에서 메소드, 속성을 상속받고, 또 상위 <del>,또또 상위</del> 이를 <strong>프로토타입 체인(prototype chain)</strong>이라 부르며 다른 객체에 정의된 메소드와 속성을 한 객체에서 사용할 수 있도록 하는 근간</p>
</blockquote>
<pre><code>class Human {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  sleep() {
    console.log(`${this.name}은 잠에 들었습니다`);
  }
}

let kimcoding = new Human(&#39;김코딩&#39;, 30);</code></pre><p><img src="https://velog.velcdn.com/images/lsm_0084/post/97582b4f-d5b5-4f10-bbd1-c6eaa7294037/image.png" alt="">
<img src="https://velog.velcdn.com/images/lsm_0084/post/c5c88731-93bf-4b8a-a9ee-6a4cf3dc338c/image.png" alt="">
흔히 쓰는 배열 역시 원리가 동일. 배열(arr)은 Array 클래스의 인스턴스이며, 프로토타입에는 다양한 메서드가 존재.</p>
<pre><code>__proto__</code></pre><p>를 이용하면 부모 클래스의 프로토타입, 혹은 &#39;부모의 부모 클래스&#39;의 프로토타입을 탐색할 수 있다.</p>
<pre><code>function Circle() {}
const shape = {}
const circle = new Circle()

// Set the object prototype
// DEPRECATED. 예시용일 뿐입니다. 실제 코드에서는 이렇게 하지 마세요.
shape.__proto__ = circle</code></pre><p><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">proto</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[고차함수]]></title>
            <link>https://velog.io/@lsm_0084/%EA%B3%A0%EC%B0%A8%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@lsm_0084/%EA%B3%A0%EC%B0%A8%ED%95%A8%EC%88%98</guid>
            <pubDate>Thu, 11 May 2023 03:39:06 GMT</pubDate>
            <description><![CDATA[<h3 id="특별한-대우를-받는-일급-객체first-class-citizen">특별한 대우를 받는 일급 객체(first-class citizen)</h3>
<blockquote>
<p>변수에 할당(assignment)할 수 있다.
다른 함수의 전달인자(argument)로 전달될 수 있다.
다른 함수의 결과로써 리턴될 수 있다.</p>
</blockquote>
<p>함수를 변수에 할당할 수 있기 때문에, 함수를 배열의 요소나 객체의 속성 값으로 저장할 수 있다. 함수를 데이터(string, number, boolean, array, object)처럼 다룰 수 있다.</p>
<blockquote>
<p><strong>고차 함수(higher order function)</strong>는 함수를 전달인자(argument)로 받을 수 있고, 함수를 리턴할 수 있는 함수
다른 함수(caller)의 전달인자(argument)로 전달되는 함수를 <strong>콜백 함수(callback function)</strong></p>
</blockquote>
<p>JavaScript에는 기본적으로 내장된 고차 함수가 여럿 있다.</p>
<blockquote>
<p><strong>filter</strong>
배열의 각 요소가
특정 논리(함수)에 따르면, 사실(true)일 때
따로 분류(filter).</p>
</blockquote>
<blockquote>
<p><strong>map</strong>
배열의 각 요소가
특정 논리(함수)에 의해
다른 요소로 지정(map) </p>
</blockquote>
<blockquote>
<p><strong>reduce</strong>
배열의 각 요소를
특정 방법(함수)에 따라
원하는 하나의 형태로
응축. (reduction)</p>
</blockquote>
<blockquote>
<p>복잡한 어떤 것을 압축해서 핵심만 추출한 상태로 만드 <strong>추상화</strong></p>
</blockquote>
<p>고차함수의 경우 개념이 어려운거같다. 문제 32개를 풀어보면서 어느정도 익숙해진거같지만..개념을 다시보면 이게 뭔말인지 제대로 모르겠다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[객체 지향 ( OOP )]]></title>
            <link>https://velog.io/@lsm_0084/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4</link>
            <guid>https://velog.io/@lsm_0084/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4</guid>
            <pubDate>Thu, 11 May 2023 02:28:11 GMT</pubDate>
            <description><![CDATA[<p><strong>객체 지향 프로그래밍</strong>은 하나의 모델이 되는 청사진(blueprint) &gt; class 을 만들고, 그 청사진을 바탕으로 한 인스턴스 객체(instance object) &gt; instance 를 만드는 프로그래밍 패턴.
(절차 지향 프로그래밍과는 다르게 데이터와 기능을 한 곳에 묶어서 처리. 속성과 메서드가 하나의 &quot;객체&quot;라는 개념에 포함되며, 이는 JavaScript 내장 타입인 object와는 다르게, Class라는 이름으로 부름.)</p>
<p><strong>객체를 만드는 방식</strong>은 그냥 일반적인 함수를 정의하듯 만듦. 
그냥 실행하는 것이 아니고 new 키워드를 써서 만듦. 새로운 인스턴스를 만드는 방법.
각각의 인스턴스는 클래스의 고유한 속성과 메서드를 갖게 됨.</p>
<p>일반적인 <strong>다른 함수와 구분</strong>하기 위해 클래스는 보통 대문자로 시작하며 일반명사로 만듦. 
일반적인 함수는 적절한 동사를 포함하고 소문자로 시작.</p>
<p><img src="https://velog.velcdn.com/images/lsm_0084/post/382f06e1-cfd0-4b4c-bce1-3c47e5cdf60a/image.png" alt="">
ES5는 prototype이라는 키워드를 사용해야 메서드를 정의할 수 있다. Car 클래스에 메서드를 추가하기 위해서는 <code>Car.prototype.refuel</code>과 같이 <code>prototype</code>을 이용해야 한다.</p>
<p>ES6에서는 생성자 함수와 함께 class 키워드 안쪽에 묶어서 정의한다.</p>
<p><img src="https://velog.velcdn.com/images/lsm_0084/post/b22b73e0-e4a4-494e-9c9e-ca83f233d1aa/image.png" alt="">
<img src="https://velog.velcdn.com/images/lsm_0084/post/c74bd06a-5b8f-44fe-acb0-e668cc2fb899/image.png" alt=""></p>
<p><strong>캡슐화</strong>는 외부에서 데이터(속성)와 기능(메서드)을 따로 정의하는 것이 아닌, 하나의 객체 안에 넣어서 묶는 것. 데이터(속성)와 기능(메서드)들이 느슨하게 결합.</p>
<p><strong>느슨한 결합</strong>은 코드 실행 순서에 따라 절차적으로 코드를 작성하는 것이 아니라, 코드가 상징하는 실제 모습과 닮게 코드를 모아 결합하는 것. 코드만 보고도 인스턴스 객체의 기능을 상상할 수 있게 작성하는 것이 느슨한 결합을 추구하는 코드 작성법.</p>
<p>캡슐화라는 개념은 <strong>&quot;은닉화&quot;</strong>의 특징도 포함하고 있는데, 은닉화는 내부 데이터나 내부 구현이 외부로 노출되지 않도록 만드는 것. 객체 내 메서드의 구현만 수정하고, 노출된 메서드를 사용하는 코드 흐름은 바뀌지 않도록 만들 수 있다. 절차적 코드의 경우 데이터의 형태가 바뀔 때에 코드의 흐름에 큰 영향을 미치게 되어 유지 보수가 어렵다. 그래서 더 엄격한 클래스는 속성의 직접적인 접근을 막고, 설정하는 함수(setter), 불러오는 함수(getter)를 철저하게 나눔.</p>
<h2 id="oop의-장점">OOP의 장점</h2>
<blockquote>
<p><strong>캡슐화</strong>는 코드가 복잡하지 않게 만들고, 재사용성을 높임.</p>
<p><strong>추상화</strong>는 마찬가지로 코드가 복잡하지 않게 만들고, 단순화된 사용으로 변화에 대한 영향을 최소화.</p>
<p><strong>상속</strong> 역시 불필요한 코드를 줄여 재사용성을 높임.</p>
</blockquote>
<p> <strong>다형성</strong>으로 인해 동일한 메서드에 대해 if/else if와 같은 조건문 대신 객체의 특성에 맞게 달리 작성하는 것이 가능해짐.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript Koans]]></title>
            <link>https://velog.io/@lsm_0084/JavaScript-Koans</link>
            <guid>https://velog.io/@lsm_0084/JavaScript-Koans</guid>
            <pubDate>Mon, 01 May 2023 01:14:14 GMT</pubDate>
            <description><![CDATA[<p>JavaScript Koans과제가 주어졌다.
01_Introduction.js
02_Types-part1.js
03_LetConst.js
04_Scope.js
05_ArrowFunction.js
06_Types-part2.js
07_Array.js
08_Object.js
09_SpreadSyntax.js
10_Destructuring.js
10가지 주제와 51개의 koans가 주어졌다.</p>
<p>1, 2, 3, 5, 7, 8, 9, 10번의 경우 막힘없이 풀었고,
4, 6번의 스코프, 클로저, 원시자료형과 참조자료형이 많이 헷갈렸다.</p>
<h3 id="4번">4번</h3>
<pre><code>    let age = 27;
    let name = &#39;jin&#39;;
    let height = 179;

    function outerFn() {
      let age = 24;
      name = &#39;jimin&#39;;
      let height = 178;

      function innerFn() {
        age = 26;
        let name = &#39;suga&#39;;
        return height;
      }

      innerFn();

      expect(age).to.equal(26);
      expect(name).to.equal(&#39;jimin&#39;);

      return innerFn;
    }

    const innerFn = outerFn();

    expect(age).to.equal(27);
    expect(name).to.equal(&#39;jimin&#39;);
    expect(innerFn()).to.equal(178);
  });
});</code></pre><p>innerFn()에서 age의 값은 26으로 변경됐고, name은 outerFn()에서 &#39;jimin&#39;으로 변경됐다.
innerFn()에서 name변수를 새로운값&#39;suga&#39;로 재할당했지만, 이 name은 innerFn()의 지역변수기에 전역스코프의 name과는 다른 변수다.</p>
<p>const innerFn = outerFn();을 했기에 outerFn()에서 age를 24로 초기화하고 innerFn()의 함수에서 age를 26으로 변경하였지만 outerFn에서 선언된 지역변수이기에 전역스코프에선 여전히 age변수값은 27의 값을 가진다.</p>
<p>innerFn()의 값은 return height;의 값인 178이 반환된다.</p>
<h3 id="6번">6번</h3>
<pre><code>const nums1 = [1, 2, 3];
const nums2 = [1, 2, 3];</code></pre><p>일때 nums1 === nums2의 값은 false가 된다..nums1, nums2의 동일한 데이터를 갖고있지만, heap에는 nums1, nums2 각각에 대한 주소가 담기기 때문에 둘의 주소값이 달라서 false가 나온다.</p>
<pre><code>const person = {
  son: {
    age: 9,
  },
};
const boy = person.son;
boy.age = 20;
</code></pre><p>일때
expect(person.son.age).to.equal(20);
expect(person.son === boy).to.equal(true);
expect(person.son === { age: 9 }).to.equal(false);
expect(person.son === { age: 20 }).to.equal(false);
가 된다. 여기서도 ???가 나왔다. </p>
<p>밑에 두줄이 false로 나오는 이유는, 위 문제와 같은 논리로 객체 비교 시에는 객체의 내용이 아니라 참조(주소)를 비교하기 때문이다. </p>
<p>둘 다 { age: 20 }이라는 동일한 데이터 값을 가지지만, 실제로는 다른 객체다. person.son은 { age: 20 } 객체의 주소를 가지고 있지만, { age: 20 }와 같은 내용을 가진 다른 객체가 새로 생성되어 그 객체의 주소를 사용하기 때문에 false가 반환된다.</p>
<p>왜 이렇게 힘들게....머리 아프게 이해되지않았다.
문제는 어떻게 풀어도...이걸 적용해서 코드를 적을 수 있을까 걱정이다. 뭐만하면 주소가 다르고...처음이랑 다르게 뭔가 공부를 할수록 확 어려워지는거 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[js 자료형]]></title>
            <link>https://velog.io/@lsm_0084/js-%EC%9E%90%EB%A3%8C%ED%98%95</link>
            <guid>https://velog.io/@lsm_0084/js-%EC%9E%90%EB%A3%8C%ED%98%95</guid>
            <pubDate>Sun, 30 Apr 2023 23:52:51 GMT</pubDate>
            <description><![CDATA[<p>JavaScript에서 자료형(type)이란 값(value)의 종류. 각각의 자료형은 고유한 속성과 메서드를 가지고 있다. 자료형은 크게 두 가지로 구분할 수 있는데, 바로 <strong>원시 자료형(primitive type)</strong>과 <strong>참조 자료형(reference type)</strong>.</p>
<blockquote>
<p>6개의 자료형(number, string, boolean, undefined, null, symbol)을 <strong>원시 자료형</strong>
원시 자료형이 아닌 모든 자료형은 참조 자료형입니다. 배열, 객체, 함수 등 <strong>참조 자료형</strong></p>
</blockquote>
<h1 id="원시-자료형과-참조-자료형의-특징">원시 자료형과 참조 자료형의 특징</h1>
<p><img src="https://velog.velcdn.com/images/lsm_0084/post/3fc3ef7d-b2c5-4e80-b662-219e10e47985/image.png" alt=""></p>
<h3 id="얕은-복사">얕은 복사</h3>
<blockquote>
<p>lice(), Object.assign(), spread syntax 등의 방법으로 참조 자료형을 복사하면, 중첩된 구조 중 한 단계까지만 복사</p>
</blockquote>
<h3 id="깊은-복사">깊은 복사</h3>
<blockquote>
<p>참조 자료형 내부에 중첩되어 있는 모든 참조 자료형을 복사하는 것은 깊은 복사(deep copy)</p>
</blockquote>
<ul>
<li>배열의 경우 slice() 메서드 또는 spread syntax 등의 방법으로 복사할 수 있다.</li>
<li>객체의 경우 Object.assign() 또는 spread syntax 등의 방법으로 복사할 수 있다.</li>
<li>위 방법으로 참조 자료형을 복사할 경우, 중첩된 구조 중 한 단계까지만 복사된다. (얕은 복사)</li>
<li>JavaScript 내부적으로는 중첩된 구조 전체를 복사하는 깊은 복사를 구현할 수 없다. 단, 다른 문법을 응용하여 같은 결과물을 만들 수 있다.</li>
<li>대표적인 JSON.stringify()와 JSON.parse()를 사용하는 방법이 있지만, 예외의 케이스가 존재한다. (참조 자료형 내부에 함수가 있는 경우)</li>
<li>완전한 깊은 복사를 반드시 해야 하는 경우, node.js 환경에서 외부 라이브러리인 lodash, 또는 ramda를 사용하면 된다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[js 배열]]></title>
            <link>https://velog.io/@lsm_0084/js-%EB%B0%B0%EC%97%B4</link>
            <guid>https://velog.io/@lsm_0084/js-%EB%B0%B0%EC%97%B4</guid>
            <pubDate>Tue, 25 Apr 2023 13:38:38 GMT</pubDate>
            <description><![CDATA[<h1 id="배열">배열</h1>
<blockquote>
<p>배열은 다량의 데이터를 다룰 수 있는 데이터타입.
배열의 순서는 index라고 부르고, 1이 아닌 0부터 센다.</p>
</blockquote>
<ul>
<li><p>.length = 배열의 길이</p>
</li>
<li><p>.pop() = 배열의 끝의 요소 삭제</p>
</li>
<li><p>.push() = 배열의 끝에 요소 추가</p>
</li>
<li><p>.shift() = 배열의 처음의 요소 삭제</p>
</li>
<li><p>.unshift()     = 배열의 처음에 요소 추가</p>
</li>
<li><p>Array.isArray = 배열인지 아닌지 판별</p>
</li>
<li><p>indexOf, includes = 특정 값이 배열에 포함되어 있는지 확인
(없는값 = -1) ( 없는값  = false)
외에도 엄청많은 메서드들이 있다. 그때그때 상황에 맞게 필요한걸 쓰는 능력을 기르자.</p>
</li>
</ul>
<p>이번 배열의 경우 그렇게 막히는 부분없이 문제를 푼거같다.
전부 이해해서 푼건 아니지만 할만했다....</p>
<p>내일 배우는 객체의 경우 조금 복잡한 느낌을 받았다.
막상 집중해서 해보면 이것도 할만할 수 도 있다. 화이팅..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Linux/Git] 기초]]></title>
            <link>https://velog.io/@lsm_0084/LinuxGit-%EA%B8%B0%EC%B4%88</link>
            <guid>https://velog.io/@lsm_0084/LinuxGit-%EA%B8%B0%EC%B4%88</guid>
            <pubDate>Mon, 24 Apr 2023 04:16:28 GMT</pubDate>
            <description><![CDATA[<p>우선 나는 맥북이 없어서 노트북으로 우분투를 깔아서 진행하였다.</p>
<h1 id="cli-gui">CLI, GUI</h1>
<p><strong>CLI</strong>
(Command Line Interface)
명령어를 이용하여 컴퓨터를 제어</p>
<p><strong>GUI</strong>
(Graphical User Interface)
그래피컬한 방식을 이용하여 컴퓨터를 제어
<img src="https://velog.velcdn.com/images/lsm_0084/post/526aa7b9-2285-4d13-804b-4179a16bae65/image.png" alt="">
이런 검은화면인 터미널을 이용하여 명령어를 적어 사용하는 방법이다.</p>
<h2 id="기본적인-명령어">기본적인 명령어</h2>
<blockquote>
<p><strong>pwd</strong> / 현재 위치 확인
<strong>mkdir</strong> / 새로운 &#39;폴더&#39; 생성
<strong>ls</strong>  / 특정 폴더에 포함된 파일이나 폴더 확인
<strong>cd ** / 폴더로 진입
**touch</strong> / 새로운 &#39;파일&#39;생성
<strong>cat</strong> / 파일 내용을 터미널에 출력 
<strong>rm</strong> / 단일 파일 삭제
<strong>rm -rf</strong> / 폴더삭제
<strong>mv</strong> / 이름변경, 위치변경
<strong>cp</strong> / 복사
<strong>sudo</strong> / 관리자 권한을 일시적으로 획득</p>
</blockquote>
<h2 id="apt">apt</h2>
<ul>
<li>패키지 목록 갱신: apt update(관리자 권한 필요)</li>
<li>업그레이드 가능한 패키지 목록을 출력: apt list -—upgradable</li>
<li>전체 패키지 업그레이드(버전 업): apt upgrade (관리자 권한 필요)</li>
<li>특정 패키지만 업그레이드(버전 업): apt --only-upgrade install 패키지 이름 (관리자 권한 필요)</li>
<li>패키지 설치: apt install 패키지 이름 (관리자 권한 필요)</li>
<li>설치된 패키지 보기: apt list --installed</li>
<li>패키지 검색: apt search 검색어</li>
<li>패키지 정보 확인: apt show 패키지 이름</li>
<li>패키지 삭제: apt remove 패키지 이름(관리자 권한 필요)</li>
</ul>
<h2 id="nodejs">Node.js</h2>
<blockquote>
<p>런타임이란, 프로그래밍 언어가 실행되는 환경, 그리고 Node.js는 JavaScript 런타임.</p>
</blockquote>
<h2 id="nvm">nvm</h2>
<blockquote>
<p>nvm은 Node Version Manager. nvm을 통해 간단한 명령어로 Node.js를 설치하고, 다양한 Node.js version을 손쉽게 옮겨 다닐 수 있다.</p>
</blockquote>
<h2 id="packagejson">package.json</h2>
<blockquote>
<p>남이 만들어놓은 모듈을 node.js 에서는 npm 모듈이라는 이름으로 부르며, 이에 대한 정보를 담아둔 곳이 바로 package.json.
즉, 프로젝트(패키지) 전반에 관한 정보가 들어있다.</p>
</blockquote>
<h2 id="npm">npm</h2>
<blockquote>
<p>npm은 Node Package Manager로 일종의 앱스토어. 필요한 모듈을 다운로드할 수 있는, 모듈들이 모여있는 모듈 스토어.</p>
</blockquote>
<p>그리고 CLI를 이용하여 과제 제출하는 방법을 배웠다.
과제의 경우 간단했고, 이 CLI에 익숙해지는게 문제인거같다.</p>
<p>검은화면에 뭐라 적으면 막~수십줄이 뭐라뭐라 주르륵 올라가는데 어우......</p>
<p>이거....익숙해질 수 있을까..?화이팅</p>
]]></description>
        </item>
    </channel>
</rss>