JavaScript

생성자와 new

객체

객체란 서로 연관된 변수와 함수를 그룹핑한 그릇이라고 할 수 있다. 객체 내의 변수를 프로퍼티(property) 함수를 메소드(method)라고 부른다. 객체를 만들어보자.

var person = {}
person.name = 'egoing';
person.introduce = function(){
    return 'My name is '+this.name;
}
document.write(person.introduce());

객체를 만드는 과정에 분산되어 있다. 객체를 정의 할 때 값을 셋팅하도록 코드를 바꿔보자.

var person = {
    'name' : 'egoing',
	'introduce' : function(){
		return 'My name is '+this.name;
	}
}
document.write(person.introduce());

만약 다른 사람의 이름을 담을 객체가 필요하다면 객체의 정의를 반복해야 할 것이다. 객체의 구조를 재활용할 수 있는 방법이 필요하다. 이 때 사용하는 것이 생성자다.

생성자

생성자(constructor)는 객체를 만드는 역할을 하는 함수다. 자바스크립트에서 함수는 재사용 가능한 로직의 묶음이 아니라 객체를 만드는 창조자라고 할 수 있다.

function Person(){}
var p = new Person();
p.name = 'egoing';
p.introduce = function(){
    return 'My name is '+this.name;	
}
document.write(p.introduce());

함수를 호출할 때 new을 붙이면 새로운 객체를 만든 후에 이를 리턴한다. 위의 코드는 새로운 객체를 변수 p에 담았다. 여러사람을 위한 객체를 만든다면 아래와 같이 코드를 작성해야 할 것이다. 

function Person(){}
var p1 = new Person();
p1.name = 'egoing';
p1.introduce = function(){
    return 'My name is '+this.name;	
}
document.write(p1.introduce()+"<br />");

var p2 = new Person();
p2.name = 'leezche';
p2.introduce = function(){
	return 'My name is '+this.name;	
}
document.write(p2.introduce());

별로 개선된 것이 없다. 

function Person(name){
    this.name = name;
	this.introduce = function(){
		return 'My name is '+this.name;	
	}	
}
var p1 = new Person('egoing');
document.write(p1.introduce()+"<br />");

var p2 = new Person('leezche');
document.write(p2.introduce());

생성자 내에서 이 객체의 프로퍼티를 정의하고 있다. 이러한 작업을 초기화라고 한다. 이를 통해서 코드의 재사용성이 대폭 높아졌다.

코드를 통해서 알 수 있듯이 생성자 함수는 일반함수와 구분하기 위해서 첫글자를 대문자로 표시한다.

자바스크립트 생성자의 특징

일반적인 객체지향 언어에서 생성자는 클래스의 소속이다. 하지만 자바스크립트에서 객체를 만드는 주체는 함수다. 함수에 new를 붙이는 것을 통해서 객체를 만들 수 있다는 점은 자바스크립트에서 함수의 위상을 암시하는 단서이면서 또 자바스크립트가 추구하는 자유로움을 보여주는 사례라고 할 수 있다.

 

댓글

댓글 본문
  1. GelandeWagen
    ok
  2. 감사합니다.
  3. 콜드브루
    좋은 강의 감사합니다 !!
  4. seaWater
    2021. 9. 28. 완료
  5. 엘리
    파이티잉! 감사합니다
  6. 완료
  7. labis98
    20210822 good~~~!
  8. 드림보이
    수강완료했습니다...
  9. 낭만고양이
    수강완료 ES6을 따로 공부해야겠네요
  10. Yosi Gom
    이번 강의도 설명 참 잘하셔
    대화보기
    • Amousk
      좋은 강의 감사합니다.
    • ㄱㅁㅎㅁ
      2015년 ES6에서 클래스 선언이 추가 되었습니다~ 강의가 2014년 강의라 자바스크립트에는 클래스가 없다고 하셨지만.. 참고하세요!
    • 금도끼은도끼
      자바하구 묘하게 닮았네요...
    • gf0308
      자바스크립트에서 객체생성의 주체는 '함수'이다.
      명쾌하게 정리되었습니다
      감사합니다 이고잉님
    • hanel_
      21.2.24
    • 자바스크립트는 특이하게 생성자 함수를 활용해 객체를 만든다. 즉 함수가 곧 객체인 상황. 객체 속 함수는 메소드, 변수는 프로퍼티라고 한다.
    • 강승
      감사합니다.
    • 박병진
      감사합니다. 2020.10.27
    • 코딩중독
      엄청나게 어려울까봐 큰일났네 싶었는데 그렇게 어렵진 않네요^^ 다행입니다.
    • ironia
      그래도 크게 다르지 않네요 많이 겁먹었다가 괜찮아졌습니다. ㅋㅋ
    • 한강
      좋은 아침입니다. ^^!
    • 한강
      굿모닝~~! 200319
    • 굼벵이
      완료
    • 없으면안돼요
      완료
    • 홍주호
      20191028 완료
    • 박창신
      완료
    • Dujin
      자바스크립트 강의를 보면서 document.write()의 기능을 사용할 때 줄바꿈을 위해서 <br>을 추가하시던데 document.wrireln()을 사용하시면 자동으로 줄바꿈을 해주는데 왜 <br> 태그를 추가하시는건가요? 그냥 습관인 건가요? writeln쓰면 편해요 ㅎㅎ
    • sayyoursong
      newmite0님,
      저도 js를 공부하는 입장이지만 공부차 아는만큼만 적어봅니다.

      우선 질문자님의 코드를 에러가 나지 않는 "전자"의 코드와
      에러가 나는 "후자"의 코드로 이름 부를게요.

      1.
      "사실 변수의 경우는 this로 하건
      var로 선언하건 정상작동이 되더군요.
      그런데 함수의 경우는 에러가 나요...."

      이 부분 답변 드리자면 p1에 도트연산자(.)를 사용해
      변수 age와 함수 calAge()를 호출하고 싶으셨던 것 같은데요, 후자의 방법으론 둘다 불가능합니다.

      작성하신 코드에서 변수 부분은 에러나지 않았다 하셨는데요,
      p1.age = 22;
      이 코드는 (person이 들어있는) p1에 age라는 프로퍼티를 "동적으로 생성"한 후, 22라는 값을 대입한 것입니다.
      그러니까 p1에 age라는 프로퍼티가 없더라도 생성해서 값을 넣은 거에요.

      그리고 메서드 호출이 안 되신 것은 p1에 해당 메서드가 존재하지 않기 때문입니다.
      new person("newmite0");
      -> 이렇게 객체 생성을 했다고 해서 p1에 name, age, calAge란 프로퍼티가 존재하지 않습니다. (★을 참조)

      ★ 왜 함수 내의 변수를 p1.age 처럼 도트연산자(.)를 이용해 부를 수 없냐고 물으신다면
      자바스크립트에서는 그렇게 약속되어있다고 알고 있습니다.
      자바스크립트에서 도트연산자로 뭔갈 가져오고 싶으시다면 Json 형식으로 작성하셔야 합니다.

      var 렉시컬 = {
      프로퍼티명1 : 값,
      프로퍼티명2 : function() {
      return document.write('문자열');
      }
      }
      document.write(렉시컬.프로퍼티명1);
      렉시컬.프로퍼티명2();

      이렇게 작성하신다면 정상작동할거에요.


      2. 전자와 후자의 차이
      전자가 실행되는 이유를 아시려면 this를 살펴보셔야 되는데요,
      person 함수 내에 console.log(this); 를 추가하고 크롬 - 개발자도구 - 콘솔에서 확인하시면
      this에 person이 들어있는 것을 보실 수 있을거에요.
      그러므로 전자의 코드는 아래처럼 이해할 수 있겠지요.

      1: function person(in_name) {
      2: person.name = in_name;
      3: person.age;
      4: person.calAge = function() {
      5: return document.write('my name is '+person.name+'<br>');
      6: };
      7: }
      8:
      9: p1 = new person('newmite0');
      a: p1.calAge();
      b: p1.age = 22;
      c: document.write('my age is '+p1.age+'<br>');

      9행이 실행되면서 함수 person안을 타고들어갈 텐데요,
      2행: 지금 실행되는 person 객체에 name이란 프로퍼티를 동적으로 추가한 후 in_name을 대입해주었습니다.
      3행: 지금 실행되는 person 객체에 age란 프로퍼티를 호출합니다만, age가 없으므로 만약 document.write를 사용했다면 undefined가 떴겠군요.
      4~6행: 지금 실행되는 person 객체에 calAge란 메서드를 동적으로 추가한 후, 익명함수를 대입해주었습니다. 익명함수의 return 값에 person.name이 사용되네요.
      ->결과적으로 p1안에는 person이 들어있는데, 그 person 안에는 프로퍼티로 name, calAge 가 존재하는 것이지요. age는 없습니다.

      그리고
      a행: p1의 프로퍼티 calAge()를 실행
      b행: p1에 프로퍼티 age를 동적으로 생성한 후 22를 대입
      c행: p1의 프로퍼티 age에 담긴 22를 사용해 document.write()실행.


      도움이 되셨으면 좋겠습니다.
    • newmite0
      질문 하나 드립니다.
      function person(in_name)
      {
      this.name = in_name;
      this.age;
      this.calAge = function() {
      return document.write('my name is '+this.name+'<br>');
      }
      }

      p1 = new person('newmite0');
      p1.calAge();
      p1.age = 22;
      document.write('my age is '+p1.age+'<br>');

      상기 소스의 경우는 정상 작동이 되며 문제가 없습니다.



      그런데

      function person(in_name)
      {
      var name = in_name;
      var age;
      var calAge = function() {
      return document.write('my name is '+name+'<br>');
      }
      }

      p1 = new person('newmite0');
      p1.calAge();
      p1.age = 22;
      document.write('my age is '+p1.age+'<br>');

      위와 같이 하면 p1.calAge()에서 에러가 나요. calAge가 notfound라는 에러가 나옵니다.
      이유를 모르겠습니다. 객체안의 함수를 호출한것 뿐인데...사실 변수의 경우는 this로 하건
      var로 선언하건 정상작동이 되더군요.
      그런데 함수의 경우는 에러가 나요....

      알고 계신분의 답글을 부탁드릴께요...
      감사합니다..
    • nathanEast
      정말 저에겐 사막의 오아시스같은 강의 입니다
      정말정말 감사합니다 이고잉님 ㅠㅠ!!
    • ㅇㅇ
      new가 리턴값으로 돌려줘서 객체를 형성한다는 말을 걍 쉽게 풀어서 생각하면
      함수를 복붙해서 새 폴더로 만들어준다고 생각하면 쉬울듯?
    • Wonni132
      저도 NOV 님과 같은 의문을 갖고 있었는데요, 이 다음다음 강의 (this 강의) 내용중에 다음과 같은 설명이 나옵니다

      "생성자가 실행되기 전까지는 객체는 변수에도 할당될 수 없기 때문에 this가 아니면 객체에 대한 어떠한 작업을 할 수 없기 때문이다."

      혹시 여기에 답이 있는것은 아닐까요? 혹시해서 실험해보니, NOV 님 코드 실행후에

      console.log(window.name)

      하면 'egoing' 이 출력됩니다. 저도 잘 이해한건지는 모르겠네요 ㅜㅜ
      대화보기
      • egoing
        new를 안쓰면 그냥 함수를 호출한 것이고,
        new를 쓰면 그 함수를 객체의 생성자로서 호출한 것입니다.
        그 결과 값은 객체가 됩니다.
        이것은 단지 약속일 뿐이랍니다.
        대화보기
        • 마지막 수업에서
          Person을 생성자를 안쓰고 아래와 같이 person으로 하고 실행하면 왜 안되는 건가요?

          function person(name){
          this.name = name;
          this.introduce = function(){
          return 'My name is ' + this.name;
          }
          }
          var p1 = person('egoing');
          document.write(p1.introduce()+"<br/>");
        • 스네이프
          마법같은 강의
        • 호두
          나중에 다시 볼 것
        • choon
          감사합니다.
        • 미완성
          20190109
        • pakimchi
          function person() 이 생성자.
          이를 new 와 같이 호출하면 person 객체가 위 생성자의 내용으로 만들어 지는 것.
          대화보기
          • 김주현
            생성자라는 말이 잘 와닿지 않습니다. Construct-객체를 생성하는 함수

            함수 앞에 new를 붙이면 객체가 생성되는데 new Person자체가 생성자인가요? Person이 생성자인가요?
          • 스탐
            감사합니다.
          • 땔감
            갓-고잉
          • 쏘르
            아주 중요한 개념을 새삼 상기하였습니다. 고맙습니다.
          • def dict
            감사합니다!
          • moon
            감사합니다!
          • 안장호
            감사합니다~! ^^
          • 김진홍
            감사합니다~!
          • 박인호
            12-18
            수강완료.
            생성자란 객체를 만드는, 정의하는 함수로 생성자 안에 생성될 객체의 속성 및 메소드(함수)를 정의 할 수 있다.(초기화)
            이 방법을 통해 같은 맥락을 가진 객체를 여러개 생성 할 때 코드의 재활용성을 높여준다.
            *this는 해당 메소드를 포함하고 있는 변수를 가리킨다.
          • Jupi
            생성자는 객체를 만드는 함수.
            함수에 new를 붙이면 새로운 객체를 만들어 리턴.
            생성자에 객체에서 쓸 프로퍼티, 메소드등을 정의하면 new 생성자이름(인자) 한번 실행 하는 것으로,
            인자와 관련된 객체를 쓱싹하고 만들 수 있다.

            이러한, 생성자를 하나 만들어 놓으면 붕어빵 기계에서 붕어빵(객체)을 편하게 찍어낼 수 있다.
            여기서 붕어빵기계(생성자)에 안에 팥이 들어가냐, 크림이 들어가냐 , 얼마만큼 구울거냐 하는
            속성들을 정의하는 과정을 초기화(init) 라고 할 수 있다.
          • 고스트프리
            이고잉님!~ 다른게 아니라 새로운페이지로 링크를 거실때 새창으로 띄워주세요... shift누르고 하면되긴하지만.... 약간 불편한게 있는거같습니다.

            감사합니다.
            대화보기
            버전 관리
            egoing
            현재 버전
            선택 버전
            graphittie 자세히 보기