[자바스크립트] 생성자 함수

박지원·2023년 3월 26일
0

1차 스터디

목록 보기
8/13

▷ 객체를 생성하는 방법

1. 객체 리터럴

#1

let ob = {};

객체를 리터럴로 생성하는 방법이다. 빈 객체를 리터럴로 생성하기 위해서는 중괄호 {}를 변수에 할당하면 된다.

하지만 객체의 중괄호는 코드 블록을 의미하지 않는다.

코드 블록문은 문의 종료를 의미하는 자체 종결성을 가지고 있어서
예를 들면 함수의 중괄호나 제어문의 중괄호 같은 경우, 끝에 세미콜론 ;을 붙이지 않는다.

따라서 객체에는 마지막에 세미콜론 ;을 붙여준다.

객체 리터럴로 객체를 생성하는 것은 뭔가 보기에도 직관적이고 편해보이지만, 하나의 객체만 생성하기 때문에 value가 다른 여러 객체를 생성해야 하는 경우에는 비효율적이다.
100명의 신원 정보를 나타대기 위해서는 100개의 객체 리터럴을 생성해야 하기 때문이다.

따라서 이런 부분은 생성자 함수를 통해 효율적으로 구현할 수 있다.


2. 생성자 함수로 인스턴스 만들기

#2

function User(name) {
    this.name = name;
    this.getNameLength = function () {
        return this.name.length;
    }
}

let user1 = new User('muzi');
let user2 = new User('frodo');

console.log(user1.getNameLength()) // 4
console.log(user2.getNameLength()) // 5

생성자 함수를 사용하는 경우에는 해당 함수의 이름 첫 글자를 대문자로 기입한다. 이런 규칙이 필요조건은 아니지만, 이 함수가 생성자 함수임을 구분하기 위한 관례라고 한다.

여기서 중요하게 봐야 할 것은 this키워드new키워드이다.

> this

먼저 name앞에 this키워드가 붙어있는데, 꼴을 보면 임의의 객체를 의미하는 것 처럼 보인다.

#3

let thiss = {
	name: 'muzi'
};

console.log(thiss)      // {name: 'muzi'}
console.log(thiss.name) // muzi

위 코드와 같이 thiss라는 이름의 객체를 선언했다고 가정해보았다.
여기서 우리가 muzi를 출력하려면 thiss.name꼴의 리터럴로 접근해야 한다.

다시 돌아와서

자바스크립트에는 전역에서 window( global )로 이미 정의된 전역 객체가 있고, this가 해당 전역 객체를 바인딩하고 있다. 따라서 windowthis의 default값이다.

하지만 window로 안쓰고 this라고 쓰는 이유는 this가 어느 객체든지 동적으로 바인딩 할 수도 있기 때문이다.( -> 내생각 )

나중에 더 자세히 작성할 내용이지만, 일반 함수 내부에서 this를 선언하면 함수의 호출 방법에 따라서 this가 가리키는 객체가 동적으로 결정된다.


> new

#4

function User(name) {
    this.name = name;
    this.getNameLength = function () {
        return this.name.length;
    }
	console.log(this) // User {name: 'muzi', getNameLength: ƒ}
}

let user1 = new User('muzi');
//let user2 = new User('frodo');

//console.log(user1.getNameLength())
//console.log(user2.getNameLength())

#2번 코드를 그대로 가져와, User함수 안에서 this를 콘솔로 찍어보니까 User객체가 출력되었다.

이는 User함수 안의 thisUser라는 객체를 바인딩하고 있다는 뜻이다.
그러면 객체는 언제 생성한걸까?

let user1 = new User('muzi'); 

이 구문이 바로 User객체 생성의 근원이다.

new키워드와 함께 함수를 호출하면, 함수의 내부에서 this로 선언한 프러퍼티들을 그대로 가져와 객체를 반환한다.

이렇게 생성된 객체를 인스턴스라고 부른다.

따라서 우리가 인스턴스를 생성하기 위해서 해야하는 일을 요약하면 아래와 같다.

  1. 함수 이름 첫 글자 대문자로 적어
  2. 함수 내부에 this.~ 로 미래의 프러퍼티 정의 ( ~ 는 인스턴스의 프로퍼티가 될 예정 )
  3. 이렇게 만든 함수를 new키워드와 함께 호출
  4. 이걸 변수에 할당시켜서 구조가 동일한 객체 여러 개를 생성 할 수 있음

> 추가) 함수를 그냥 호출했을 때 this값

#5

function User() {
    //this.name = name;
    //this.getNameLength = function () {
    //    return this.name.length;
    //}
	console.log(this) // window {...}
}

//let user1 = new User('muzi');
//let user2 = new User('frodo');

//console.log(user1.getNameLength())
//console.log(user2.getNameLength())

User()

만약에 위의 코드 처럼 User 함수를 생성자 함수로 만들지 않고 그냥 호출한다면, thiswindow객체를 가리킨다.


▷ 함수의 내부 메서드

함수는 객체라서, 일반 객체가 가지고 있는 내부 슬롯이나 메서드들을 가지고 있다.

하지만 함수는 일반 객체와는 다르다. 일반 객체는 호출할 수 없지만, 함수는 호출할 수 있기 때문이다. 따라서 함수는 객체 메서드에 이어 [[Call]][[Constructor]]메서드를 추가로 가지고 있다.

함수가 일반 함수로 호출되면 [[Call]]이 호출되고, 생성자 함수로 호출되면 [[Constructor]]가 호출된다.

따라서 생성자 함수는 함수 선언언문이나 표현식으로도 만들 수 있기 때문에 모든 함수는 [[Call]]이 호출 될 수 있다.

반면 new키워드와 함께 호출할 수 없는 함수 형태인 메서드화살표 함수는 생성자 함수로 호출할 수 없기 때문에 [[Constructor]]를 가지지 않는다. 이런 함수 객체를 non-constructor라고 부른다.

Call : 모든 함수
Constructor : 함수 선언문, 함수 표현식, 클래스( 클래스도 함수다 )
non-constructor : 메서드, 화살표 함수

profile
NodeJS 백엔드

0개의 댓글