Js 클래스

심채운·2022년 7월 17일
0

JavaScript

목록 보기
5/14

생성자 함수(prototype)

생성자 함수(Prototype) - 객체 생성
생성자의 의의는 재사용할 수 있는 객체 생성 코드 구현하기 위함이다.
같은 로직이면
.prototype으로 객체 생성이 가능하다.
객체 데이터 안에있는 속성(property), 메소드들을 통틀어서 맴버(Member)라고 부른다.
특정한 기호만을 가지고 어떤 데이터를 만드는것을 우린 리터럴이라고 부른다. {}, "", []
new라는 키워드를 통해서 생성자 함수로 실행한 결과를 반환해서 할당된 그 변수를 생성자 함수의 "인스턴스"라고 부르고, 생성자 함수는 일반 함수와 구분하기 위해 첫번째 문자를 대문자로 쓴다. ex) new라는 키워드로 User()라는 생성자 함수.

//원래 객체 생성할때
const Sim = {
  firstName : 'Sim',
  lastName : 'chaewoon',
  getFullName: function(){
    return `${this.firstName} ${this.lastName}`
  }
}
console.log(Sim.getFullName())
//이러한 객체들을 여러개 생성할려하면 번거로워서 js class 문법 사용

function User(first,last){
  this.firstName = first
  this.lastName = last
}
user.prototype.getFullName = function (){
  return `${this.firstName} ${this.lastName}`
}
const fullName = new User('Sim','chaewoon')
console.log(fullName)//Object
console.log(fullName.getFullName())//Sim chaewoon

this

일반(Normal)함수는 호출 위치에 따라 this 정의
화살표(Arrow)함수는 자신이 선언된 함수 범위에서 this 정의

const nickname = {
  name: 'Sim',
  normal:function(){
    console.log(this.name)
    //sim
  },
  arrow : () => {
    console.log(this.name)
    //undefined
  }
}
nickname.normal() // Sim
nickname.arrow() // undefined

//new 키워드 생성자함수
function User(name){
  this.name = name
}
User.prototype.normal = function() {
  console.log(this.name)
}
User.prototype.arrow = () => {
  console.log(this.name)
}

const nickname = new User('Sim')

nickname.normal() // Sim
nickname.arrow() //undefined

그러면 timer객체를 사용했을때는 왜 undefined 일까?

//타이머객체 사용
const timer = {
  name : 'Sim',
  timeout: function(){
    setTimeout(function(){
      console.log(this.name)
    },2000)
  }
}
timer.timeout() // undefined

이유 : 일반함수는 호출 위치에 따라 this 정의 여기서 this는 setTimeout안에 있는 name이라는 속성을 지칭 그러므로 결과가 undefined로 출력
일반함수가 아닌 화살표함수로 하게되면

const timer = {
  name : 'Sim',
  timeout: function(){
    setTimeout(() => {
      console.log(this.name)
    },2000)
  }
}
timer.timeout() //Sim

이유 : 코드를 보면 화살표함수가 this를 정의할때는 화살표함수 자신이 만들어진 함수 범위에서 정의가 되기 때문이다. 쉽게 풀어보자면 화살표함수가 정의된 부분이 있고, 화살표함수를 감싸고 있는 timeout이라는 메소드를 정의할때 만든 함수가 화살표함수를 감싸고 있다. 이렇게 추가적인 함수 범위가 있기 때문에 화살표함수는 정의될 수 있고 정의가 된 값이 timer라는 객체데이터를 가리키기 때문에 this는 timer가 된다.
이러한 이유로 저번에 타이머함수를 설명할때 타이머함수를 사용할때는 콜백함수로 일반함수 보다는 화살표함수가 활용도가 높다고 설명한 것이다. 상황에 따라 일반함수, 화살표함수를 사용해야하니깐.

ES6 Classes

js는 prototype 기반의 프로그래밍언어인데 좀 더 안정적이고 신뢰도가 높은 다른 객체지향 프로그래밍 언어들의 영향을 받아서 class라는 개념을 흉내내서 새로운 문법을 ES6에서 제공하기 시작 그래서 좀더 직관적이고 간결하고 유연한 문법으로 작성이 가능해졌다.
ex)

//객체 데이터 내부에서 일반함수를 사용할때는 :function이라는 키워드를 생략 가능하다.
const nickname = {
  name: 'Sim',
  normal(){
    console.log(this.name)
    //sim
  },
  arrow : () => {
    console.log(this.name)
    //undefined
  }
}
nickname.normal(); //Sim
nickname.arrow() // undefined

//기존 내용
function User(first,last){
  this.firstName = first
  this.lastName = last
}
User.prototype.getFullName = function (){
  return `${this.firstName} ${this.lastName}`
}
const fullName = new User('Sim','chaewoon')
console.log(fullName)//Object
console.log(fullName.getFullName())//Sim chaewoon 

//변경내용
class User {
  constructor(first,last) {
    this.firstName = first
    this.lastName = last
  }
  getFullName(){
    //별도로.prototype이라는 속성을 중간에 사용하지 않아도 바로 prototype으로 만들어지는 메소드가 정의가 됨
    return `${this.firstName} ${this.lastName}`
  }
}
const fullName = new User('Sim','chaewoon')
console.log(fullName)//Object
console.log(fullName.getFullName())//Sim chaewoon 
//결과값 동일

constructor라는 내부함수 사용(:function이 생략된거랑 같은 맥락) 리액트 배울때 이러한 문법 자주 사용

상속(확장)

클래스를 사용한다는 것은 미리 만들어진 어떠한 정보에 추가적으로 살을 붙여가면서 새로운 기능들을 확장이라는 개념으로 관리를 해줄 수 있다는 의미.

class Vehicle {
  constructor(name, wheel){
    this.name = name
    this.wheel = wheel
  }
}
const myVehicle = new Vehicle('운송수단', 2)
console.log(myVehicle)

결과 :


class Bicycle extends Vehicle {
  constructor(name, wheel){
    super(name, wheel)
    //super 키워드는 부모 오브젝트의 함수를 호출할 때 사용
    //constructor()의 인자들을 super()인자들에게 넘기고 그 값이 Vehicle로 할당되는 구조
  }
}
const myBicycle = new Bicycle('자전거', 2)
const daughtersBicycle = new Bicycle('세발자전거', 3)
console.log(myBicycle)
console.log(daughtersBicycle)

결과 :


class Car extends Vehicle {
  constructor(name, wheel, license) {
    super(name, wheel)
    this.license = license
  }
}
const myCar = new Car('마세라티', 4, true)
const secondCar = new Car('포르쉐', 4, false )
console.log(myCar)
console.log(secondCar)

결과 :

profile
불가능, 그것은 사실이 아니라 하나의 의견일 뿐이다. - 무하마드 알리

0개의 댓글