-
일반 함수로 생성자 함수처럼 구현언어 공부/JS 2022. 4. 7. 22:25
생성자 함수는 유사한 객체를 여러 개 만들어야 하는 상황에 유용하다.
그런데 사실 생성자 함수와 그냥 함수는 크게 다를 바가 없지만, 관례라 해야하나... 3가지 차이점이 있다.
- 함수 이름의 첫 자는 대문자로 시작한다.
- 반드시 new 연산자를 앞에 붙여 호출한다.
- 생성자 함수 안에는 return문이 없다. (메서드 함수에서 사용되는 부분은 제외하고)
예시를 살펴보자.
function User(name, age) { this.name = name; this.age = age; this.introduce = function () { console.log(`Hi, I'm ${this.name}, ${this.age} years old.`); }; } user1 = new User("Jane", 32);
이렇듯 위에 세 조건을 모두 만족한다. 물론, introduce 메서드 안에 return문이 들어가도 된다.
만약 User 내에 return 문이 들어가면 어떻게 될까?
답은 그때그때 다르다. 다음 2가지의 경우로 결과가 달라진다.
- 객체를 return 할 때
- 그 외 나머지
1의 경우에는 this 대신에 객체가 반환된다. 반면 2의 경우에는 return문 자체가 무시된다.
사실 무시된다기 보단 그냥 하던대로 this가 리턴되는 것이다.
여기서 의문이 들었다.
생성자 함수에 return문도 없고, return문을 적었을 때 객체가 아닌 아무거나 적어도 모두 this가 반환되는데 데체 이유가 뭘까?
그 이유는 js가 자동으로 this라는 빈 객체를 만들고 리턴하기 때문이다. 그리고 이 매커니즘이 작동하는 트리거는 바로 new 연산자가 그 역할을 하는 것이다. 실제로 다음의 코드는 위의 예시와 동일한 코드이다.
function User(name, age) { this = {}; this.name = name; this.age = age; this.introduce = function () { console.log(`Hi, I'm ${this.name}, ${this.age} years old.`); }; return this; } user1 = new User("Jane", 32);
따라서 return문이 없어도 객체가 잘 반환 되었던 것이다.
만약 new 연산자를 쓰지 않고 생성자 함수를 호출하면 어떻게 될까?
그럼 생성자 함수는 그냥 함수처럼 호출되기 때문에 return문이 없어 아무것도 반환하지 않는, undefined를 반환하게 된다.
사실 이 과정은 this 키워드와 연관이 있는데 this에 대해서는 다음에 자세히 알아보도록 해야겠다.
여기서 또 의문이 들었다.
아래의 코드도 똑같이 생성자 함수의 역할을 할 수 있지 않나? 굳이 왜 생성자 함수를 쓰는거지?
function user (name, age) { return { name: name, age: age, introduce: function () { console.log(`Hi, I'm ${this.name}, ${this.age} years old.`); }, }; }; user1 = user("Woong", 21); console.log(user1);
실제로 두 함수의 차이는 생성자가 객체인지 사용자 정의 생성자인지의 차이와 프로토타입의 구성 뿐이다.
게다가 상속받은 프로토타입의 메서드도 완벽히 동일하다.
**추가**
위 설명에 오류에 대한 지적과 굳이 생성자 함수를 사용하는 방법에 대한 포스팅을 올렸습니다.
프로토타입 포스팅에서 확인하실 수 있습니다.현재로써는 굳이 왜 생성자 함수를 쓰는지 모르겠다. 그냥 함수로도 충분한데...
나중에 알게 되면 따로 글을 또 적는걸로 하고, 일단 지금은 혹시 모를 프로토타입 관련 오류방지를 위해 앞서 사용한 코드가 생성자 함수를 활용했다면 나도 생성자 함수를, 아니라면 아닌대로 사용해야겠다.
요약
생성자 함수는 대문자로 시작하게 작명하고,
new 키워드를 꼭 사용하여 호출하고,
가급적이면 return문을 쓰지 말자.
...근데 꼭 써야하나? 다른 방법도 많은데...'언어 공부 > JS' 카테고리의 다른 글
prototype (0) 2022.04.10 Closure (0) 2022.04.07 console.log() 실시간 적용 (0) 2022.04.06