🎯 Achievement Goals


  • 클래스와 인스턴스라는 용어를 이해할 수 있다.
    • new 키워드의 사용법을 이해할 수 있다.
    • class 키워드의 사용법을 이해할 수 있다.
    • 현실 세계의 모델을 바탕으로 클래스의 메소드와 속성을 디자인할 수 있다.


  • this와 call, apply, bind와 같은 함수 메소드의 작동을 이해할 수 있다.




👉 클래스와 인스턴스


클래스 ? 인스턴스 ?

클래스와 인스턴스


“클래스는 객체 지향 프로그래밍에서 특정 객체를 생성하기 위해 변수와 메소드를 정의하는 일종의 틀로, 객체를 정의하기 위한 상태(멤버 변수)와 메서드(함수)로 구성된다.”


현업에서는 사용자나 물건같이 동일한 종류의 객체를 여러 개 생성해야 하는 경우가 많다고 한다.

즉, 코드를 작성할 때 객체 단위로 코드 그룹화 및 코드 재사용성을 사용하기 위함이다.

ES6 에서는 class 라는 키워드를 이용해서 정의할 수도 있다. 문법은 다음과 같다.


class useonglee {
  // 인스턴스가 만들어질 때 실행되는 코드
  constructor (name, age, gender) {...}
  method1 () {...}
  method2 () {...}
  method3 () {...}
}

// 생성자 함수는 return 값을 만들지 않는다.


이렇게 클래스를 만들고 new Car ()를 호출하면 내부에서 정의한 메서드가 들어 있는 객체(위 인스턴스가 만들어질 때 실행되는 코드)가 생성된다.

객체의 기본 상태를 설정해주는 생성자 메서드 constructor ()new에 의해 자동으로 호출되므로, 특별한 절차 없이 객체를 초기화 할 수 있다.


class Useonglee {

  constructor (name, age, gender) {
  this.name = name;
  this.age = age;
  this.gender = gender;
  }

  learn () {
    console.log(this.name + "님은 현재 코딩중입니다!")
  }
}

// 인스턴스
let itsMe = new Useonglee ("이우성", 28, "male")


console.log (itsMe)
// {name: "이우성", age: 28, gender: "male"}

console.log (itsMe.learn())
// 이우성님은 현재 코딩중입니다!

console.log (typeof Useonglee)
// "function"


new Useonglee(“이우성”, 28, “male”)를 호출하면 다음과 같은 일이 발생한다.

  1. 새로운 객체가 생성된다. (Useonglee라는 이름을 가진 함수를 만든다.)
  2. 넘겨받은 인자와 함께 constructor가 자동으로 실행된다. 생성자 메서드가 없으면 본문이 비워진 채로 함수가 만들어진다.
  3. “이우성”this.name에 할당이 된다.
  4. learn()같은 클래스 내에서 정의한 메서드를 Useonglee.prototype에 저장한다.
  5. (Useonglee === Useonglee.prototype.constructor) // true
    class 와 생성자 메서드는 동일하다.


위에 코드에서 인스턴스 (instance)itsMe 변수가 된다.




👉 call(),apply() 그리고 bind()


먼저 call(),apply() 와 bind()의 결정적인 차이점은 함수 호출에 있다.

  • call(),apply() : 함수 호출
  • bind() : 함수 호출X, this 호출



함수에서 call(), apply() 를 사용하는 이유


함수가 실행될 때 내부 콘텍스트의 this는 실행중인 객체 자신을 가리키거나 객체 내부의 함수가 아니라면 window 객체를 가리킬 것이다.


이때 this가 가리키는 대상을 바꿀 수 있는데 이때 this값을 조작하는데 사용하는 방법이 바로 call()apply()이다.



call(), apply () 사용방법


function foo() {
  return 'bar'
}

foo.call() // 함수.call(지정할 객체명, 전달할 매개변수)

foo.apply() // 함수.apply(지정할 객체명, [전달할 매개변수])


먼저 둘 다 첫번째 인자가 항상 this값이 된다. 첫번째 인자 this 키워드가 가리키는 대상을 변경할 수 있게 해준다. 둘의 차이점은 단지 전달하는 방법에서 차이가 있다.



bind()

어떠한 함수이건 (메서드 포함) bind라는 함수를 사용할 수 있다. 즉, function object는 모두 bind()를 사용할 수 있다는 뜻이다.

bind()를 사용하면 this는 내가 정한 object로 고정된다.

그전에 만약 bind가 되어있다면 그 bind를 무시하고 object를 고정하게 된다.


class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  info () {
    console.log(`x:${this.x}, y:${this.y}`);
  }
}

let point = Point(10, 20)

console.log(point.info())
// x:10, y:20

console.log(point.info.bind({x:100, y:200}))
// x:100, y:200


info()Point의 메소드이기때문에 이미 this가 Point로 bind가 되어있다.

하지만 바인드 함수를 이용해서 다시 사용할 수 있다.



setTimeout 바인드

setTimeout()를 사용할 때는 바인드 함수를 특히 다르게 써야한다는 것을 배웠다.


printAsync() {
    setTimeout(this.printArea, 2000)
  }

이러한 코드였는데 해당 this가 class의 인스턴스가 아니기에 오류가 났다. 그렇다면 setTimeout()을 사용할 때는 어떻게 사용해야 할까?


printAsync() {
  setTimeout(this.printArea.bind(this), 2000)
}

바인드 함수를 사용해서 this를 지정해서 불러온다.


printAsync() {
  setTimeout(() => {
    this.printArea()
  }, 2000)
}

다른 방법으로는 이렇게 사용할 수 도있다. setTimeout() 을 사용할 때 명심하자!




이렇게 modernJavaScript 스프린트까지 끝이 났다. 내일이 지나면 벌써 이머시브 1주차가 끝난다~~~




👊 내일의 TIW(today I Will)

OOP, Inheritance Patterns