자바스크립트

 

 

강의 보기 :

인프런 무료  강의 -   초급자를 위해 준비한 [프론트엔드, 웹 개발] 강의

 

 

실용적인 코딩컨텐츠를 만들어 가는 유튜브 짐코딩 채널입니다.
유튜브 | 깃헙 | Gym스타그램 | Coding스타그램

 

 

 

 

참고  문서 : => 

  1. 개발자를 위한 웹 기술
  2. JavaScript

MDN Plus  Learn more ✨

 

구글 검색 방법 : 

DOM mdn

BOM mdn

Navigator mdn

 

 

 

 

1. DOM 이란?

 

DOM 이란?

 

문서 객체 모델(The Document Object Model, 이하 DOM) 은 HTML, XML 문서의 프로그래밍 interface 이다. DOM은 문서의 구조화된 표현(structured representation)을 제공하며 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕는다. DOM 은 nodes와 objects로 문서를 표현한다. 이들은 웹 페이지를 스크립트 또는 프로그래밍 언어들에서 사용될 수 있게 연결시켜주는 역할을 담당한다.

웹 페이지는 일종의 문서(document)다. 이 문서는 웹 브라우저를 통해 그 내용이 해석되어 웹 브라우저 화면에 나타나거나 HTML 소스 자체로 나타나기도 한다. 동일한 문서를 사용하여 이처럼 다른 형태로 나타날 수 있다는 점에 주목할 필요가 있다. DOM 은 동일한 문서를 표현하고, 저장하고, 조작하는 방법을 제공한다. DOM 은 웹 페이지의 객체 지향 표현이며, 자바스크립트와 같은 스크립팅 언어를 이용해 DOM 을 수정할 수 있다.

W3C DOMWHATWG DOM 표준은 대부분의 브라우저에서 DOM 을 구현하는 기준이다. 많은 브라우저들이 표준 규약에서 제공하는 기능 외에도 추가적인 기능들을 제공하기 때문에 사용자가 작성한 문서들이 각기 다른 DOM 이 적용된 다양한 브라우저 환경에서 동작할 수 있다는 사실을 항상 인지하고 있어야 한다.

예를 들어, 표준 DOM 에서는 문서 안에서 모든 

 elements 에 대한 list 를 리턴하는 getElementsByTagName method 를 정의하고 있다:

var paragraphs = document.getElementsByTagName("P");
// paragraphs[0] is the first 

element // paragraphs[1] is the second

element, etc. alert(paragraphs[0].nodeName);

 

출처: https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model/Introduction

 

 

 

 

 

2. BOM 이란?

 

 

브라우저 객체 모델(BOM)이란?

웹 '브라우저'에 삽입된 각 요소를 객체로 인식하고 관리하는 것을 '브라우저 객체 모델(Browser Object Model)이라고 합니다. BOM은 자바스크립트 프로그램을 통해 브라우저 창을 관리할 수 있도록 객체화 해놓은 것입니다.

 

 




2. Window 객체 모델 계층도

 

 

브라우저 창이 열리면 Window 객체가 만들어지며, 그 하위에 브라우저 각 요소에 해당하는 객체가 만들어집니다.

 

객체설명

Window브라우저 창이 열릴 때마다 하나씩 만들어지는 객체, 브라우저 창 안에 존재하는 모든 요소의 최상위 객체

Document웹 문서에서 <body> 태그를 만나면 만들어지는 객체, HTML 문서 정보를 가지고 있음

History현재 창에서 사용자의 방문 기록을 저장하고 있는 객체

Location현재 페이지에 대한 URL 정보를 가지고 있는 객체

Navigator현재 사용 중인 웹 브라우저 정보를 가지고 있는 객체

Screen현재 사용 중인 화면 정보를 다루는 객체

 

 

출처: https://godsu94.tistory.com/156

 

 

 

 

 

3. script 태그 defer, async 

 

<p>...스크립트 앞 콘텐츠...</p>

<script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<!-- 바로 볼 수 있네요! -->
<p>...스크립트 뒤 콘텐츠...</p>

 

 

defer

<script>는 다운로드와 실행이 순차적으로 진행되는 것과 달리 defer 속성을 가진 스크립트는 브라우저가 <script defer>를 만났을 때 다운로드를 시작하지만, html 파싱을 막지 않고 </html>을 만났을 때 실행됩니다. (DOMContentLoaded 이벤트 이전에 실행됩니다) 스크립트를 <body>태그의 맨 마지막 줄에 작성하는 것과 같이 스크립트가 DOM을 조작하는 내용을 포함하는 것이 좋습니다. 하지만 일부 브라우저에서는 defer속성을 지원하지 않음으로 주의해야합니다.

 

async

async 속성을 가진 스크립트는 <script>, <script defer>와 마찬가지로 브라우저가 해당 요소를 만났을 때 외부 스크립트 다운로드를 시작합니다. defer와 마찬가지로 다운로드 중에 HTML 파싱을 막지 않지만 다운로드가 완료되면 즉시 실행하고 실행하는 동안 브라우저는 HTML 파싱을 멈춥니다. async속성의 스크립트에는 DOM을 조작하지 않으며 앞뒤에 로드되고 실행될 스크립트와 의존성이 없는 코드만 포함하는 것이 좋습니다. async속성 역시 일부 브라우저에서 지원하지 않음으로 주의해야합니다.

결론

HTML 문서에서 script의 위치는 매우 중요합니다. 스크립트가 로딩되고 실행되어야하는 시점을 잘 파악하여 적절한 위치에 사용하는것이 좋겠습니다.

 

 

 

 

4. this란 무엇인가?

 

 

 

this란 함수를 호출할 때 생성되는 실행 컨텍스트 객체다.

 

this가 가리키는 대상은 어떻게 this가 호출되는지에 따라 다르다. 아래 상황별로 this의 의미를 나눌 수 있다. 

 

→ 전역 공간에서의 this

→ 메서드로서 호출할 때 내부에서의 this

→ 함수로서 호출할 때 내부에서의 this

→ 콜백 함수 호출 시 내부에서의 this

→ 생성자 함수 내부에서의 this

 

 

참조    =>: 자바스크립트 this란 무엇인가?

 

 

 

index.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>This 는 무엇인가?</title>
    <!-- <script src="./js/this1.js" defer></script> -->
    <!-- <script src="./js/this2.js" defer></script> -->
     <!-- <script src="./js/this3.js" defer></script> -->
     <!-- <script src="./js/this4.js" defer></script> -->
     <!-- <script src="./js/this5.js" defer></script> -->
     <!-- <script src="./js/this6.js" defer></script> -->
      <script src="./js/this7.js" defer></script>    
</head>
<body>    
    <button>버튼</button>
</body>
</html>

 

this1.js

//1. this 는 호출한 놈이다  */
let person = {
    fullname: '짐코딩',
    age: 20,
    printThis: function () {
        console.log(this);
        console.log('this ==== person:', this === person);
        console.log('this ==== window:', this === window);
    }
}
person.printThis();
//출력-->
//여기서는  person 이 this 이다.
//this ==== person: true
//this ==== window: false



let printThis = person.printThis;
printThis();
//출력-->
//앞에 호출하는 객체가 없을 경우 디폴트로 window 가 this 가 된다.
//this ==== person: false
//this.js: 7 this ==== window: true


 

this2.js

//2.대부분의 경우 this 의 값은 함수를 호출한 방법에 의해 결정된다. */

function printThis() {
    //호출한 객체가 없기 때문에 여기서 this 는  default 값으로 =>window 
    console.log("this : ", this === window, this);
}

printThis();


let person1 = {
    name: "홍길동1",
    printThis: printThis,
};
person1.printThis();


let person2 = {
    name: "홍길동2",
    printThis: printThis,
};
person2.printThis();


let person3 = {
    name: "홍길동3",
    printThis: printThis,
};
person3.printThis();

 

this3.js

//3.이벤트값 내에서 this  이벤트 객체값이 this 가 된다.
//4.bind 는 한번만 처리가능하며 여기서 this 는 person1 이 this 가 된다.
let btn = document.querySelector("button");
btn.addEventListener('click', function () {
    console.log("this : ", this === window, this);
    console.log("btn 이 this 인가 ?", this === btn);
});
//출력 =>
//this : false < button > 버튼​</button >
//btn 이 this 인가 ? true


//ES5 에서 this 를 설정할 수 있는 bind 메서드가 나왔다.
function printThis() {
    //호출한 객체가 없기 때문에 여기서 this 는  default 값으로 =>window 
    console.log("this : ", this === window, this);
}

//bind 는 한번만 처리가능하며 여기서 this 는 person1 이 this 가 된다.
let person1 = {
    name: "홍길동"
}
let person2 = {
    name: "김길동"
}
let printThis1 = printThis.bind(person1);
printThis1();

//bind 는 한번 만 가능 여기서 출력은 홍길동 출력
//let printThis2 = printThis1.bind(person2);
//printThis2();


 

this4.js

//5.setTimeout 내에서서 this 는 window 가 된다.
//6.bind 처리시 person 이 this가 된다.
let person = {
    name: "짐코딩",
    age: 20,
    hello: function () {


        setTimeout(function () {
            console.log("1.this : ", this === window, this);
        }, 1000);

        setTimeout((function () {
            console.log("2.this : ", this === window, this);
        }).bind(this), 1000);

        function printHello() {
            console.log("3.this : ", this === window, this);
        }

        setTimeout(printHello.bind(this), 1000);

    }
}

person.hello();

//출력=>
//1.this : true Window { window: Window, self: Window, document: document, name: '', location: Location, … }
//2.this : false { name: '짐코딩', age: 20, hello: ƒ }
//3.this : false { name: '짐코딩', age: 20, hello: ƒ }

 

this5.js

//ES6
//7.익명 함수가 아닌 화살표 함수에서  this는 자신을 포함하고 있는 외부스코프객체 this를 물려 받는다
let person = {
    name: "짐코딩",
    age: 20,
    hello: function () {

        setTimeout(() => {
            console.log("1.this : ", this === window, this);
            console.log(this.name);
            console.log(this.age);
        }, 1000);
    }
}

person.hello();

//1.this : false { name: '짐코딩', age: 20, hello: ƒ }
//짐코딩
//20

 

this6.js

'use strict'
//8.this 기본값은 window 이나 strict 모드를 선언하면 undefined 가 기본값이 된다.
function printThis() {
    console.log("this : ", this === window, this);
}
printThis();

//this :  false undefined

 

this7.js

//9.화살표 함수 사용 주의
//1)화살표 함수 사용 주의 예
let person = {
    name: "짐코딩",
    age: 20,
    printThis: () => {
        //여기서 this 는 화살표 상위 객체인 window 가 된다.
        console.log(this);
    }
}
person.printThis();



//2)화살표 함수 사용 주의 예
let btn = document.querySelector("button");
btn.addEventListener('click', () => {
    console.log("this : ", this === window, this);
    console.log("btn 이 this 인가 ?", this === btn);
});

//this : true Window { window: Window, self: Window, document: document, name: '', location: Location, … }
//btn 이 this 인가 ? false

 

 

 

 

 

5. API란 무엇인가? 

 

 

 

https://blog.wishket.com/api란-쉽게-설명-그린클라이언트/

 

API의 역할은? 

1. API는 서버와 데이터베이스에 대한 출입구 역할을 한다.
: 데이터베이스에는 소중한 정보들이 저장되는데요. 모든 사람들이 이 데이터베이스에 접근할 수 있으면 안 되겠지요. API는 이를 방지하기 위해 여러분이 가진 서버와 데이터베이스에 대한 출입구 역할을 하며, 허용된 사람들에게만 접근성을 부여해줍니다.

2. API는 애플리케이션과 기기가 원활하게 통신할 수 있도록 한다.
: 여기서 애플리케이션이란 우리가 흔히 알고 있는 스마트폰 어플이나 프로그램을 말합니다. API는 애플리케이션과 기기가 데이터를 원활히 주고받을 수 있도록 돕는 역할을 합니다.

3. API는 모든 접속을 표준화한다.
API는 모든 접속을 표준화하기 때문에 기계/ 운영체제 등과 상관없이 누구나 동일한 액세스를 얻을 수 있습니다. 쉽게 말해, API는 범용 플러그처럼 작동한다고 볼 수 있습니다.

 

 

 

 

 

6. 동기와 비동기란?

 

 

 

동기(Synchronous): 요청에 대한 결과가 동시에 일어난다.
비동기(Asynchronous): 요청에 대한 결과가 동시에 일어나지 않는다.

동기는 바로 요청을 하면 시간이 얼마가 걸리던지 요청한 자리에서 결과가 주어집니다.

비동기는 요청과 결과가 동시에 일어나지 않을거란 약속입니다.

 

동기방식은 매우 간단하고 직관적이지만,

결과가 주어질 때까지 아무것도 못하고 기다려야 하기에 효율적이지 않다는 단점이 있습니다.

비동기 방식은 동기보다 복잡할 순 있지만,

결과가 주어지는데 시간이 걸리더라도 그 시간 동안 다른 작업을 할 수 있으므로 효율적으로 사용할 수 있습니다.

 

비동기와 동기의 일상생활의 예시를 들면,

커피를 마시고 카페에 갔는데 줄이 있습니다.

우리는

1. 커피를 주문한다.

2. 결제한다.

3. 커피를 받는다. 

이 세 과정을 거칩니다. 

 

여기서 앞에 있는 손님이 커피를 주문하고 결제하고, 커피를 받을때까지 직원이 커피 주문을 받지 않는다면,

줄은 길어지고 효율적이지 못하겠죠.

이것은 동기입니다. 하나의 한동작만 할수 있습니다.

하지만 비동기는 다릅니다.

앞에 손님이 주문을 하고 결제하고 나면, 다음사람이 주문을 하고 결제를 합니다.

그사이에 커피가 나오면 커피를 받아가고, 그 시간에 또 다른 손님은 주문하고 결제할 수 있습니다.

이렇게 사람마다 마시는 커피는 다를 수도 있고 동시에 이루어지지 않죠.

이것을 비동기라고 합니다.

 

비동기의 주요사례를 보면 다음과 같습니다.

1.dom element의 이벤트 핸들러

 -마우스, 키보드 입력(click, keydown 등)

 -페이지 로딩(DOMContentLoaded 등)

2. 타이머

 -타이머 API(setTimeout 등)

 -애니메이션 API(requestAnimationFrame)

3.서버에 자원 요청 및 응답

 -fetch API

 -AJAX(XHR)

 

 

 

출처 :

https://miracleground.tistory.com/entry/자바스크립트동기비동기-개념정리callbackpromiseasyncawait

 

 

 

7. 프론트엔드&백엔드란?

 

 

 

프론트엔드 개발에서 사용하는 언어는 어떤 것들인가?

HTML
: HTML은 하이퍼텍스트와 마크업 언어로 구성되어 있습니다. 하이퍼텍스트는 페이지들 사이의 링크를 정의해 줍니다. 반면에 마크업 언어는 웹페이지의 구조를 정의하는데 사용됩니다.
CSS
: CSS는 종속 스타일 시트(Cascading Style Sheets)의 약자입니다. CSS는 개발자가 웹페이지에 다양한 스타일을 적용할 수 있게 해줌으로써 애플리케이션 페이지를 표시하는 프로세스를 단순하게 만들어주는 디자인 언어입니다. CSS는 HTML보다 독립적으로 작동해서 각 웹페이지들을 보완해 줍니다.
Javascript
: 자바스크립트는 어마어마할 정도로 인기가 많은 언어로써, 사용자들을 위해 상호작용하는 애플리케이션을 만들 수 있도록 도와줍니다. 또한, 웹사이트의 기능성을 향상시키는데 사용되며, 웹 기반의 소프트웨어 또는 게임들을 실행할 수 있게 해주죠.

프론트엔드 개발에서 사용되는 테크놀로지는 무엇일까?


AngularJS
: 앵귤러JS는 오픈소스 자바스크립트 프레임워크로써, 주로 싱글 페이지 웹 애플리케이션(SPA)을 만드는 데 사용됩니다. 앵귤러JS는 계속해서 발전하고 있으며, 개발자가 웹 애플리케이션을 더욱 잘 만들 수 있게 해주는 프론트엔드 개발 테크놀로지들 중 하나입니다. 앵귤러 JS는 정적(static) HTML을 동적(dynamic) HTML로 변환해주는 기능이 있습니다. 또한 오픈소스 테크놀로지이기 때문에, 누구나 자유롭게 사용할 수 있고, 변경할 수도 있죠.
ReactJS
: 리액트는 프론트엔드 개발에서 사용할 수 있는 유연하고 효과적인 선언형(declarative)의 자바스크립트 라이브러리입니다. 뛰어난 사용자 인터페이스를 만드는 데 도움이 되죠. 리액트는 컴포넌트 기반의 오픈소스 라이브러리이며, 애플리케이션의 반응형 뷰 레이어(view layer)입니다. 이 기술은 페이스북이 개발해서 유지관리를 해오고 있습니다.
​Bootstrap
: 부트스트랩은 반응형 웹 애플리케이션 및 웹사이트를 개발하기 위해 사용되는 오픈소스 무료 도구입니다. 부트스트랩은 가장 인기 있는 자바스크립트, CSS, HTML 프레임워크이며, 모바일 우선의 반응형 웹사이트를 구축할 수 있게 해줍니다.

백엔드 개발에서 사용되는 언어들은 어떤 것들일까?

PHP
: 특별히 웹 애플리케이션 개발을 위해서 고안된 서버 측 스크립트 언어입니다. PHP는 서버 측에서 실행되기 때문에, 특히 서버 측 언어로서 많은 인기를 얻고 있습니다.
Node.js
: 노드는 크로스 플랫폼의 오픈소스 런타임(run time) 환경으로써, 브라우저의 외부에서 자바스크립트 코드를 실행할 수 있게 해줍니다. 노드는 프로그래밍 언어도 아니고, 프레임워크도 아닙니다. 노드는 모바일이나 웹 어플리케이션용 API와 같은 백엔드 서비스 개발을 위해서 사용됩니다. 이미 페이팔, 우버, 월마트, 넷플릭스 등 포춘지 선정 500대 기업에서 많이들 사용하고 있죠.
Javascript
: 앞서 프론트엔드 때 소개해드렸던 자바스크립트는, 프론트엔드 백엔드 모두에서 사용할 수 있는 프로그래밍 언어입니다.​
C++
: C++은 요즘에도 경쟁력을 갖추기 위해서 가장 널리 사용되는 프로그래밍 언어입니다. 또한, 백엔드 언어로도 많은 인기를 얻고 있죠.
Java
: 자바는 가장 인기 있는 프로그래밍 언어들 중 하나이며, 개발자 커뮤니티에서 널리 사용되고 있는데요. 자바의 컴포넌트는 쉽게 사용할 수 있기 때문에 확장성이 아주 뛰어난 플랫폼이라고 말할 수 있습니다.
Python
: 파이썬은 개발자들이 시스템을 효율적으로 통합하고, 빠르게 작업할 수 있게 해주는 최고의 프로그래밍 언어입니다.

출처 :  https://blog.wishket.com/프론트엔드-vs-백엔드-개념과-차이점/

 

 

 

8. 이벤트 전파, 버블링&캡쳐링

 

 

버블링(bubbling)

한 요소에 이벤트가 발생하면, 이 요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작합니다. 가장 최상단의 조상 요소를 만날 때까지 이 과정이 반복되면서 요소 각각에 할당된 핸들러가 동작합니다.

3개의 요소가 FORM > DIV > P 형태로 중첩된 구조를 살펴봅시다. 요소 각각에 핸들러가 할당되어 있습니다.

<style>
  body * {
    margin: 10px;
    border: 1px solid blue;
  }
</style>

<form onclick="alert('form')">FORM
  <div onclick="alert('div')">DIV
    <p onclick="alert('p')">P</p>
  </div>
</form>

 

가장 안쪽의 <p>를 클릭하면 순서대로 다음과 같은 일이 벌어집니다.

  1. <p>에 할당된 onclick 핸들러가 동작합니다.
  2. 바깥의 <div>에 할당된 핸들러가 동작합니다.
  3. 그 바깥의 <form>에 할당된 핸들러가 동작합니다.
  4. document 객체를 만날 때까지, 각 요소에 할당된 onclick 핸들러가 동작합니다.

이런 동작 방식 때문에 <p> 요소를 클릭하면 p → div → form 순서로 3개의 얼럿 창이 뜨는것이죠.

이런 흐름을 '이벤트 버블링’이라고 부릅니다. 이벤트가 제일 깊은 곳에 있는 요소에서 시작해 부모 요소를 거슬러 올라가며 발생하는 모양이 마치 물속 거품(bubble)과 닮았기 때문입니다.

 

캡처링

이벤트엔 버블링 이외에도 ‘캡처링(capturing)’ 이라는 흐름이 존재합니다. 실제 코드에서 자주 쓰이진 않지만, 종종 유용한 경우가 있으므로 알아봅시다.

표준 DOM 이벤트에서 정의한 이벤트 흐름엔 3가지 단계가 있습니다.

  1. 캡처링 단계 – 이벤트가 하위 요소로 전파되는 단계
  2. 타깃 단계 – 이벤트가 실제 타깃 요소에 전달되는 단계
  3. 버블링 단계 – 이벤트가 상위 요소로 전파되는 단계

 

출처 :https://ko.javascript.info/bubbling-and-capturing

 

 

 

 

 

 

 

 

9. 자바스크립트 유용한 Array APIs

 

 

 

map,    some,    every,   filter,    reduce

 

Array.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>자바스크립트 유용한 Array APIs</title>
    
    <!--
     개발하는 애플리케이션의 크기가 커지면 언젠간 파일을 여러 개로 분리해야 하는 시점이 옵니다. 
    이때 분리된 파일 각각을 '모듈(module)'이라고 부르는데, 모듈은 대개 클래스
    하나 혹은 특정한 목적을 가진 복수의 함수로 구성된 라이브러리 하나로 구성됩니다.
    
    모듈은 단지 파일 하나에 불과합니다. 스크립트 하나는 모듈 하나입니다.
    모듈에 특수한 지시자 export와 import를 적용하면 다른 모듈을 불러와 불러온 모듈에 있는 함수를 호출하는 것과 같은 기능 공유가 가능합니다.
    export 지시자를 변수나 함수 앞에 붙이면 외부 모듈에서 해당 변수나 함수에 접근할 수 있습니다(모듈 내보내기).
    import 지시자를 사용하면 외부 모듈의 기능을 가져올 수 있습니다(모듈 가져오기).
    export 지시자를 사용해 파일 sayHi.js 내부의 함수 sayHi를 외부로 내보내 봅시다.
    모듈은 특수한 키워드나 기능과 함께 사용되므로 
    <script type="module"> 같은 속성을 설정해 해당 스크립트가 모듈이란 걸 브라우저가 알 수 있게 해줘야 합니다.
    엄격 모드로 실행됨
    모듈은 항상 엄격 모드(use strict)로 실행됩니다. 선언되지 않은 변수에 값을 할당하는 등의 코드는 에러를 발생시킵니다.
    https://ko.javascript.info/modules-intro
     -->
     <!-- <script type="module"  src="./js/map.js"></script>  -->
      <!-- <script type="module"  src="./js/some.js"></script> -->
      <!-- <script type="module"  src="./js/every.js"></script>  -->
     <!-- <script type="module"  src="./js/filter.js"></script> -->
     <script type="module"  src="./js/reduce.js"></script>
</head>
<body>
</body>
</html>

 

data.js

export const numbers = [1, 2, 3, 4, 5, 6, 7];

export class Student {
    constructor(name, koreaLanguage, english, mathematics) {
        //console.log("this 는", this);
        this.name = name;
        this.koreaLanguage = koreaLanguage;
        this.english = english;
        this.mathematics = mathematics;
    }
}

const student1 = new Student("홍길동", 95, 87, 75);
const student2 = new Student("김길동", 67, 92, 55);
const student3 = new Student("고길동", 78, 82, 100);
const student4 = new Student("최길동", 45, 55, 85);


export const students = [student1, student2, student3, student4];
export const fluits = ["사과", "딸기", "배", "참외", "딸기", "수박"];

 

1) map

"use strict";

import { numbers, Student, students, fluits } from './data.js';


// const result = numbers.map(function (number) {
//     return number * 2;
// });
const result = numbers.map((number) => number * 2);
console.log(result);

//(7)[2, 4, 6, 8, 10, 12, 14]

console.log("영어 점수",
    students.map((student) => student.english)
);
//영어 점수(4)[87, 82, 82, 55]

console.log("학생 이름",
    students.map((student) => student.name)
);

//학생 이름(4)['홍길동', '김길동', '고길동', '최길동']

 

2)some

"use strict";

import { numbers, Student, students, fluits } from './data.js';


// some 함수는 배열의 요소 중 하나라도 callbackFunction에서 true를 리턴하면 true를 리턴 합니다.
// 하나라도 false가 떨어지면 false를 리턴합니다.
//array.some(callbackFunction(currentValue, index, array), thisArg)
// 구문은 filter, map과 같습니다.
// callbackFunction, thisArg 두개의 매개변수를 갖고,
// callbackFunction은
// currentValue: 배열의 현재 값
// index: 배열의 현재 값의 인덱스
// array: 현재 배열
// thisArg: this값으로 활용될 것 입니다.


//some 함수는 요소를 순회하면서 하나라도 존재하면 true 반환 후 종료
console.log("과일 중에 배가 있나요?",
    fluits.some((fluit, index) => {
        console.log("index : ", index, "fluit: ", fluit);
        return fluit === "배"
    })
);

// index: 0 fluit: 사과
// index: 1 fluit: 딸기
// index: 2 fluit: 배
//  과일 중에 배가 있나요 ? true


console.log("숫자에 7이상이 숫자가 있나요?",
    numbers.some((number) => number >= 8)
);
// 숫자에 7이상이 숫자가 있나요 ? false


console.log("수학 점수가 100점인 학생이 있나요?",
    students.some((student) => student.mathematics === 100)
);
// 수학 점수가 100점인 학생이 있나요 ? true

console.log("영어 점수가 50점인 미만인 학생이 있나요?",
    students.some((student) => student.english < 50)
)
// 영어 점수가 50점인 미만인 학생이 있나요 ? false

 

3)every

"use strict";

import { numbers, Student, students, fluits } from './data.js';


// every 함수는 배열의 모든 요소가 callbackFunction 에서 true를 리턴해야 true를 리턴,
// 하나라도 false가 떨어지면 false를 리턴합니다.
//array.every(callbackFunction(currentValue, index, array), thisArg)
// 구문은 filter, map과 같습니다.
// callbackFunction, thisArg 두개의 매개변수를 갖고,
// callbackFunction은
// currentValue: 배열의 현재 값
// index: 배열의 현재 값의 인덱스
// array: 현재 배열
// thisArg: this값으로 활용될 것 입니다.

console.log("숫자가 모두 8이하 인가요?",
    numbers.every((number) => number <= 8)
);

//숫자가 모두 8이하 인가요 ? true



console.log("학생들이 수학 점수가 80점 이상인가요?",
    students.every((student) => student.mathematics <= 80)
)

//학생들이 수학 점수가 80점 이상인가요 ? false

 

 

 

4)filter

"use strict";

import { numbers, Student, students, fluits } from './data.js';

//ECMA에는 "주어진 배열의 값들을 오름차순으로 접근해 callbackfn을 통해 true를 반환하는 요소를 기준으로 신규 배열을 만들어 반환한다"

console.log("짝수만 출력해주세요.",
    numbers.filter(number => number % 2 === 0)
);
//짝수만 출력해주세요. (3) [2, 4, 6]



console.log("홀수만 출력해주세요.",
    numbers.filter(number => number % 2 === 1)
);
//홀수만 출력해주세요. (4) [1, 3, 5, 7]


console.log(
    "영어점수가 90점 이상인 학생들은?",
    students.filter((Student) => Student.english >= 90)
);

//영어점수가 90점 이상인 학생들은 ?
//    [Student]0: Student { name: '김길동', koreaLanguage: 67, english: 92, mathematics: 55 } length: 1[[Prototype]]: Array(0)

 

 

5)reduce

"use strict";

import { numbers, Student, students, fluits } from './data.js';

//reduce()** **메서드는 배열의 각 요소에 대해 주어진 **리듀서**(reducer) 함수를 실행하고, 하나의 결과값을 반환합니다.
// 리듀서 함수는 네 개의 인자를 가집니다.

// 1.누산기(acc)  accumulator
// 2.현재 값(cur)  currentValue
// 3.현재 인덱스(idx)  currentIndex
// 4.원본 배열(src)  array

//reduce()는 빈 요소를 제외하고 배열 내에 존재하는 각 요소에 대해 callback 함수를 한 번씩 실행하는데, 콜백 함수는 다음의 네 인수를 받습니다:

console.log("reduce",
    [0, 1, 2, 3, 4].reduce(function (accumulator, currentValue, currentIndex, array) {
        return accumulator + currentValue;
    })
);

//출력 =>
//reduce 10

// 콜백은 4번 호출됩니다.각 호출의 인수와 반환값은 다음과 같습니다.

// callback	accumulator	currentValue	currentIndex    	array	            반환 값
// 1번째 호출	0	        1	            1           [0, 1, 2, 3, 4]	            1
// 2번째 호출	1	        2	            2           [0, 1, 2, 3, 4]	            3
// 3번째 호출	3	        3	            3           [0, 1, 2, 3, 4]	            6
// 4번째 호출	6	        4	            4           [0, 1, 2, 3, 4]         	10
// reduce()가 반환하는 값으로는 마지막 콜백 호출의 반환값(10)을 사용합니다.



const result = numbers.reduce((acc, cur, idx, src) => {
    console.log("acc:", acc, "cur: ", cur, " idx: ", idx);
    return acc + cur;
}, 0);

console.log("result : ", result);
// acc: 0 cur: 1  idx: 0
// acc: 1 cur: 2  idx: 1
// acc: 3 cur: 3  idx: 2
// acc: 6 cur: 4  idx: 3
// acc: 10 cur: 5  idx: 4
// acc: 15 cur: 6  idx: 5
// acc: 21 cur: 7  idx: 6
//result: 28

console.log("fluits : ", fluits);
//중복된 값 제거
const result2 = fluits.reduce((acc, cur) => {
    console.log("acc : ", acc, "cur :", cur);
    if (acc.includes(cur) === false) {
        acc.push(cur);
    }
    return acc;
}, []);
console.log("result2 ", result2);

// fluits: (6)['사과', '딸기', '배', '참외', '딸기', '수박']
// acc: [] cur: 사과
// acc: ['사과'] cur: 딸기
// acc: (2)['사과', '딸기'] cur: 배
// acc: (3)['사과', '딸기', '배'] cur: 참외
// acc: (4)['사과', '딸기', '배', '참외'] cur: 딸기
// acc: (4)['사과', '딸기', '배', '참외'] cur: 수박
// result2(5)['사과', '딸기', '배', '참외', '수박']

 

 

 

 

 

10. JavaScript 모듈 시스템

 

모듈 소개
개발하는 애플리케이션의 크기가 커지면 언젠간 파일을 여러 개로 분리해야 하는 시점이 옵니다. 이때 분리된 파일 각각을 '모듈(module)'이라고 부르는데, 모듈은 대개 클래스 하나 혹은 특정한 목적을 가진 복수의 함수로 구성된 라이브러리 하나로 구성됩니다.

자바스크립트가 만들어 진지 얼마 안 되었을 때는 자바스크립트로 만든 스크립트의 크기도 작고 기능도 단순했기 때문에 자바스크립트는 긴 세월 동안 모듈 관련 표준 문법 없이 성장할 수 있었습니다. 새로운 문법을 만들 필요가 없었던 것이죠.

그런데 스크립트의 크기가 점차 커지고 기능도 복잡해지자 자바스크립트 커뮤니티는 특별한 라이브러리를 만들어 필요한 모듈을 언제든지 불러올 수 있게 해준다거나 코드를 모듈 단위로 구성해 주는 방법을 만드는 등 다양한 시도를 하게 됩니다.

그 시도는 다음과 같은 모듈 시스템으로 이어졌습니다.

AMD – 가장 오래된 모듈 시스템 중 하나로 require.js라는 라이브러리를 통해 처음 개발되었습니다.


CommonJS – Node.js 서버를 위해 만들어진 모듈 시스템입니다.
UMD – AMD와 CommonJS와 같은 다양한 모듈 시스템을 함께 사용하기 위해 만들어졌습니다.

ES Module이란

 

  • ES6에 도입된 모듈 시스템.
  • import, export를 사용해 분리된 자바스크립트 파일끼리 서로 접근할 수 있다.


이런 모듈 시스템은 오래된 스크립트에서 여전히 발견할 수 있는데, 이제는 역사의 뒤안길로 사라져가고 있습니다.

 

모듈 시스템은 2015년에 표준으로 등재되었습니다. 이 이후로 관련 문법은 진화를 거듭해 이제는 대부분의 주요 브라우저와 Node.js가 모듈 시스템을 지원하고 있습니다. 이제 본격적으로 모던 자바스크립트에서 쓰이는 모듈에 대해 알아봅시다.

모듈이란
모듈은 단지 파일 하나에 불과합니다. 스크립트 하나는 모듈 하나입니다.

모듈에 특수한 지시자 export와 import를 적용하면 다른 모듈을 불러와 불러온 모듈에 있는 함수를 호출하는 것과 같은 기능 공유가 가능합니다.
 

 

1)ES Module

index.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript 모듈 시스템</title>
    <!-- <script type="module" src="../js/a.js"></script>
    <script type="module" src="../js/b.js"></script>
     -->
   <!--
    <script type="module">
       import a_number  from  "../js/a.js";
       import b_number  from  "../js/b.js";
       console.log("a_number:",a_number);
       console.log("b_number:",b_number);

        // a.js >number :  10
        // b.js::::1 >number :  undefined
        // b.js:3 b.js::::2 >number :  20
        // a_number: 10
        // b_number: 20
    </script>
    -->  
    <script type="module" src="index.js"></script>
</head>
<body>    
</body>
</html>

 

math.js

////////////////////////////////
//////1. export 유형1////////////
////////////////////////////////
// export const perfectScore = 100;

// export const sum = (num1, num2) => {
//     return num1 + num2;
// }

// export const avg = (num1, num2) => {
//     return (num1 + num2) / 2;
// }

// const subtract = (num1, num2) => {
//     return (num1 - num2);
// }

//export default subtract;




////////////////////////////////
//////2. export 유형2////////////
////////////////////////////////
const perfectScore = 100;

const sum = (num1, num2) => {
    return num1 + num2;
}
const avg = (num1, num2) => {
    return (num1 + num2) / 2;
}
const subtract = (num1, num2) => {
    return (num1 - num2);
}
export default {
    perfectScore,
    sum,
    avg,
    subtract
}

 

index.js

//////////////////////////////////////////////////
//////      1. 구조 분해 로 import ///////////////
//////////////////////////////////////////////////
//import { perfectScore, sum, avg } from './math.js';
// console.log('perfectScore: ', perfectScore);
// console.log('sum: ', sum(80, 10));
// console.log('avg: ', avg(80, 90));



//////////////////////////////////////////////////
//////  2.all  as 로 임의 변수설정 import /////////
//////////////////////////////////////////////////
// import * as math from './math.js';
// console.log('perfectScore: ', math.perfectScore);
// console.log('sum: ', math.sum(80, 10));
// console.log('avg: ', math.avg(80, 90));




//////////////////////////////////////////////////
//3.defualt 인경우 구조분해 없이 직접 지정이 가능하며,
// 임의로 변수명을 지정할수 있다. /////////////////
//////////////////////////////////////////////////
// import subtract2 from "./math.js";
// console.log('subtract: ', subtract2(80, 90));
//subtract:  -10



//////////////////////////////////////////////////
//////4. export 유형2방벙으로 import 받기///////////
//////////////////////////////////////////////////
import math from "./math.js";
console.log('subtract: ', math.subtract(80, 90));

 

 

 

2)CommonJS

index.js

//1.구조분해 방법
const { perfectScore, sum, avg, subtract } = require('./math');
console.log('1.perfectScore: ', perfectScore);
console.log('1.sum: ', sum(80, 10));
console.log('1.avg: ', avg(80, 90));
console.log('1.subtract:', subtract(80, 90));
console.log("=====================");

//2. 하나의 변수로명으로 받는 방법
const math = require('./math');
console.log('2.perfectScore: ', math.perfectScore);
console.log('2.sum: ', math.sum(80, 10));
console.log('2.avg: ', math.avg(80, 90));
console.log('2.subtract:', math.subtract(80, 90));



//commonjs 방식은 node 방식이라 node 로 실행 한다.
//node commonjs/index.js


// 출력 결과
// 1.perfectScore: 100
// 1.sum: 90
// 1.avg: 85
// 1.subtract: -10
// =====================
// 2.perfectScore:  100
// 2.sum:  90
// 2.avg:  85
// 2.subtract: -10

 

 

math.js

////////////////////////////////////////////////////////
///////1.exports 개별적인 방법////////////////////////////
////////////////////////////////////////////////////////
// exports.perfectScore = 100;

// exports.sum = (num1, num2) => {
//     return num1 + num2;
// }
// exports.avg = (num1, num2) => {
//     return (num1 + num2) / 2;
// }
// exports.subtract = (num1, num2) => {
//     return (num1 - num2);
// }



////////////////////////////////////////////////////////
///////2.exports 하나의 객체로 내보내는 방법/////////////
////////////////////////////////////////////////////////
const perfectScore = 100;

const sum = (num1, num2) => {
    return num1 + num2;
}
const avg = (num1, num2) => {
    return (num1 + num2) / 2;
}
const subtract = (num1, num2) => {
    return (num1 - num2);
}

module.exports = {
    perfectScore,
    sum,
    avg,
    subtract
}

 

 

3) 프로젝트 단위로 ES 모듈 적용

Node.js에서 ES 모듈을 사용하는 두번째 방법은 package.json 파일 설정을 통해 전체 파일에 적용하는 것입니다. 모든 파일의 확장자를 일일이 바꾸지 않고, 프로젝트 전체에 ES 모듈을 적용하고 싶을 때 적합한 방법입니다.

먼저 프로젝트의 package.json 파일을 열고, 최상위에 type 항목을 module로 설정합니다.

  • package.json
{
  // 생략
  "type": "module"
  // 생략
}

 

 

 

11. NPM 기초 강좌 

 

 

# package.json 생성

- 수많은 패키지를 다운받다보면 관리가 어려워진다.

- 그래서 프로젝트마다 package.json 파일을 만들어서 패키지 목록 및 버전을 관리한다.

* 프로젝트를 생성하자마자 package.json을 만들어주고 시작하길 권장한다.

 

- 명령어:  npm init 

 

1) package name 등의 정보를 입력해준다. 필요 없는 항목은 Enter를 눌러 스킵할 수 있다.

2) 마지막에 Is this OK? 항목에서 yes를 입력해준다.

* git 설정이 안 되어 있다면, git repository 관련 warning이 뜰 수 있는데 무시해도 된다

 

# 패키지 설치/삭제 명령어

: 외부 모듈인 패키지를 설치/삭제하는 명령어이다.

1. 패키지 설치

- 명령어:  npm install 패키지명  

: 패키지를 현재의 프로젝트의 node_modules 폴더에 설치한다.

: package.json 파일의 dependencies 항목에도 자동으로 추가 된다.

* 과거에는 dependencies에 패키지를 추가하기 위해 npm install --save 패키지명 으로 설치했으나, npm@5 버전 이후 부터는 디폴트로 적용되므로 --save 옵션을 붙이지 않아도 된다.

* npm i 패키지명 으로 축약 사용 가능.

* npm install 패키지명@버전 으로 버전을 지정하여 설치 가능

npm install 주소 로 패키지 설치 주소를 지정하여 설치 가능

 

2. 패키지 여러개 설치

- 명령어:  npm install 패키지1 패키지2 패키지3 

: 여러개의 패키지를 동시에 설치한다.

npm i 패키지1  패키지2 패키지3 으로 축약 사용 가능.

 

3. 전역 설치

- 명령어:  npm install --global 패키지명 

: npm 자체가 설치되어 있는 폴더에 패키지를 설치하여 어디서나 참조할 있게 한다.

: 현재 프로젝트의 node_modules에 설치되지 않으므로, package.json에도 기록되지 않는다.

* 맥, 리눅스의 경우, sudo를 붙여서 sudo npm install --global 패키지명 으로 설치해야 할 수 있다.(권한 이슈)

* npm i -g 패키지명 으로 축약 가능

 

4. 개발용 설치

- 명령어:  npm install --save-dev 패키지명 

: package.json 파일의 devDependencies 항목에 추가되도록 설치한다.

* npm i -D 패키지명 으로 축약 가능

 

5. package.json 파일을 사용한 설치

- 명령어:  npm install 

: package.json 파일이 저장된 폴더에서 명령어를 실행하면, dependencies 항목에 기록된 패키지들을 모두 자동으로 설치해 준다.

: 이 기능을 사용하면, 프로젝트를 복사/백업할 때 모든 모듈 파일을 옮길 필요 없이 package.json 파일만 복사해두면 된다.

* npm i 로 축약 가능

 

6. 패키지 삭제

- 명령어:  npm uninstall 패키지명 

: node_modules 폴더에 설치된 패키지를 삭제한다. package.json의 dependencies 항목에서도 제거된다.

* npm rm 패키지명 으로 축약 가능

# 기타 NPM 명령어

1.  npm -version 

: npm 자체의 버전 체크

* npm -v 로 축약 가능

 

2.  npm install -g npm 

: npm 자체의 버전 업그레이드

* 맥, 리눅스의 경우 sudo를 앞에 붙여줘야할 수 있다.

 

3.  npm outdated 

: 업데이트 가능한 패키지가 있는지 체크

 

4.  npm update 패키지명 

: 패키지를 최신 버전으로 업데이트

 

5.  npm info 패키지명 

: 패키지의 상세 정보 파악

 

6.  npm search 검색어 

: npm 서버의 패키지 검색

 

7.  npm help 

: 명령어 목록 확인

* npm 명령어 help : 명령어에 대한 설명 및 옵션 정보 확인

 

8.  npm ls 

: 설치된 패키지들의 구조를 보여준다.

npm ls 패키지명: 패키지와 관련된 구조만 노출

* npm ll : 더 상세한 페캐지 구조 정보 노출

 

9.  npx 패키지명 [옵션] 

: 전역 설치하지 않은 패키지를 전역처럼 콘솔에서도 사용할 수 있도록 해주는 명령어

: 즉, node_modules/bin 폴더에서 해당 패키지의 바이너리 파일을 찾아서 실행시켜 준다.

: 만약 해당 패키지가 없다면 임시로 다운로드 받아 설치하여 실행시켜준다.

* npx에 대한 내용은 길어질 수 있으므로 생략.

* 사용 예시: npx pm2 list

출처: https://curryyou.tistory.com/346 [카레유:티스토리]

 

 

Nodemon 사용하
서버 코드를 변경 할 때마다, 서버를 재시작하는게 꽤 귀찮지요? nodemon 이라는 도구를 사용하면 이를 자동으로 해줍니다.

먼저, 이 도구를 npm 을 통해 글로벌 설치하세요.

$ npm install -g nodemon
설치한 다음엔, 다음 명령어를 통해서 서버를 실행하면 코드가 바뀔떄마다 자동으로 재시작을 해줍니다.

$ nodemon --watch src/ src/index.js
위 명령어는, src/ 디렉토리에서 코드변화가 감지하면 재시작을 하도록 설정하고, src/index.js 를 실행시켜줍니다.

 

 

 

 

 

 

 

12. Webpack 기초 강좌 

 

 

1. npm 설정

▶ vs code에 웹팩을 이용할 폴더 open → 터미널 오픈 (하단의 terminal 혹은 상단 메뉴바에 termianl → new termianl) 

// 프로젝트 폴더 터미널에 입력
npm init

▶ init를 입력하면 package-name을 설정하라고 뜨는데 enter를 누르면 자동으로 폴더 이름이 입력된다. (단, 한글은 인식하지 못하므로 한글일 경우 영어로 package 이름을 설정해줘야 한다.) 이후에 vsersion이나 description 등 다양한 설정이 나오는데 특별히 설정할 것이 없으면 enter를 계속 눌러주면 된다. 그리고 마지막에 Is this OK?라고 물어보는데 yes라고 입력해도 되고 그냥 enter를 눌러도 된다.

▶ 이 모든 과정이 끝나면 폴더에 package.json 파일이 생성된다.

 

 

2. webpack 설치

// 프로젝트 폴더 터미널에 입력
npm i webpack webpack-cli -D

▶ 설치가 끝나면 node_modules 폴더와 package-lock.js 파일이 생성된다

package.json  에 다음과 같이 생성된다.

  "devDependencies": {
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0"
  }

 

 

웹펙 공식 문서  참조   : https://webpack.js.org/

 

3. root 디렉토리에  webpack.config.js 파일 생성후 다음과 같이 작성

const path = require('path');

module.exports = {
    mode: "production", //development
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js',
    },
};

 

4. 빌드

다음 명령어로 빌드하면  dist 디렉토리가 생성 되고 bundle.js 파일이 생성된다.

$ npx webpack 

 

5. package.json 의 scripts 에  등록

package.json   "build": "webpack" 를 등록한 후 다음 명령어를 통해서도 빌드가 가능해 진다.

$ npm run  build

 

  "scripts": {    
    "build": "webpack"
  },

 

 

6.index.html 에  webpack 으로 빌드된  파일로 변경 처리

   <script type="module"  src="./dist/bundle.js" ></script>   

 

 

 

소스 : https://github.com/braverokmc79/javascript_study_1

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

문유지족자( 蚊有知足者 ). 모기도 만족한 것을 아는 것이 있다. 변하여 사람은 만족하는 것을 알아야 한다는 비유. 제(齊) 나라 환공의 고사로, 공의 피를 빨지 않고 그대로 물러가는 예(禮)를 아는 모기와 공의 피를 빨고는 곧 물러가는 만족을 아는 모기가 있었다고 하는 고사. -잡편

댓글 ( 4)

댓글 남기기

작성