[TIL] JS 개념 + React 강의

JISU·2021년 11월 22일
0

TIL

목록 보기
2/27

일기


오늘 배운 것

React 개념

useCallback

엘리

memo

엘리

MVC 패턴 / 컴포넌트 역할 분리

엘리

react-router

일반적으로 routing은 네트워크에 있는 path를 선택하는 프로세스라고 한다.

네트워크에서 특정 url을 이용했을 때 어떤 경로를 이용해서 데이터를 받아올 것인지를 결정해주는 것이다.

routing을 좀더 쉽게

웹에서는, routing은 http 요청을 어떤 페이지로 연결할 것인지를 연결하는 메커니즘.

router는 사용자가 어떤 요청을 했을 때 어떤 페이지를 띄워줄 것인지를 결정해주는 친구이다.

SPA에서 routing
spa는 하나의 url로 (html 로) 다른 페이지를 띄우는 것이 아니라, 부분적으로 변경하면서 컴포넌트를 바꿔주어서 페이지가 깜빡거리지 않고도 페이지 내용을 동적으로 바꿔주는 application이다.

근데 여기서 문제가 생긴다. spa에서는 html이 하나이므로 url이 그냥 하나인 것이다.
따라서 다른 페이지(페이지가 아니라 다른 화면)을 북마크 할 수도 없고 바로 접근할 수 조차 없다.

그런데 이런 것들을 개선하고 가능하게 해주는 라이브러리가 react-router 이다.

redux

스파르타 강의

Javascript 개념

prototype

  1. prototype의 개념

Javascript는 클래스라는 개념이 없다. 기존의 객체를 복사하여 새로운 객체를 생성하는 프로토타입 기반의 언어(prototype-based language)이다. 프로토타입 기반 언어는 객체 원형인 프로토타입을 이용하여 새로운 객체를 만들어낸다. 생성된 객체 또한 다른 객체의 원형이 될 수 있다.
프로토타입은 객체를 확장하고, 객체 지향적인 프로그래밍을 할 수 있도록 해준다.

왜냐면, 객체를 상속하므로써 코드의 재사용성을 높여야 하는데 class 개념이 없으니까! 따라서 속성들을 상속받기 위한 템플릿으로써 프로토타입 객체(prototype object)를 가진다는 것.

그래서 prototype이 뭐냐.
객체가 만들어지기 위해서는 자신을 만드는 데 사용된 원형인 프로토타입 객체를 이용해서 만듭니다.
이 때, 만들어진 객체 안에 __proto__라는 링크가 있는데, 그 링크를 프로토타입이라고 정의한다.

그럼 __proto__는 뭔데?
자신(객체)를 만들어낸 원형과 연결된 속성

그니까, 객체 원형에 prototype이 들어있고, 그건 원형을 가지고 만든 객체들이랑 연결되는 속성.
그리고 그 만들어진 객체에 __proto__가 들어있고, 그것이 자신을 만든 원형과 연결된 속성이다 라는 것.

[참고] https://velog.io/@wmc1415/Javascript-Prototype%EC%9D%B4%EB%9E%80

  1. prototype 사용법 및 예제

1) 객체 속성과 prototype chaining

  • hasOwnProperty를 이용한 속성 존재 여부 확인
const user = {
  name: "Mike",
}

console.log(user.name) // Mike
// hasOwnProperty: 속성이 있는지 확인하는 함수
console.log(user.hasOwnProperty("name")) // true
console.log(user.hasOwnProperty("age")) // false

hasOwnProperty는 객체 안에 해당하는 속성이 있는지 없는지를 알아보고 boolean 값으로 반환해주는 함수이다.
따라서 당연히 위와 같이 나온다.

그런데 user 객체 안에는 hasOwnProperty라는 함수를 선언해준 적이 없는데,
어떻게 사용 가능한 것일까? 이것이 바로 prototype
user를 만든 객체 원형(Object)의 속성에 hasOwnProperty라는 함수가 내장되어 있기 때문에 객체 원형으로 만들어진 user에서도 상속받아서 사용할 수 있는 것.

  • 만들어진 객체에 원형에 있는 속성을 추가하면?
    만약 만들어진 객체(user)에 원형(Object) 프로토타입에 있는 속성을 추가하면 어떻게 될까?
const user = {
  name: "Mike",
  hasOwnProperty: function () {
    return "난 몰라, 상위에 가서 물어봐야함"
  },
}
console.log(user.hasOwnProperty("name")) // 난 몰라, 상위에 가서 물어봐야함
console.log(user.hasOwnProperty("age")) // 난 몰라, 상위에 가서 물어봐야함

먼저 user에 hasOwnProperty를 찾아보고, 없으면 __proto__에서 찾는다.
이러한 탐색을 prototype chaining이라고 한다.

따라서 만약 user에 hasOwnProperty 있으면 그것을 먼저 실행하게 된다.

2) 프로토타입 기반 언어인 Javascript에서의 상속
어쨌든 코드의 재사용성을 높이려면 상속이 필요하고, javascript에서는 프로토타입을 이용해서 이렇게 상속을 구현한다는 것.

  • 냅다 그냥 다 써주기
const bmw = {
  color: "red",
  wheels: 4,
  navigation: 1,
  drive() {
    console.log("drive..!!")
  },
}

const benz = {
  color: "black",
  wheels: 4,
  drive() {
    console.log("drive..!!")
  },
}

const audi = {
  color: "blue",
  wheels: 4,
  drive() {
    console.log("drive..!!")
  },
}

길다.. 중복되는 코드들도 많고, 그래서 공통되는 요소들을 묶어서 prototype에 속성으로 넣어주려고 한다.

  • 원형에다가 속성 넣기
// 먼저 proto가 될 객체를 선언한다.
const car = {
  wheels: 4,
  drive() {
    console.log("drive..!!")
  },
}

const bmw = {
  color: "red",
  navigation: 1,
}

const benz = {
  color: "black",
}

const audi = {
  color: "blue",
}

// 위의 세 객체를 car의 prototype이 되도록 한다.
// car의 상속을 받도록
bmw.__proto__ = car
benz.__proto__ = car
audi.__proto__ = car

console.log(bmw.wheels) // 4

먼저, 원형이 될 객체를 선언해서 그 안에 공통적으로 들어가는 속성을 넣어준다.
그러고 밑에 선언했던 객체들의 proto로 만든 원형(car)를 넣어주어서
car의 속성을 bmw, benz, audi 들이 상속받을 수 있도록 한다.

  • 상속 또 만듦 (이번엔 bmw가 x5의 prototype이 되도록 해보자.)
    위의 코드에 이어서,
const x5 = {
  color: "white",
  name: "x5",
}

x5.__proto__ = bmw

console.log(x5.name) // name은 x5에 있으므로 잘 나온다.
console.log(x5.color) // color는 bmw에도 있지만 x5에 있으니 x5에 있는 color를 나타내준다.
console.log(x5.wheels) // wheels는 x5에도 bmw에도 없으나 car에 있으므로 잘 나온다.

3) proeprty 순회

for (p in x5) {
  console.log(p) // name, color, navigation, wheel, drive
}
console.log(x5) // name, color

prototype의 속성까지 모든 속성 다나옴
하지만 객체를 console에 찍어보면 그 객체가 가진 속성만 나온다.

4) 우리가 사용하고 있던 prototype

let array = new Array(4, 2, 1)
console.log(array.sort())
console.log(Array.prototype) // Array의 prototype을 모두 볼 수 있다.

우리는 sort라는 함수를 array안에 따로 만든 적이 없다.
하지만 사용이 가능한 것이 array의 원형(Array)에 sort()라는 함수가 내장되어 있기 때문에 사용 가능 했던 것이다.

5) 원형의 prototype으로 속성 추가하기 (ft. 생성자)
bmw.__proto__ = car
benz.__proto__ = car
audi.__proto__ = car
이렇게 하나하나씩 객체 생성할 때마다 프로토타입을 설정해주면 완전 귀찮다.

그래서 생성자를 이용해서 이렇게 구현해본다.

const Bmw = function (color) {
  this.color = color
}

const x5 = new Bmw("red")
const z4 = new Bmw("blue")

Bmw.prototype.wheels = 4
Bmw.prototype.drive = function () {
  console.log("drive..!!")
}
Bmw.prototype.navigation = 1
Bmw.prototype.stop = function () {
  console.log("stop!")
}

console.log(z4.wheels) // 4 // wheels 속성을 확인할 수 있다

이번엔 이렇게 Bmw (원형)에다가 prototype에 속성들을 추가해주므로써 원형 객체만 수정하면 모든 만들어진 하위 객체들에 바로 적용이 되도록 사용한다.

6) instance와 constructor
instance(인스턴스)란?

생성자를 이용해서 객체가 생성될 때,
그 객체를 생성자의 instance라고 한다.

거의 객체와 같은 개념으로 봐도 무방하다고 한다. (왜냐면, 자바스크립트에서는 primitive type을 제외한 모든 타입은 다 객체 타입이므로.. 함수도 마찬가지)

constructor(생성자)란?

constructor(생성자)란 인스턴스 객체를 생성한 생성자의 정보이다.

인스턴스 및 생성자 확인

  • 원형의 prototype에 하나하나씩 속성을 추가했을 때
    위의 코드에 이어서
console.log(z4 instanceof Bmw) // true
console.log(z4.constructor === Bmw) // true

따라서, z4가 Bmw의 instance인지 확인했을 때 true, z4의 constructor(생성자)가 Bmw인지 확인했을 때 또한 true가 나오게 된다.

  • 프로토타입 속성 한꺼번에 설정했을 때
Bmw.prototype = {
  wheels: 4,
  drive: function () {
    console.log("drive..!!")
  },
  navigation: 1,
  stop: function () {
    console.log("stop!")
  },
}
// 하지만 이렇게 하면 constructor는 사라진다.
console.log(z4.constructor === Bmw) // false

위에 처럼 하나하나 쓰기 싫으면 묶어서 이렇게 써도 되지만, 대신 constructor가 사라진다.

  • constuctor 명시
Bmw.prototype = {
  construcor: Bmw,
  wheels: 4,
  drive: function () {
    console.log("drive..!!")
  },
  navigation: 1,
  stop: function () {
    console.log("stop!")
  },
}

따라서, 이렇게 작성할 때에는 constructor를 명시해주는 것이 좋다.

7) 클로저를 활용한 prototype 속성 위험성 방지

const Bmw = function (color) {
  this.color = color
}

const z4 = new Bmw("blue")

console.log(z4.color) // blue
z4.color = "weird" // 이렇게 아무나 색을 바꿀 수 있으면 안되지 않을까?
console.log(z4.color) // weird

const Bmw = function (color) {
  const c = color
  this.getColor = function () {
    return c
  }
}

const x5 = new Bmw("red")
console.log(x5.getColor()) // red
x5.color = "weird" // color라는 속성이 따로 없으므로 바꿀 수 없으나 값은 확인할 수 있다

생성자에 있는 속성들도 임의로 바꾸어서는 안되는 데이터들이 있을 것이다.
따라서 클로저를 활용하여 데이터를 보호할 수 있다.
Bmw에 color를 인자로 받아서, const에 저장한 후 그 변수를 return 해줌으로써 const c에 저장된 color가 있으므로 밖의 스코프에서 데이터를 확인할 수 있지만, 생성된 객체에 직접 color를 변경할 수 없게 된다.

[참고 및 출처] https://www.youtube.com/watch?v=wUgmzvExL_E&t=1
[참고 및 출처] https://www.youtube.com/watch?v=ddJcDZHBRm0

profile
블로그 이전

0개의 댓글