프론트엔드/Javascript

함수와 this

syleemomo 2024. 4. 20. 08:53
728x90

function 으로 생성한 함수에는 항상 this 와 prototype 속성이 존재한다. 

const Shadow = function(){ console.log(this) }
console.log(Shadow())

this 는 윈도우 객체이다.

console.log(new Shadow())

this 는 생성자함수이다. 

var Human = function(type){
    this.type = type || 'human'
}
Human.isHuman = function(human){
    return human instanceof Human 
}
Human.prototype.breathe = function(){
    alert('h-a-a-a-m')
}

자바스크립트에서는 객체 복사로 상속한다. 복사하는 원본객체를 프로토타입 객체라고 한다.

var Human = function(type){
  this.type = type || 'human'
}
Human.isHuman = function(human){
  return human instanceof Human
}
Human.prototype.breath = function(){
  alert('h-a-a-a-m')
}
var Zero = function(type, firstName, lastName){
  Human.apply(this, arguments) // 부모 생성자 호출 (부모의 멤버변수 상속)
  this.firstName = firstName
  this.lastName = lastName 
}
Zero.prototype = Object.create(Human.prototype) // 부모 프로토타입 상속 (부모 메서드 상속)
Zero.prototype.constructor = Zero // 프로토타입 객체의 생성자를 자신의 생성자를 참조하도록 설정 
Zero.prototype.sayName = function(){
  alert(this.firstName + ' ' + this.lastName)
}
var oldZero = new Zero('human', 'Zero', 'Cho')
// oldZero.sayName()
Human.apply(this, arguments) // 부모 생성자 호출 (부모의 멤버변수 상속)

this 는 Zero 생성자 함수를 가리킨다. Human 생성자 함수의 this 값을 Zero 로 바인딩한다. 즉, class 문법에서 super(type)으로 부모 생성자를 호출하고 부모의 멤버변수를 상속받는다. 

Zero.prototype = Object.create(Human.prototype) // 부모 프로토타입 상속 (부모 메서드 상속)

부모인 Human 생성자함수의 프로토타입 객체를 참조함으로써 부모의 메서드를 상속받는다. Human 처럼 생성자 함수가 아니라 일반적인 객체 리터럴 형태라면 그냥 Object.create() 에 인자로 전달하면 된다. 

Zero.prototype.constructor = Zero // 프로토타입 객체의 생성자를 자신의 생성자를 참조하도록 설정

Human.prototype 을 상속받으면 Zero.prototype.constructor 는 Human 이다. 자신을 참조하기 위하여 다시 Zero 로 설정한다.

Zero.prototype.sayName = function(){
  alert(this.firstName + ' ' + this.lastName)
}

Zero 생성자함수 자신의 메서드를 정의한다. 

 

클래스 문법으로 다시 작성하면 아래와 같다.

class Human{
  constructor(type = 'human'){
    this.type = type 
  }
  static isHuman(human){
    return human instanceof Human 
  }
  breathe(){
    alert('h-a-a-a-m')
  }
}
class Zero extends Human{
  constructor(type, firstName, lastName){
    super(type)
    this.firstName = firstName
    this.lastName = lastName
  }
  sayName(){
    alert(`${this.firstName} ${this.lastName}`)
  }
}
const newZero = new Zero('human', 'Zero', 'Cho')
Human.isHuman(newZero)

static 메서드는 생성자함수나 클래스명으로만 접근할 수 있는 메서드이다. 즉, 생성자함수나 클래스로 생성된 인스턴스로는 호출할 수 없다. 

728x90