API

 

API는 서로 다른 다른 소프트웨어나 어플리케이션 간을 연결해주는 매개체이자 약속이라고 볼 수 있다.

 

API를 작성한다는 의미

  • 웹 어플리케이션에서 원하는 기능을 수행하는 URL과 인터페이스를 제공한다는 의미다.
  • API에서 원하는 데이터를 받아 DB에 데이터를 저장하고, 저장되어 있는 데이터를 읽어 웹 어플리케이션에 데이터를 제공하는 행위를 통해 사용자가 원하는 목적을 이룰 수 있게 해야 한다.

REST API

REST API ( 출처 : https://mannhowie.com/rest-api )

 

  • REST는 'Representational State Transfer'의 줄임 말로, 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위해 네트워크 상에서 자원을 쉽고 명확하게 식별하고 조작할 수 있게 도와주는 소프트웨어 아키텍처의 한 형식이다.
  • URL, Headers, Method 등 네트워크 표현 수단을 이해하기 쉬운 표현으로 정의하는 것을 말하고, 'REST 아키텍쳐'는 쉽게 이해할 수 있도록 '자원'을 정의하고 이 '자원'을 중심으로 표현을 구성하는 원칙을 제시한다.
  • REST API는 HTTP를 통해 웹 서비스의 자원에 접근하는 방식을 'REST 아키텍쳐'의 규칙을 따라 구현된 API라고 생각하면 된다.

REST API의 구성 요소

REST API의 구성은 크게 세 가지로 이루어 진다.

1. 자원 ( Resource ) - URL

  • 소프트웨어가 관리하는 모든 것을 자원으로 표현할 수 있다.

2. 행위 - HTTP method

  • http method인 GET, POST 등으로 자원에 대한 행위를 표현할 수 있다. ( 예를 들어, GET 메서드는 '조회'와 관련이 있어서 데이터를 읽는 작업을 수행하고, POST 메서드는 '생성'과 관련이 있어서 새로운 데이터를 생성하는 작업을 수행한다. )
  • 자원에 대한 생성/조회/수정/삭제를 각각의 method로 나누어 놓고, 이를 보통 CRUD라 한다.
Create : 생성(POST)
Read : 조회(GET)
Update : 수정(PUT),(PATCH)
Delete : 삭제(DELETE)

 

3. 표현

  • 해당 자원을 어떻게 표현할지에 대한 방법으로, 보통 JSON, XML 같은 형식을 이용해 자원을 표현한다.
  • HTTP에서는 Content-Type 이라는 헤더를 통해 표현 방법을 서술한다.

REST API 예시

router.get('/books', (req, res) => {
	res.json({ success: true, data: getAllBooks() });
});
  • 위 예시코드는 /books 라는 URL을 통해 전체 책 목록을 불러와 응답해 주는 역할을 하는 API다.
  • http 메서드인 GET은 리소스를 조회하는 역할을 담당하므로, 위 코드는 전체 책 목록을 조회하고, 그 결과를 JSON 형식으로 반환한다. 이렇게 API가 "REST 원칙"에 따라 구현되었으므로, 이 API는 RESTful 하다고 볼 수 있다.

Routing의 이해

Routing은 클라이언트의 요청 조건( http 메서드, 주소 등)에 대응해 응답하는 방식을 말한다.

여기서 말하는 Router는 클라이언트의 요청을 쉽게 처리 할 수 있게 도와주는 Express.js의 기본 기능중 하나다.

  • 일반적으로 Router는 아래와 같은 구조를 가진다.
router.METHOD(PATH, HANDLER);
  • router : Express.js의 라우터를 정의하기 위해 사용한다
  • METHOD : http method를 나타낸다. ( 예 : get, post, put, patch, delete, ... )
  • PATH : 실제 서버에서 API를 사용하기 위한 경로를 나타낸다. ( 예 : users, posts, URL, ... )
  • HANDLER : 라우트가 일치할 때 실행되는 함수다.

 

'Javascript' 카테고리의 다른 글

[Javascript][Node.js] Request, Response  (0) 2024.08.30
[Javascript] API Client ( Insomnia API Client )  (0) 2024.08.30
[Javascript] Module  (0) 2024.08.29
[Javascript] Express.js 프레임 워크  (0) 2024.08.28
[Javascript] Node.js  (0) 2024.08.27

모듈 ( 출처 : hacks.mozilla.org )

 

모듈은 Javascript를 파일 단위로 분리된 코드 덩어리를 말한다.

모듈은 하나의 모듈에서 다른 모듈을 호출해 사용할 수 있다.

모듈은 대개 클래스 하나 혹은 특정한 목적을 가진 복수의 함수로 구성된 라이브러리 하나로 구성된다.

 

모듈의 필요성

  • 코드 베이스를 분리할 수 있고, 이를 통해 코드를 구조적으로 관리할 수 있다.
  • 코드를  재사용 가능하게 만들어준다. ( = 모듈화 )
  • 코드의 함수와 변수중 일부만 외부에서 사용하도록 노출시킬 수 있다. ( 즉, 모듈 내부의 코드 세부사항을 외부로 부터 은닉하는 정보은닉을 표현할 수 있다. )
  • 해당 모듈이 참조하고 있는 다른 모듈에 대한 종속성을 관리하는 역할을 담당한다.

 

CJS ( CommonJS )

Node.js 환경에서 기본적으로 사용되는 모듈 시스템이다.

설정을 따로 추가하지 않은 이상, Node.js에서는 CommonJS를 기본으로 사용한다.

require 함수를 사용하여 다른 모듈을 불러올 수 있다.

require 함수는 경로 혹은 문자열을 가지고 내부 알고리즘을 통해 모듈을 가져오고 종속성을 처리한다.

 

ESM ( ECMA Script Module )

최신 Javascript에서 지원하는 모듈 시스템이다.

모든 Javascript 환경에서 통합적인 인터페이스를 제공하기 위해 시작된 체계다.

CommonJS 와는 다르게 정적으로 모듈을 가져오며 비동기적 모듈 로딩과 순환 종속을 처리한다.

 


모듈의 사용법

모듈 사용법 ( 출처 : hacks.mozilla.org )

 

export 명령어를 변수나 함수 앞에 붙이면 외부 모듈에서 해당 변수나 함수에 접근할 수 있다. 

import, require 명령어를 사용해 외부 모듈의 기능을 가져올 수 있다.

 

 ● import는 ES6( ES2015 )로 모듈 시스템을 관리할 때 사용한다.

  • 이 방식은 정적 로딩을 지원한다.
  • import 문은 코드의 최상위에 위치해야 한다

 ● require는 CommonJS로 모듈시스템을 관리할 때 사용한다.

  • 이 방식은 동적 로딩을 지원한다.
  • require 문은 코드의 어디에서든 사용할 수 있다.

 

ES6 Module 사용

// 📁 sayHi.js
export function sayHi(user) {
  console.log(`Hello, ${user}!`);
}

 

export 지시자를 사용해 sayHi.js 내부의 함수 sayHi를 외부로 내보낸다.

 

// 📁 main.js
import {sayHi} from './sayHi.js';

console.log(sayHi); // function
sayHi('John'); // Hello, John!

 

import 지시자를 사용해 상대 경로 ( ./sayHi.js ) 기준으로 모듈을 가져오고 sayHi.js 에서 내보낸 함수 sayHi를 상응하는 변수에 할당한다.

 

상대 경로

import {sayHi} from './sayHi.js';

 

위 코드에서 ./sayHi는 파일 경로를 나타내는데, ./ 으로 시작하는 경로는 '상대 경로' 라는 것을 나타낸다.

여기서, '상대 경로'란 현재 파일의 위치에 따라 다르게 해석되는 파일 또는 디렉토리의 위치는 나타내는 방식이다.

즉, ./sayHi.js 는 현재 파일이 위치한 디렉토리에서 sayHi.js라는 이름의 파일을 찾는 것을 의미한다.

상위 디렉토리에서 파일을 찾으려면 ../ 을 이용하면 된다. 

즉, ../sayHi.js 라고 상대경로를 설정하면 현재 파일이 위치한 디렉토리의 상위 디렉토리에서 sayHi.js 를 찾는 것을 의미한다.

 

화살표 함수 export, import

/** 화살표 함수 export **/

// 모듈을 호출했을 때, addArrowFunction 키 값에는 addArrowFunction 변수 함수가 가지고 있는 값이 할당된다.
export const addArrowFunction = (a, b) => {
  return a + b;
}

 

/** 화살표 함수 import **/

import { addArrowFunction } from './math.js'

console.log(addArrowFunction(5, 3));

// Print: 8

 

'Javascript' 카테고리의 다른 글

[Javascript] API Client ( Insomnia API Client )  (0) 2024.08.30
[Javascript] API  (0) 2024.08.29
[Javascript] Express.js 프레임 워크  (0) 2024.08.28
[Javascript] Node.js  (0) 2024.08.27
[Javascript] 자료형  (0) 2024.08.24

웹 프레임 워크

 

출처 : https://blog.back4app.com/backend-frameworks/

 

웹 프레임 워크는 프로그래밍의 특정 부분을 추상화해서 개발자가 더 높은 수준에서 프로그램을 작성할 수 있게 도와주는 도구다. 프레임워크는 '틀'이라는 의미로, 개발하는 동안 준수해야하는 규칙과 구조를 제공하게 된다.

이미 만들어진 기능을 재사용하고, 이를 조립해서 웹 서비스를 만드는 것이다.


Express.js

Expree.js는 Node.js로 서버를 빠르고 간편하게 만들 수 있게 도와주는 가장 대표적인 웹 프레임워크다.

Expree.js의 가장 큰 특징 중 하나는 미들웨어를 지원하는 것이다.

미들웨어는 사용자의 요청과 응답 사이에 위치하며, 특정 기능을 수행하는 함수로 생각할 수 있다.

예를 들어 인증 ( Authentication ), 로깅 ( Logging ), 에러 처리 핸들러 ( Exception Handler ) 등을 담당하는 다양한 미들웨어를 사용할 수 있게 된다.

 

Express.js로 백엔드 서버 구현

yarn 패키지 매니저로 expree.js 프레임워크를 우선 설치해야한다.

yarn add express

 

터미널에서 위 명령어를 입력해 express.js 프레임워크를 설치한다.

package.json에 express 패키지가 기록되어 있는 모습

 

// app.js

import express from 'express';

const app = express();
const PORT = 3000;

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(PORT, () => {
  console.log(PORT, '포트로 서버가 열렸어요!');
});

 

app.js에 위 내용을 입력하고 터미널에서 node app.js 를 입력해 실행하면 서버가 열린다.

 

 

웹 브라우저 주소에 localhost:3000을 입력하면 위 그림 처럼 Hello World!가 출력된 것을 확인할 수 있다.

'Javascript' 카테고리의 다른 글

[Javascript] API  (0) 2024.08.29
[Javascript] Module  (0) 2024.08.29
[Javascript] Node.js  (0) 2024.08.27
[Javascript] 자료형  (0) 2024.08.24
[Javascript] 화살표함수  (0) 2024.08.22

Node.js 의 구조

 

Node.js는 "Javascript를 브라우저가 아닌 컴퓨터에서 브라우저 없이 실행하게 도와주는 환경"을 말한다.

이는 Core Library와 V8 Engine, 그리고 libuv라는 라이브러리를 통해 가능해진다.

 

V8 Engine은 구글이 개발하여 구글 크롬 브라우저에서 사용하는 Javascript Engine이다.

Node.js에서 이 Engine을 활용해서, 브라우저 환경 이외에서도 Javascript를 사용할 수 있게 되었다.

 

libuv는 Node.js가 비동기 I/O 작업을 수행할 수 있게 해주는 중요한 라이브러리다.

이 라이브러리 덕분에 Node.js는 논 블로킹 I/O 모델이라는 특징을 가지게 되었다.

 

이 두가지 주요 구성 요소인 V8 Engine과 libuv는 C와 C++ 언어로 작성되어 있어서, Node.js 사용자가 Javascript으로 작성하면 Node.js Bindings을 통해 c++로 변환되어 실행된다.

 

Node.js는 대표적으로 논 블로킹( Non-blocking ) I/O, 싱글 스레드, 이벤트 루프의 특성이 있다.

Node.js는 싱글 스레드로 동작하나, I/O 작업이 발생한 경우 이를 비동기적으로 처리해 여러 작업을 동시에 처리할 수 있게 한다.


호출 스택

콜스택, 이벤트 루프

 

Javascript는 코드를 실행하며 호출 스택 ( Call Stack )에 함수를 추가하고 함수가 완료되면 호출 스택에서 제거한다.

이는 비동기 작업에서 문제가 되는데, 특히 네트워크 요청과 같이 시간이 많이 걸리는 작업을 기다리는 동안

Javascript는 다른 어떠한 작업도 처리할 수 없게 된다. 이 문제를 해결하기 위해 Javascript는 이벤트 루프와 이벤트 큐를

사용하게 된다.

 

이벤트 루프

이벤트 루프

 

이벤트 루프는 여러 이벤트들과 같은 비동기 작업들을 모아서 관리하고, 어떤 순서대로 실행해야하는지 도와주는 도구다.

 - 이벤트 루프는 호출 스택과 이벤트 큐를 관찰하며, 호출 스택이 비어있고, 이벤트 큐에 작업이 있으면, 이벤트 큐의 작업을 호출 스택으로 이동하는 역할을 담당한다.

 - 이벤트 루프를 활용한다면, 자바스크립트는 시간이 오래 걸리는 작업을 이벤트 큐에 넣어 비동기적으로 처리하고, 그 동안 호출 스택에서 다른 작업들을 계속 처리할 수 있다.

 

이벤트 루프 동작 방식 코드로 살펴보기

function firstFunction() {
  console.log('firstFunction 입니다.');
  secondFunction();
}

function secondFunction() {
  // 2 초간 기다린다.
  setTimeout(function () {
    console.log('secondFunction 입니다.');
  }, 2000);
}

firstFunction();
console.log('전역 코드 실행 중!');

// print: firstFunction 입니다.
// print: 전역 코드 실행 중!
/** 2 초간 기다린다. **/
// print: secondFunction 입니다.

 

위 코드에서 firstFunction은 호출 스택에 추가되고, 실행되며 'firstFunction 입니다.'를 콘솔에 출력하고 secondFunction을 호출 한다. 그 다음 secondFunction은 호출 스택에 추가되고, setTimeout 함수를 실행한다.

setTimeout은 비동기 함수이므로, Javascript는 이 작업을 이벤트 큐에 넣고 secondFunction을 호출 스택에서 제거한다.

그 다음 firstFunction도 호출 스택에서 제거하고, '전역 코드 실행 중!'을 콘솔에 출력한다.

2초가 지난 후, 'secondFunction 입니다.'를 출력하는 작업이 이벤트 큐에서 호출 스택으로 이동하고 실행된다. 이때 호출 스택은 비어 있기 때문에 이벤트 루프가 이 작업을 호출 스택으로 이동시킬 수 있었다.

이처럼, 이벤트 루프와 이벤트 큐를 사용함으로써 Javascript는 비동기 작업을 처리할 수 있게 된다.

'Javascript' 카테고리의 다른 글

[Javascript] Module  (0) 2024.08.29
[Javascript] Express.js 프레임 워크  (0) 2024.08.28
[Javascript] 자료형  (0) 2024.08.24
[Javascript] 화살표함수  (0) 2024.08.22
[Javascript] 프로토타입 ( Prototype )  (0) 2024.08.22

자바스크립트에서 값은 항상 문자열이나 숫자형 같은 특정한 자료형에 속한다.

자바스크립트에는 8가지 기본 자료형이 있다.

 

숫자형

let n = 123;
n = 12.345;

 

숫자형은 정수 및 부동소수점 숫자를 나타낸다.

숫자형과 관련된 연산은 다양한데, 곱셉, 나눗셈, 덧셈, 뺄셈 등이 대표적이다.

숫자형엔 일반적인 숫자 외에 Infinity, -Infinity, NaN 같은 특수 숫자 값이 포함된다.

 

Infinity는 무한대를 나타낸다.

일반적으로 0으로 나누면 무한대를 얻을 수 있다.

console.log( 1 / 0 );
console.log( Infinity );

 

NaN은 계산 중 에러가 발생했다는 것을 나타내주는 값이다.

부정확하거나 정의되지 않은 수학 연산을 사용하면 계산 중 에러가 발생하는데, 이때 NaN이 반환된다.

console.log( "글자" / 2 ); // NaN

 

 

NaN은 웬만해선 바뀌지 않는다. NaN에 어떤 추가 연산을 해도 결국 NaN이 반환된다.


BigInt

자바스크립트에선 내부 표현 방식 때문에 (2^53 - 1)(9007199254740991) 보다 큰 값 또는

-(2^53-1) 보다 작은 정수는 숫자형을 사용해 나타낼 수 없다.

BigInt 형은 길이에 상관없이 정수를 나타낼 수 있다.

BigInt 형 값은 정수 리터럴 끝에 n을 붙이면 만들 수 잇다. 

 

// 끝에 'n'이 붙으면 BigInt형 자료입니다.
let bigInt = 1234567890123456789012345678901234567890n;

문자형

자바스크립트에선 문자열을 따옴표로 묶는다.

let str = "Hello";
let str2 = 'Single quotes are ok too';
let phrase = `can embed another ${str}`;

 

따옴표는 세 종류가 있다.

1. 큰따옴표 : "Hello"

2. 작은따옴표 : 'Hello'

3. 역 따옴표( 백틸, backtick ) : `Hello`

 

큰따옴표와 작은따옴표는 기본적인 값으로, 자바스크립트에서는 이 둘에 차이를 두지 않는다.

역 따옴표로 변수나 표현식을 감싼 후 ${...} 안에 넣어주면, 다음과 같이 원하는 변수나 표현식을 

문자열 중간에 손쉽게 넣을 수 있다.

 

let name = "John";

// 변수를 문자열 중간에 삽입
console.log( `Hello, ${name}!` ); // Hello, John!

// 표현식을 문자열 중간에 삽입
console.log( `the result is ${1 + 2}` ); // the result is 3

Boolean 형

boolean형은 ture와 false 두 가지 값밖에 없는 자료형 이다.

boolean형은 긍정이나 부정을 나타내는 값을 저장할 때 사용한다.

let nameFieldChecked = true; 
let ageFieldChecked = false;

null 값

null 값은 지금까지 소개한 자료형 중 어느 자료형에도 속하지 않는 값이다.

null 값은 오로지 null 값만 포함하는 별도의 자료형이다.

let age = null;

 

 

자바스크립트의 null은 다른 언어에서의 null과는 성격이 다르다.

다른 언어에서는 null을 존재하지 않는 객체에 대한 참조널 포인터를 나타낼 때 사용한다.

하지만 자바스크립트에서 null은 존재하지 않는 값, 비어 있는 값, 알 수 없는 값을 나타내는 데 사용한다.

 

위 예시를 들어 설명하자면 let age = null; 은 나이를 알 수 없거나 그 값이 비어있음을 보여준다. ( 해석의 영역 )


undefined 값

undefined 값도 null 값처럼 자신만의 자료형을 형성한다.

undefined는 값이 할당되지 않은 상태를 나타낼 때 사용한다.

변수는 선언했으나, 값을 할당하지 않았다면 해당 변수에 undefined가 자동으로 할당된다.

let age;

console.log(age); // 'undefined'가 출력됩니다.

 

변수에 undefined를 명시적으로 할당하는 것도 가능하다.

let age = 100;

// 값을 undefined로 바꿉니다.
age = undefined;

console.log(age); // "undefined"

 

하지만 이렇게 undefined를 직접 할당하는 것은 권장되지 않는다.

변수가 비어있거나 알 수 없는 상태라는 걸 나타낼 때는 null을 사용하는 것이 좋다.

undefined는 값이 할당되지 않은 변수의 초기값을 위해 예약어로 남겨두는 편이 낫다.


typeof 연산자

typeof 연산자는 인수의 자료형을 반환한다. 자료형에 따라 처리 방식을 다르게 하고 싶을 경우와

변수의 자료형을 빠르게 알아내고자 할 때 유용하다.

 

typeof 연산자는 두 가지 형태의 문법을 지원한다.

1. 연산자 : typeof x

2. 함수 : typeof(x)

 

typeof undefined // "undefined"

typeof 0 // "number"

typeof 10n // "bigint"

typeof true // "boolean"

typeof "foo" // "string"

typeof Symbol("id") // "symbol"

 

참고 : https://ko.javascript.info/types

 

자료형

 

ko.javascript.info

 

'Javascript' 카테고리의 다른 글

[Javascript] Express.js 프레임 워크  (0) 2024.08.28
[Javascript] Node.js  (0) 2024.08.27
[Javascript] 화살표함수  (0) 2024.08.22
[Javascript] 프로토타입 ( Prototype )  (0) 2024.08.22
[Javascript] Random - 난수 생성하기  (0) 2024.08.21

함수 표현식보다 단순하고 간결한 문법으로 함수를 만들 수 있는 방법이 있다.

 

바로 화살표 함수를 말하는데, 화살표 함수라는 이름은 문법의 생김새를 차용해 지어졌다.

let func = (arg1, arg2, ...argN) => expression

 

위처럼 코드를 작성하면 인자 arg1..argN을 받는 함수 func가 만들어지고,

함수 func는 화살표 우측의 표현식을 평가하고, 평가 결과를 반환한다.

 

let sum = (a, b) => a + b;

/* 
위 화살표 함수는 아래 함수의 축약 버전이다.
let sum = function(a, b) {
  return a + b;
};
*/

console.log( sum(1, 2) ); // 3

 

위처럼 ( a, b ) => a + b는 인수 a와 b를 받는 함수다.

( a, b ) => a + b 는 실행되는 순간 표현식 a + b를 평가하고 그 결과를 반환한다.

 

※ 인수가 하나밖에 없으면 인수를 감싸는 괄호를 생략할 수 있다

let double = n => n * 2;
// let double = function(n) { return n * 2 }과 동일하다.

console.log( double(3) ); // 6

 

 

※ 인수가 하나도 없을 경우 괄호를 비워놓으면 된다. 다만, 이 때 괄호는 생략할 수 없다.

let sayHi = () => console.log("안녕하세요!");

sayHi();

 

 

화살표 함수는 함수 표현식과 같은 방법으로 사용할 수 있다.

let age = prompt("나이를 알려주세요.", 18);

let welcome = (age < 18) ?
  () => console.log('안녕') :
  () => console.log("안녕하세요!");

welcome();

 

위처럼 함수를 동적으로 만들 수도 있다.

'Javascript' 카테고리의 다른 글

[Javascript] Node.js  (0) 2024.08.27
[Javascript] 자료형  (0) 2024.08.24
[Javascript] 프로토타입 ( Prototype )  (0) 2024.08.22
[Javascript] Random - 난수 생성하기  (0) 2024.08.21
[Javascript] Map  (0) 2024.08.19

prototype 프로퍼티는 자바스크립트 내부에서 광범위하게 사용된다.

모든 내장 생성자 함수에서 prototype 프로퍼티를 사용한다.


Object.prototype

빈 객체를 생성해보자.

let obj = {};
alert( obj ); // "[object Object]" ?

 

"[Object Object]" 문자열을 생성하는 코드는 어디에 있는걸까?

obj는 비어 있는데 말이다.

obj = new Object()를 줄이면 obj = {} 가 된다.

여기서 Object는 내장 객체 생성자 함수인데, 이 생성자 함수의 prototype은 toString을 비롯한 다양한 메서드가 구현되어 있는 거대한 객체를 참조한다.

Object의 prototype이 Object.prototype을 참조하는 그림

 

 

new Object()를 호출하면 새롭게 생성된 객체의 Prototype 은 Object.prototype을 참조한다.

new Object()를 사용해 생성된 객체의 Prototype이 Object.prototype을 참조하는 그림

 

 

따라서 obj.toString()을 호출하면 Object.prototype에서 해당 메서드를 가져오게 된다.

예시를 통해 확인해 보자.

let obj = {};

console.log(obj.__proto__ === Object.prototype); // true

console.log(obj.toString === obj.__proto__.toString); //true
console.log(obj.toString === Object.prototype.toString); //true

 

다양한 내장 객체의 프로토타입

Array, Date, Function을 비롯한 내장 객체들 역시 프로토타입에 메서드를 저장해 놓는다.

배열 [1, 2, 3]을 만들면 new Array() 의 디폴트 생성자가 내부에서 동작하여 Array.prototype이 배열 [1, 2, 3]의 프로토타입이 되고 개발자는 Array.prototype을 통해 배열 메서드를 사용할 수 있다.

 

명세서에선 모든 내장 프로토타입의 상속 트리 꼭대기엔 Object.prototype이 있어야 한다고 규정한다.

세 내장 객체를 이용해 지금까지 설명한 내용을 그려보면 다음과 같다.

 

 

이번엔 코드로 각 내장 객체의 프로토타입을 직접 확인해 보자.

let arr = [1, 2, 3];

// arr은 Array.prototype을 상속받았나요?
console.log( arr.__proto__ === Array.prototype ); // true

// arr은 Object.prototype을 상속받았나요?
console.log( arr.__proto__.__proto__ === Object.prototype ); // true

// 체인 맨 위엔 null이 있습니다.
console.log( arr.__proto__.__proto__.__proto__ ); // null

 

 

체인 상의 프로토타입엔 중복 메서드가 있을 수 있다.

Array.prototype엔 요소 사이에 쉼표를 넣어 요소 전체를 합친 문자열을 반환하는 자체 메서드 toString이 있다.

let arr = [1, 2, 3]
console.log(arr); // 1,2,3 <-- Array.prototype.toString의 결과

 

 

그런데 Object.prototype에도 메서드 toString이 있다. 이렇게 중복 메서드가 있을 때는 체인 상에서 가까운 곳에 있는 메서드가 사용된다. Array.prototype 이 체인 상에서 더 가깝기 때문에 예시에서는 Array.prototype의 toString이 사용된다.

 

 

Chrome 개발자 콘솔과 같은 도구를 사용해 console.dir를 사용하면 내장 객체의 상속 관계를 확인할 수 있다.

 

 

배열이 아닌 다른 내장 객체들 또한 같은 방법으로 동작한다. 

함수도 마찬가지며 call, apply를 비롯한 함수에서 사용할 수 있는 메서드는 Function.prototype에서 받아온다.

function f() {}

console.log(f.__proto__ == Function.prototype); // true
console.log(f.__proto__.__proto__ == Object.prototype); // true, 객체에서 상속받음

 

'Javascript' 카테고리의 다른 글

[Javascript] 자료형  (0) 2024.08.24
[Javascript] 화살표함수  (0) 2024.08.22
[Javascript] Random - 난수 생성하기  (0) 2024.08.21
[Javascript] Map  (0) 2024.08.19
[Javascript] 소수 올림, 내림, 반올림  (0) 2024.08.19

클래스는 객체를 생성하기 위한 템플릿으로 생각하면 된다.

클래스를 생성하기 위해서는 class 키워드를 사용한다.


기본 문법

class MyClass {
  // 여러 메서드를 정의할 수 있음
  constructor() { ... }
  method1() { ... }
  method2() { ... }
  method3() { ... }
  ...
}

 

위처럼 클래스를 만들고 new Myclass()를 호출하면 객체가 생성된다.

 

constructor()는 생성자로 new에 의해 자동으로 호출되고, 객체의 기본 상태를 설정해준다.

 

class User {
  constructor(name) {
    this.name = name;
  }

  sayHi() {
    console.log("안녕하세요");
  }
}

// 사용법:
let user = new User("Yam");
user.sayHi();

 

위처럼 new User("Yam")를 호출하면, 새로운 객체가 생성되고,

넘겨받은 매개변수와 함께 constructor가 자동으로 실행된다.

 

자바스크립트에서 클래스는 함수의 한 종류로 취급한다.

class User {
  constructor(name) { this.name = name; }
  sayHi() { console.log(this.name); }
}

// User가 함수라는 증거
console.log(typeof User); // function

 

class User 문법 구조가 하는일은 다음과 같다.

1. User라는 이름을 가진 함수를 만들고, 함수 본문은 constructor에서 가져온다.

    constructor가 없으면 본문이 비워진 채로 함수가 만들어진다.

2. sayHi와 같은 메서드를 User.prototype에 저장한다.

 

new User를 호출해 객체를 만들고, 객체의 메서드를 호출하면 메서드를 prototype 프로퍼티를 통해 가져온다.

이 과정이 있어서 객체에서 메서드에 접근할 수 있다.

 

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// 클래스는 함수다.
console.log(typeof User); // function

// 정확히는 생성자 메서드와 동일하다.
console.log(User === User.prototype.constructor); // true

// 클래스 내부에서 정의한 메서드는 User.prototype에 저장된다.
console.log(User.prototype.sayHi); // console.log(this.name);

// 현재 프로토타입에는 메서드가 두 개다.
console.log(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi

 

 

class라는 키워드 없이도 클래스 역할을 하는 함수를 선언할 수 있다.

 

// class User와 동일한 기능을 하는 순수 함수를 만들어보자.

// 1. 생성자 함수를 만든다.
function User(name) {
  this.name = name;
}

// 모든 함수의 프로토타입은 'constructor' 프로퍼티를 기본으로 갖고 있기 때문에
// constructor 프로퍼티를 명시적으로 만들 필요가 없다.

// 2. prototype에 메서드를 추가한다.
User.prototype.sayHi = function() {
  console.log(this.name);
};

// 사용법:
let user = new User("John");
user.sayHi();

 

위 처럼 순수 함수로 클래스 역할을 하는 함수를 선언하는 방법과 class 키워드를 사용하는 방법의 결과는 거의 같다.

 

이 두 방법에는 중요한 차이가 몇가지 있다.

1. class로 만든 함수엔 특수 내부 프로퍼티인 IsClassConstructor : true 가 이름표처럼 붙는다.

    이것만으로도 두 방법엔 분명한 차이가 있음을 알 수 있다.

 

class User {
  constructor() {}
}

console.log(typeof User); // User의 타입은 함수이긴 하지만 그냥 호출할 수 없다
User(); // TypeError: Class constructor User cannot be invoked without 'new'

 

자바스크립트는 다양한 경우 IsClassConstructor : true를 활용한다.

클래스 생성자를 new와 함께 호출하지 않으면 에러가 발생하는데 이 때 IsClassConstructor : true 가 사용된다.

 

또 다른 차이점으로는

2. 클래스에 정의된 메서드는 열거할 수 없다.

    클래스의 prototype 프로퍼티에 추가된 메서드의 enumerable 플래그는 false 이기 때문.

    for in 으로 객체를 순회할 때, 메서드는 순회 대상에서 제외하고자 하는 경우가 많아 이 특징은 꽤 유용하다.

 

3. 클래스는 항상 엄격 모드로 실행된다. 클래스 생성자 안 코드 전체에 자동으로 엄격 모드가 적용된다.


클래스 표현식

함수처럼 클래스도 다른 표현식 내부에서 정의, 전달, 반환, 할당할 수 있다.

 

클래스 표현식을 만들어보자.

let User = class {
  sayHi() {
    console.log("안녕하세요.");
  }
};

 

 

기명 함수 표현식과 유사하게 클래스 표현식에도 이름을 붙일 수 있다.

클래스 표현식에 이름을 붙이면, 이 이름은 오직 클래스 내부에서만 사용할 수 있다.

// 기명 클래스 표현식(Named Class Expression)
// (명세서엔 없는 용어이지만, 기명 함수 표현식과 유사하게 동작한다.)
let User = class MyClass {
  sayHi() {
    console.log(MyClass); // MyClass라는 이름은 오직 클래스 안에서만 사용할 수 있다.
  }
};

new User().sayHi(); // 원하는대로 MyClass의 정의를 보여준다.

console.log(MyClass); // ReferenceError: MyClass is not defined, MyClass는 클래스 밖에서 사용할 수 없다.

getter와 setter

클래스는 getter와 setter를 지원한다.

get과 set을 이용해 user.name을 조작해보자!

class User {

  constructor(name) {
    // setter를 활성화합니다.
    this.name = name;
  }

  get name() {
    return this._name;
  }

  set name(value) {
    if (value.length < 4) {
      console.log("이름이 너무 짧습니다.");
      return;
    }
    this._name = value;
  }

}

let user = new User("성원");
console.log(user.name); // 성원

user = new User(""); // 이름이 너무 짧습니다.

 

참고로 getter와 setter는 User.prototype에 정의된다.


클래스 필드

클래스 필드라는 문법을 사용하면 어떤 종류의 프로퍼티도 클래스에 추가할 수 있다.

클래스 User에 name 프로퍼티를 추가해보자.

class User {
  name = "성원";

  sayHi() {
    console.log(`${this.name}님 안녕하세요!`);
  }
}

new User().sayHi(); // 성원님 안녕하세요!

 

 

클래스를 정의할 때 <프로퍼티 이름> = <값> 을 써주면 간단히 클래스 필드를 만들 수 있다.

클래스 필드의 중요한 특징 중 하나는 User.prototype이 아닌 개별 객체에만 클래스 필드가 설정된다는 점이다.

class User {
  name = "성원";
}

let user = new User();
console.log(user.name); // 성원
console.log(User.prototype.name); // undefined

 

 

 

 

참고 : https://ko.javascript.info/class

 

클래스와 기본 문법

 

ko.javascript.info

 

Array ( 배열 ) 에서 최대값과 최소값을 구하는 방법을 알아보자.

 

Math.max(), Math.min() 

let maxValue = Math.max(1, 2, 3, 4, 5);
let minValue = Math.min(1, 2, 3, 4, 5);

console.log(maxValue); // 5
console.log(minValue); // 1

 

Math.max() 함수는 입력받은 수 중 최대값을 구해서 반환해주는 함수다.

Math.min() 함수는 입력받은 수 중 최소값을 구해서 반환해주는 함수다.

 

위 함수들을 사용해 배열의 최대값과 최소값을 구하기 위해서는 

배열의 내용들을 꺼내 함수로 전달해주는 작업이 필요하다.

 

Spread Operator( 전개 연산자 )를 이용하면 배열의 내용들을 꺼내 함수로 전달할 수 있다.

let arr = [1, 2, 3, 4, 5];
let maxValue = Math.max(...arr);
let minValue = Math.min(...arr);

console.log(maxValue); // 5
console.log(minValue); // 1

 

 

 

Math.random()

 위 함수는 0 ~ 1 구간에서 부동소수점의 난수를 생성한다.

let rand1 = Math.random();
let rand2 = Math.random();

console.log(rand1);
console.log(rand2);

 

 

범위를 지정한 난수 생성

 정수인 난수를 생성하기 위해서는 Math.random() 함수와 Math.floor() 함수를 사용해 생성한다.

 Math.floor() 함수는 소수점 1번째 자리를 버려서 정수를 반환해주는 함수다.

let rand = Math.floor(Math.random());
console.log(rand); // 0

let rand2 = Math.floor(Math.random() * 10);
console.log(rand2); // 0 ~ 9

let rand3 = Math.floor(Math.random() * 11);
console.log(rand3); // 0 ~ 10

let rand4 = Math.floor(Math.random() * 100);
console.log(rand4); // 0 ~ 99

let rand5 = Math.floor(Math.random() * 10 ) + 1;
console.log(rand5); // 1 ~ 10

 

min 이상 max 이하 범위 안에서 랜덤하게 수 반환

function rand(min, max){
	return Math.floor(Math.random() * (max - min)) + min;
}

 

  

'Javascript' 카테고리의 다른 글

[Javascript] 화살표함수  (0) 2024.08.22
[Javascript] 프로토타입 ( Prototype )  (0) 2024.08.22
[Javascript] Map  (0) 2024.08.19
[Javascript] 소수 올림, 내림, 반올림  (0) 2024.08.19
[Javascript] this  (0) 2024.08.14

+ Recent posts