클래스

Yun Young Choi·2022년 12월 11일
0

Javascript

목록 보기
3/7
post-thumbnail

저번에 자바 수행평가로 클래스 파트 발표를 했었다.
그래서 그런지 클래스는 수월히 공부할 수 있는듯??!!


클래스 정의

class User {
  // 생성자 메소드는 new User() 명령어에 의해 자동 호출
  constructor(name) {
    // 전달받은 인수로 필요한 속성값 초기화
    this.name = name;
  }
  
  sayHi() {
    console.log("안녕하세요");
  }
}

// 객체 생성
let sam = new User("sam");
// 클래스 내부에서 정의한 메서드 사용 가능
sam.sayHi();

  • 위 코드에서 new User("sam") 명령어를 호출한 후 생기는 일

    1.새로운 객체 생성

    1. 넘겨받은 인수와 함께 constructor 메서드 자동 실행, "sam"이 this.name에 할당

자바스크립트에서 클래스는 내부적으로 생성자 함수로 취급

클래스의 constructor 메서드 => 생성자 함수


class User {
 constructor(name) { this.name = name; }
 sayHi() { alert(this.name); }
}

// User는 함수
console.log(typeof User); // function

// User.prototype에 sayHi 함수가 정의되어 있는 것을 확인 가능
console.log(User.prototype);
// { constructor: User, sayHi: f }

  • class 문법을 통해 내부적으로 수행되는 일
    1. User라는 이름을 가진 함수 생성, 함수 본문은 생성자 메서드에서 가져옴
    2. 생성자 메서드가 없으면 "본문이 비워진 상태"로 함수 생성
    3. sayHi와 같은 클래스 내 정의된 메서드를 함수의 prototype 객체에 추가

자바와 비슷한 게 자바도 생성자가 없으면 JVM이 자동 생성을 하는데 만약 있으면 JVM이 자동 생성한 생성자는 삭제된다. 그냥... 갑자기 떠올랐다.


class 대신 생성자 함수, 프로토타입 객체 이용하는 코드

// 1. User라는 이름을 가진 생성자 함수를 만들고 함수 본문은 생성자 메서드 constructor에서 가져오기
function User(name) {
	this.name = name;
}
// 만약 constructor 메서드의 내용이 비어있다면 다음과 같은 "본문이 비워진" 생성자 함수가 정의됨

// function User(name) {}

// 2. 클래스 내에서 사용할 메서드를 User.prototype에 정의하기
User.prototype.sayHi = function() {
  alert(this.name);
}

클래스와 프로토타입 정리

class User {
	constructor(name) {
  		this.name = name;
	}
	sayHi() {
    	alert(this.name);
    }
}

// 클래스는 함수
alert(typeof User); // function

// 클래스는 "생성자 메서드"와 동일
alert(User === User.prototype.constructor); // true

// 클래스 내부에서 정의한 메서드는 User.prototype에 저장
alert(User.prototype.sayHi); // alert(this.name);

// 현재 프로토타입에는 메서드가 두 개(생성자, sayHi) 존재함
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi

클래스 필드

  • 개별 객체에 포함시킬 속성 추가 가능
class User {
  // 클래스 필드 문법 (클래스 중괄호 내부에 대입문 쓰기)
  name = "john";

  sayHi() {
    console.log("안녕");
  }
}

new User().sayHi(); // 안녕

  • 클래스 필드와 생성자 메서드에 동시에 속성 정의 가능
class User {
  name = 'sam';
  age = 18;
  
  constructor(say) {
    this.say = say;
  }
}

const sam = new User({ say : "hello"});
console.log(sam.name); // sam
console.log(sam.age); // 18
console.log(sam.say); // say : "hello"
  • 클래스 필드로 선언한 속성값은 prototype 객체가 아닌 개별 객체에 적용
class User {
	name = "John";
}
let user = new User();

// 개별 객체에 name 속성이 추가됨
alert(user.name); // "John"

// prototype에 추가되어 공통적으로 사용할 속성이 되는 것이 아님을 유의
alert(User.prototype.name); // undefined

클래스 필드로 바인딩 된 메서드 만들기

  • js는 호출 시점에 따라 다른 this 값을 가질 수 있음
  • 함수 외에 메서드에도 적용되는 규칙, 메서드를 전달해서 다른 컨텍스트에서 호출하면 this는 원래 객체 참조 X
class Btn {
  constructor(value) {
    this.value = value;
  }
  
  click() {
    console.log(this.value);
  }
}

let btn = new Btn("hello");
setTimeOut(btn.click, 1000); // undefined

  • 클래스 필드에 메서드를 정의하며 화살표 함수 사용시 객체마다 독립적인 함수를 만들고 함수의 this를 해당 객체에 바인딩
  • 따라서 메서드가 실행되는 맥락이 관계없이 this에 항상 의도한 값 들어감
  • 메서드를 이벤트 리스너로 설정해야할 때 유용
class Button {
	constructor(value) {
		this.value = value;
	}
	// click 메서드를 화살표 함수를 이용해서 정의
	click = () => {
		alert(this.value);
	}
	nonBinded() {
		alert(this.value);
	}
}
let button1 = new Button("hello");
setTimeout(button1.click, 1000); // hello
let button2 = new Button("hello");

// click 메서드는 화살표 함수로 정의했으므로,
// 서로 독립적인 함수 객체 참조를 가지게 됨 (내용은 똑같지만 서로 참조가 다른 독립적인 함수)
console.log( button1.click === button2.click ); // false

// nonBinded 메서드는 화살표 함수를 이용하지 않고 정의했으므로,

// 화살표 함수로 정의하지 않았으므로 함수 객체를 공유
console.log( button1.nonBinded === button2.nonBinded ); // true

// click은 prototype 객체에도 포함되지 않음
console.log( Button.prototype.click );

// 그러나 nonBinded는 prototype 객체에 포함됨
console.log( Button.prototype.nonBinded );

profile
안냥하세요

0개의 댓글

관련 채용 정보