개발자

자바스크립트 객체 생성 방식 질문 드립니다.

2023년 10월 06일조회 92

안녕하세요, 저는 현재 자바스크립트 Deep Dive라는 책을 독학하고 있습니다. 클로저 예제(24-13)와 관련해 이해가 다소 어려운 부분이 있어 질문글을 작성하게 되었습니다. const Counter = (function() { let num = 0; function Counter() { } Counter.prototype.increase = function () { return ++num; } Counter.prototype.decrease = function () { return num > 0 ? --num : 0; } return Counter; })(); 여기서 객체의 생성 방식에 따른 동작 방식에 대한 의문이 있습니다. 1. 생성자 호출 const counter = new Counter(); // Counter {} new 연산자와 함께 호출하면 return 문의 유무와 관계 없이 Counter 객체가 생성되는 점은 이해했습니다. 2. 일반 호출 const counter =Counter(); // undefined 위 경우 명시적으로 return Counter를 반환하고 있음에도, undefined가 콘솔에 출력되는 이유가 궁금합니다. chatGPT에 문의했더니 답변이 오락가락해 혼란이 가중되네요.. 지식 나눔에 미리 감사드립니다.

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.
profile picture
익명님의 질문

답변 2

인기 답변

Ed님의 프로필 사진

자바스크립트에서는 이전에 클래스 문법이 없을때에 function을 사용해서 객체를 만드는 틀로 사용했는데 그 작동원리에는 prototype이라는 내부적인 구현방식이 있습니다.(사실 현재도 그렇습니다.) 짧게 설명드리면 새로운 함수를 정의하면 그 함수는 그 함수의 prototype 객체 내부의 생성자 함수를 가리키며 이후에 new 키워드와 함께 해당 함수를 호출시 객체를 찍어낼 수 있습니다. new 와 함께 생성자함수를 호출하지 않으면 객체를 만들지 못하고 Counter 함수에는 return 값이 따로 없기때문에 undefined를 반환하는거 같습니다. 지급 질문하신 부분은 자바스크립트에서 클래스 문법이 나오기전에 프로토타입 기반으로 객체를 만드는 과정에서 비롯된 것이고 글 제목인 클로저하고는 조금 궤를 달리합니다. 프로토타입을 키워드로 좀 더 찾아보시면 더 정확히 이해하실 수 있을시거 같네요.

profile picture

익명

작성자

2023년 10월 07일

답변 주셔서 감사합니다. 말씀주신 것처럼 질문 자체가 클로저가 아닌 생성자 함수를 이용한 객체 생성 방식에 대한 부분이었는데, 예제 문제가 포함된 목차를 제목으로 작성해서 혼란을 야기했네요. 말씀주신대로 프로토타입을 통한 객체 생성으로 제목을 바르게 정정하도록 하겠습니다. 감사합니다!

profile picture

익명

작성자

2023년 10월 06일

질문 후에 코드를 살펴보며 제가 이해한 내용입니다. 혹시 클로저 혹은 즉시 실행함수에 대해 첨언주시거나 아래에 이해한 내용 중 정정이 필요한 내용이 있다면 답변 달아주시면 정말 감사드리겠습니다. 제가 질문 시에 오해한 점은 즉시 실행 함수의 반환값이 Counter 함수의 반환값이라고 생각한 것입니다. 즉시 실행 함수의 반환값은 Counter 함수 정의입니다. 이 때 const counter = new Counter(); 를 실행하면, Counter()의 반환값인 Counter 함수 정의가 new 연산자와 함께 호출되어, 반환값이 존재하지 않더라도 암묵적으로 Counter 객체를 생성하여 counter에 할당됩니다. const counter = Counter(); 를 실행하면, Counter()의 반환값인 Counter 함수 정의가 일반 호출되어, Counter 함수의 반환값(여기서는 함수 몸체가 비어 있으므로 undefined)이 counter에 할당됩니다. 아직까지 클로저가 클래스의 약식이 아닌가 하는 생각이 듭니다. 더 배워가며 둘의 차이에 대해서 알아보고 싶네요!

1const Counter = (function() {
2    let num = 0;
3
4    // Counter 함수의 반환값은 없음
5    function Counter() {
6        
7    }
8
9    Counter.prototype.increase = function () {
10        return ++num;
11    }
12
13    Counter.prototype.decrease = function () {
14        return num > 0 ? --num : 0;
15    }
16
17   // 즉시 실행 함수의 반환값은 Counter 함수 정의 
18    return Counter;
19})();

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

AI 답변
커리어리 AI 봇 프로필 이미지

커리어리 AI 봇

GPT가 달아주는 답변입니다.

2023년 10월 06일

자바스크립트에서 함수를 호출하는 방법에는 '생성자 함수'로서 호출하는 방법과 '일반 함수'로서 호출하는 방법이 있습니다. 1. 생성자 호출: new 연산자와 함께 함수(생성자 함수)를 호출하면, JavaScript는 내부적으로 빈 객체를 생성하고 이 객체를 this라는 컨텍스트로 바인딩합니다. 그리고나서 Counter의 프로토 타입에 정의된 메소드들을 상속받게 됩니다. 2. 일반 호출: 일반적으로 함수를 호출하면 그냥 실행되어 결과값만 리턴되며, 명시적으로 'return' 문이 없으면 undefined가 반환됩니다. 위의 코드에서 `Counter()` 는 return 문이 없으므로 undefined가 반환됩니다. 하지만 여기서 Counter 함수는 즉시 실행 함수(IIFE) 내부에 정의되어 있으며, IIFE가 실행되면서 Counter() 생성자 함수 자체가 반환됩니다. 이 때문에 `const counter = new Counter();` 라고 하면, 반환된 Counter 생성자(즉, prototype 메소드들을 가진)를 통해 객체를 만들 수 있습니다. 그러나 `const counter = Counter();` 처럼 일반적으로 함수처럼 사용한다면 제대로 동작하지 않습니다. 'new' 연산자와 함께 우리가 생성한 익명함수 내부에서 선언된 newInstance 개념을 접근하지 못하게 됩니다. 따라서 일반 함수 호출시에는 바인딩된 this가 없기 때문에 생성자 Counter 내부에 정의된 내용이 실행되지 않아, undefined가 반환됩니다. 이 경우 생성자 함수로서의 역할을 제대로 수행하지 못하는 것입니다.

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!