Class,상속,express,.virtual,.exec ------------------------------ 내림차순 ↑

김민준·2023년 6월 21일
0
# 목차

class 란?
매서드
생성자
this
상속
express를 써야하는 이유
과제 진행
.virtual
.exec
naming convention

참조 사이트

Class 란?

현실과 비슷한 개념(객체)을 나타내기 위한 도구.
한 번 정의하면 필요할 때 마다 해당 클래스로 동일한 틀을 가진 객체(Instance)를 만들 수 있다.

class User { 
}

const user = new User();
user.name = "이용우";
user.age = 28;
user.tech = "Node.js";

console.log(user.name); // 이용우
console.log(user.age); // 28
console.log(user.tech); // Node.js

매서드

함수 내부의 프로퍼티로 묶여있는 함수

생성자

클래스 내부에서 construcor()로 정의한 메서드

this

현재 실행 컨텍스트에서 참조되는 객체. class가 아니라 class로 정의되는 개체.

class User {
  constructor(name, age, tech) { // User 클래스의 생성자
    this.name = name;
    this.age = age;
    this.tech = tech;
  }

  getName() { return this.name; } // getName 메서드
  getAge() { return this.age; }.  // getAge 메서드
  getTech() { return this.tech; } // getTech 메서드
}

const user = new User("이용우", "28", "Node.js"); // user 인스턴스 생성
console.log(user.getName()); // 이용우
console.log(user.getAge()); // 28
console.log(user.getTech()); // Node.js

상속

일반적으로 클래스의 인스턴스는 선언한 클래스의 기능을 모두 상속한다. = 가진다.
클래스의 경우도 마찬가지이다, 자식 클래스는 부모 클래스의 매서드, 내부 변수등을 상속받는다.
super 키워드를 호출 / 참조 하면 각각 부모 클래스의 생성자 constructor / 메서드 method 를 호출 할 수 있다.

class User { // User 부모 클래스
  constructor(name, age, tech) { // 부모 클래스 생성자
    this.name = name;
    this.age = age;
    this.tech = tech;
  }
  getTech(){ return this.tech; } // 부모 클래스 getTech 메서드
}

class Employee extends User{ // Employee 자식 클래스
  constructor(name, age, tech) { // 자식 클래스 생성자
//   ↓부모클래스의 생성자를 호출한다.
    super(name, age, tech);
  }
}

//             자식클래스로 ↓     ↓인자들이 들어간다.
const employee = new Employee("이용우", "28", "Node.js");
console.log(employee.name); // 이용우
console.log(employee.age); // 28
console.log(employee.getTech()); // 부모 클래스의 getTech 메서드 호출: Node.js

Express를 써야하는 이유

http를 이용하는 것보다 생산성이 더 좋기 때문이다.

//  http로 구현하기
const http = require('http');

// 서버 객체를 생성합니다.

http.createServer(function (req, res) {
  res.write('Hello World!'); // 클라이언트에게 전달할 응답을 작성합니다.
  res.end(); // 클라이언트에게 응답을 전달합니다.
}).listen(8080); // 서버를 8080포트로 실행합니다.
//  express로 구현하기

const app = require("express")(); // express의 app객체를 가져옵니다.

app.listen(8080,()=> {}); // 서버를 8080포트로 실행합니다.

과제 진행

할일 목록을 만들고, 수정할 수 있는 사이트를 만들자, 로그인 기능도 추가

내 프로젝트 폴더 이름
├── app.js
├── assets
│   ├── asset-manifest.json
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   ├── robots.txt
│   └── static
│       ├── css
│       │   ├── main.6842b365.chunk.css
│       │   └── main.6842b365.chunk.css.map
│       └── js
│           ├── 2.96129310.chunk.js
│           ├── 2.96129310.chunk.js.LICENSE.txt
│           ├── 2.96129310.chunk.js.map
│           ├── 3.0962e34f.chunk.js
│           ├── 3.0962e34f.chunk.js.map
│           ├── main.c5ceafa0.chunk.js
│           ├── main.c5ceafa0.chunk.js.map
│           ├── runtime-main.2ec3457b.js
│           └── runtime-main.2ec3457b.js.map
├── models
│   ├── index.js
│   └── todo.js
├── routes
│   └── todos.router.js
├── package-lock.json
└── package.json
// index.js

const mongoose = require("mongoose");

//                  로컬호스트 포트 번호 ↓
mongoose.connect("mongodb://localhost:27017/todo-demo", {
  useNewUrlParser: true, //              DB 이름 ↑
  useUnifiedTopology: true,
})
  .then(value => console.log("MongoDB 연결에 성공하였습니다."))
  .catch(reason => console.log("MongoDB 연결에 실패하였습니다."))


const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));

module.exports = db;
// todos.js
const mongoose = require("mongoose");

// 스키마 생성
const TodoSchema = new mongoose.Schema({
  value: String,
  doneAt: Date,
  order: Number
  // ↑ 저장 된 항목을 정렬하기 위해서 추가한 값.
});

TodoSchema
  //.virtual 은 mongoDB 에 저장되는 않는 속성이다.
  .virtual("todoId")
  .get(function () {
    return this._id.toHexString();
    //           ↑ todoId
  });

TodoSchema.set("toJSON", { virtuals: true, });

module.exports = mongoose.model("Todo", TodoSchema);
// ./routes/todos.rourte.js
const express = require("express");
const router = express.Router();

const Todo = require("../models/todos");

router.get("/", (req, res) => {
    res.send("Hi!");
});

//     추가하는 API
router.post("/todos", async (req, res) => {
    const { value } = req.body;  //         mongoose 3버전 이전에 ↓ 쿼리를 프로미스 로 만들기 위해 사용하던 것.
    const maxOrderByUserId = await Todo.findOne().sort("-order").exec(); // 4버전 이후로는 불필요하나 가독성과 일관성을 위해 사용한다.

//                                  저장된 값이 없으면 order = 1, 아니면 갯수+1 로 설정 
    const order = maxOrderByUserId ? maxOrderByUserId.order + 1 : 1;
    const todo = new Todo({ value, order });
    await todo.save();

    res.send({ todo }); // 마지막이어서 return 이 생략되었다.
});

//     가져오는 API
router.get("/todos", async (req, res) => {
    const todos = await Todo.find().sort("-order").exec();

    res.send({ todos });
});

//      순서를 바꾸는 API
// order 의 값을 교환해서 순서를 바꾼다.
router.patch("/todos/:todoId", async (req, res) => {
    const { todoId } = req.params;
    const { order, value, done } = req.body;

    const currentTodo = await Todo.findById(todoId).exec();
    if (!currentTodo) {
        throw new Error("존재하지 않는 todo 데이터입니다.");
    }

    if (order) {
        const targetTodo = await Todo.findOne({ order }).exec();
        if (targetTodo) {
            // 목표물에 현재 order 값을 넣고 저장한다.
            targetTodo.order = currentTodo.order;
            await targetTodo.save();
        }
        // 현재 데이터에     order 값을 넣는다.
        currentTodo.order = order;
    } else if (value) {
        currentTodo.value = value;
    } else if (done !== undefined) {
        currentTodo.doneAt = done ? new Date() : null;
    }

    await currentTodo.save();

    res.send({});
});

router.delete("/todos/:todoId", async (req, res) => {
    const { todoId } = req.params;

    const todo = await Todo.findById(todoId).exec();
    await todo.delete();

    res.send({});
});

module.exports = router;

.virtual

mongoDB 에 저장되지 않고, 기존의 Column을 이용해 가상의 column을 만든다. get/set 펑션을 정의하며, DB에 저장 되지 않기 때문에 쿼리로 조회할 수 없다.

대해 자세한 건 아래 참조
1. / 2. / 3. / 4.

.exec

몽구스 3버전 이전에 프로미스를 정의하기 위해 사용하던 기능이다. 4버전 이후로는 필요가 없지만 사용이 권장된다. 왜냐하면, 쿼리를 정의하기 위한 객체를 만든 시점과 저장, 복사, 전달 하는 시점이 다를 수 있기 때문이다. 그렇기 때문에 저장과 동시에 날리지 않기 위해 사용한다.

naming convention

변수의 이름을 짓는 방법, 언어의 특성과 환경에 따라 다르다.
C와 파이썬의 경우 naming_style
node.js 의 경우 camelCase 를 사용한다.
만약 파이썬에서 naming-style 이라고 이름을 짓는다면 뺄셈으로 인식할 것이다.

참조 사이트

벨로그 문법 정리
벨로그 코드 블럭
express.listen
.virtual 1. / 2. / 3. / 4.
.exec

profile
node 개발자

0개의 댓글

관련 채용 정보