제코베 12번 문제인 class에 관한 내용을 스터디원들이랑 얘기하다가 생각난김에 정리해보려고 글을 쓴다 ! class는 react에서도 쓰면서 개념도 모르고 썼던 내 자신을 반성합니다 😥
📝 Classes
Class는 객체를 생성하기 위한 템플릿입니다. 클래스는 데이터와 이를 조작하는 코드를 하나로 추상화합니다. 자바스크립트에서 클래스는 프로토타입을 이용해서 만들어졌지만 ES5의 클래스 의미와는 다른 문법과 의미를 가집니다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Classes
한마디로 class는 객체를 여러개 생성하기 위한 하나의 템플릿이라고 생각하면 되고, es6 이전에는 function을 이용해 비슷하게 만들었다고한다.
function Dog(name){
this.name = name;
}
let dog = new Dog('제톰');
console.log(dog.name);
class Jetom{
constructor(age, blood){
this.age = age;
this.blood = blood;
}
}
const dog = new Jetom(5, '비숑');
console.log(dog.age, dog.blood);
쓰다보니 this와 new라는 단어들이 눈에 띄는데 이것들이 어떤 일을 하는지 알아보겠다!
여기서의 내용은 생활코딩을 참고했습니다 ✍️
📝 new
new 연산자는 사용자 정의 객체 타입 또는 내장 객체 타입의 인스턴스를 생성한다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/new
//obj
const person = {};
//객체 내의 변수를 프로퍼티(property, 속성)라고 부른다.
person.name = 'jetom';
//property에 담겨 있는 함수를 메서드(method, 방법)라고 부르다.
person.introduce = function(){
return 'My name is' +this.name;
}
//메서드 안의 this.name은 person의 객체를 가리키며
//person.name의 값을 'jetom'으로 담아줬으니 결국 'jetom'을 호출한다.
console.log(person.introduce);
위의 예제 코드는 'jetom'이라는 강아지의 정보를 하나만 담을 때 사용했다. 하지만 강아지가 여러 마리라면 어떻게 만들어야할까? 이 때가 생성자와 new를 사용할 순간이다.
생성자(constructor)는 객체를 만드는 역할을 하는 함수다. 자바스크립트에서 함수는 재사용 가능한 로직의 묶음이 아니라 객체를 만드는 창조자라고 할 수 있다.
https://opentutorials.org/module/532/6571
function Dog(){}
//new는 생성자 함수라고 부르며 이 때 생성되는것은 비어있는 객체이다.
//let many = {}랑 같다고 생각하면 된다.
function Dog(name){
//객체가 생성될 때마다 만들어지는 코드
this.name = name;
this.introduce = function(){
return 'My name is '+' '+this.name;
}
}
let many = new Dog('jetom');
console.log(many.introduce())
let many2 = new Dog('rari');
console.log(many2.introduce())
위의 코드를 살펴보면 생성자 내에서 객체의 프로퍼티를 정의하고 있으며 이 작업은 초기화(initialize)라고한다.
📝 this
this는 함수 내에서 함수 호출 맥락(context)를 의미한다. 맥락이라는 것은 상황에 따라서 달라진다는 의미인데 즉 함수를 어떻게 호출하느냐에 따라서 this가 가리키는 대상이 달라진다는 뜻이다. 함수와 객체의 관계가 느슨한 자바스크립트에서 this는 이 둘을 연결시켜주는 실질적인 연결점의 역할을 한다.
https://opentutorials.org/module/532/6571
어떤 객체에 속해 있지 않을 때의 this는 window를 가르키는데 이 window는 웹 브라우저의 전역 객체 이름이다. 따라서 아래의 예제의 경우 func의 this는 window이므로 window를 생략한 채로 func()를 출력 할 수 있다.(함수는 window라는 것이 암시적으로 사용된다.)
function func(){
if(window === this){
console.log('window === this');
}
}
//window.func()를 해도 정상적으로 작동한다.
func()
메서드는 객체에 저장된 정보에 접근할 수 있어야 제 역할을 할 수 있습니다. 모든 메서드가 그런 건 아니지만, 대부분의 메서드가 객체 프로퍼티의 값을 활용합니다.
메서드 내부에서 this 키워드를 사용하면 객체에 접근할 수 있습니다.
이때 '점 앞’의 this는 객체를 나타냅니다. 정확히는 메서드를 호출할 때 사용된 객체를 나타내죠.
https://ko.javascript.info/object-methods#ref-933
let dog = {
name: "jetom",
age: 5,
//객체안의 함수는 function 생략 가능
sayHi() {
// 'this'는 '현재 객체'인 dog를 가르킨다.
console.log((this.name));
}
};
dog.sayHi();
let funcThis = null;
function Func(){
funcThis = this;
}
//new가 없으므로 일반 함수를 호출함
const o1 = Func();
if(funcThis === window){
console.log(('window'));
}
//func()는 o2에서 new를 통해서 호출 했기 때문에 생성자를 호출함
const o2 = new Func();
if(funcThis === o2){
console.log(('o2'));
}
o1을 출력했을 때 window가 찍히는 이유?
Func()는 일반 함수인데, 일반 함수는 위에서 언급했듯이 window가 생략되었기 때문에 o1에서의 Func()는 funcThis에서 window를 찍는다.
o2를 출력했을 때 o2가 찍히는 이유?
new를 생성자로 호출하면 자바스크립트 내부에서 빈 객체를 만드는데 비어있는 객체가 생성자 안에서 this가 된다. 따라서 this는 Func에 있는 this값이 funcThis가 되고, 이 funcThis는 조건문에 따라 o2가 출력되는것
따라서 생성자로 사용될 때는 this의 값이 생성될 객체를 가리키고, 일반 함수로 호출 했을 때는 window를 가리킨다.
쓰다보니 class로 쓴 내용보다 function으로 구현한 코드가 많지만.... 원리는 같으니까... 슬쩍 넘어가려한다....ㅎ🙄