본문으로 바로가기

생성자 함수

category JavaScript/기초 2020. 10. 1. 02:43

생성자 함수

자바스크립트에서 생성자 함수는 말그대로 객체를 생성하는 역할을 한다

이러한 생성자 함수는 형식이 다르게 정해져있진 않고 기존 함수에 new 명령어를 붙여서 호출하면 그 함수가 생성자 함수로 동작하게 된다

이렇게 생성자 함수와 일반 함수가 다르게 정해져 있지 않기 때문에 대부분의 개발자들이 생성자 함수의 이름 첫 글자를 대문자로 쓴다

    var Student = function(name, grade){
        this.name = name;
        this.grade = grade;
    }

    var st1 = new Student('아무개', '4학년');

Student생성자 함수로 st1객체를 만든 코드이다

궁금한 점이 생긴다 "이 this들은 뭘까?"

생성자 함수에서의 this

이전 포스팅을 기억한다면 저 함수 안의 this들은 전역 객체 즉, window객체를 바라보고 있다

한번 테스트 해 보자

    var Student = function(name, grade){
        this.sName = name;
        this.grade = grade;
    }

    var st1 = new Student('아무개', '4학년');

    console.log(window.sName);
    console.log(window.grade);

위 코드의 결과

왜 이럴까?

생성자 함수에서의 this는 조금 다르게 작동하는데

우리는 생성자 함수를 동작시킬 때의 new에 주목해야한다

new가 붙은 생성자 함수가 실행되기 전에는 빈 객체가 생성된다고 생각하면 된다

생성자 함수에서의 this는 바로 이 빈 객체를 가르키고, 생성자 함수 내부의 코드가 실행이 끝나고 나면

암묵적으로 이 this가 가르키는 객체가 리턴된다 (리턴값을 명시하면 명시한 값이 리턴된다)

제일 첫 코드를 다시 살펴보자

이 this들은 새로운 객체를 가르키고 있었고 그 객체는 st1에게 리턴되었다

그 값들을 출력하고 싶다면?

    var Student = function(name, grade){
        this.sName = name;
        this.grade = grade;
    }

    var st1 = new Student('아무개', '4학년');
    console.log(st1.sName);
    console.log(st1.grade); 

위 코드의 결과

우리가 바라는 결과가 출력되었다!

 

 


new를 빠뜨린다면?

위에서 본 바로는 생성자 함수와 일반 함수는 차이가 없고 new로만 구분된다고 했다

만약 누군가가 실수로 생성자 함수로 만든 Student함수를 new없이 객체 생성을 시도한다면 어떻게 될까?

    var Student = function(name, grade){
        this.sName = name;
        this.grade = grade;
    }

    var st1 = Student('아무개', '4학년');
    console.log(st1.sName);
    console.log(st1.grade);

이전 포스팅에서 배웠기 때문에 우리는 일반 함수의 this가 어떻게 작동하는지 잘 알고있다

바로 window객체에 변수들이 선언,초기화 되어서 우리가 원하는 st1객체는 올바르게 만들어 지지않는다

위 코드의 결과

이러한 문제를 피하기 위해서 앞서 소개했듯이 생성자 함수는 첫 글자를 대문자로 표기하는데

그렇게 표기하여도 결국 new를 붙이지 않으면 우리가 원하는대로 굴러가지 않는다

그래서 자바스크립트 전문가들은 객체를 생성하는 생성자 함수 코드에 이러한 코드 패턴을 사용한다

    var Student = function(name, grade){
           if(!(this instanceof Student))
            return new Student(name,grade);
        this.sName = name;
        this.grade = grade;
    }

    var st1 = Student('아무개', '4학년');
    console.log(st1.sName);
    console.log(st1.grade);

함수 이름 바로 아래에 추가된 코드를 풀이하면

실행된 코드의 this가 Student의 인스턴스인지를 확인하고 그렇지 않으면 new를 사용하지 않은 즉, 잘못된 생성자 함수 호출을 의미하기 때문에

new Student로 다시금 생성자 함수를 호출하게 하는 코드이다

결과값은

위 코드의 결과

생성자 함수를 new로 호출하지 않았음에도 정상적으로 객체가 생성된 것을 확인할 수 있다

'JavaScript > 기초' 카테고리의 다른 글

closure  (0) 2020.10.03
호출 스택, 이벤트 루프  (0) 2020.10.02
this binding  (0) 2020.09.30
실행 컨텍스트와 스코프  (0) 2020.09.28
호이스팅  (0) 2020.09.28