일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 자바스크립트 연결리스트
- 리액트쿼리
- 프로그래머스
- JavaScript
- Baekjoon
- 자바스크립트 문제 풀이
- next13
- stack문제
- leetcode
- lodash
- 프론트엔드
- NPM
- 알고리즘문제풀이
- 타입스크립트
- 자바스크립트
- CSS
- til
- Next.js13
- HTML
- 자바스크립트 문제
- 자바스크립트 알고리즘
- 리액트
- leetcode문제풀이
- JS
- 제로베이스
- Next
- react
- 자바스크립트코딩테스트
- 자바스크립트 문제풀이
- 자바스크립트 알고리즘 문제
- Today
- Total
코드노트
자바스크립트 Object 객체 생성자 함수 본문
Object 생성자 함수
- new 연산자와 Object 생성자 함수를 호출하게 되면 빈 객체를 생성하여 반환
- 빈 객체를 생성한 후 프로퍼티, 메서드를 추가해 객체를 완성
- 생성자 함수에 의해 생성된 객체를 인스턴스(instance)라 한다.
const tranvel = new Object();
tranvel.first = "곽튜브";
tranvel.hello = function () {
console.log(`Hi! ${this.first}`);
};
console.log(tranvel); // { first: '곽튜브', hello: [Function] }
tranvel.hello(); // Hi! 곽튜브
- new 연산자로 객체를 생성하고 프로퍼티를 추가할 수 있다.
- Object 외에도 String, Number, Boolean, Function, Array, Date, RegExp, promise 등등 빌트인 생성자 함수를 만들 수도 있다.
그러나 Object 생성자 함수로 하는것 보단, 객체리터럴 방식으로 하는게 더 직관적이고 간편하게 사용할 수 있다.
그러면 생성자 함수는 어떻게 쓰일까?
만약 같은 값이나 메서드를 가진 객체를 사용하는데 여러개의 객체를 만들어야 한다면?
같은 함수를 반복하여 작성하지 않고 생성자 함수를 사용하여 간편하게 생성하면 된다.
function Add(num) {
this.num = num;
this.getAdd = function () {
return num + this.num;
};
}
const one = new Add(1);
const two = new Add(2);
console.log(one.getAdd()); // 2
console.log(two.getAdd()); // 4
- 함수는 하나만 생성하고 num값을 가진 객체를 만들어준다.
- 생성자 함수를 사용해서 프로퍼티 구조가 같은 객체를 여러개 만들더라도 간편하게 만들 수 있다.
여기서 this 는?
- 객체 자신의 프로퍼티 또는 메서드를 참조하는 변수 이다.
- this가 가리키는 값, this 바인딩은 함수 호출 방식에 따라서 동적으로 결정
함수 호출 방식 | this가 가리키는 값(this 바인딩) |
일반 함수로서 호출 | 전역 객체 |
메서드로서 호출 | 메서드를 호출한 객체(마침표 앞의 객체) |
생성자 함수로서 호출 | 생성자 함수가 생성할 인스턴스 |
▶ 일반함수에서 사용하면 전역window를 가르킨다.
▶ 메서드로 호출하게 되면 호출한 객체를 가르킨다.
▶ 생성자 함수가 생성하는 인스턴스(생성된 객체)를 가르킨다.
생성자 함수는 빈객체를 만들거나 반환하는 것을 자바스크립트가 암묵적으로 처리한다.
- 인스턴스 생성 및 반환을 암묵적으로 처리
* 생성자 함수에서는 return 문을 생략 해야한다! 그렇지 않으면 생성자 함수의 기본 동작을 훼손한다.
- 메서드 외에 returm은 사용하지 말자!
== this가 반환되지 않고, return 문에 명시한 객체가 반환된다.
내부 메서드 [[call]], [[construct]]
- 일반 함수도 new 연산자를 통해 생성자 함수로 호출할 수 있다.
- 함수는 객체이기 때문에 일반 객체와 동일하게 동작 한다.
- 그러나 함수는 일반 객체와는 다르다. 일반 객체는 호출할 수 없지만, 함수는 호출이 가능하다.
* 함수 객체는 함수로 동작하기 위한 내부 슬롯, 내부 메서드를 가지고 있다.
내부 슬롯 : [[ Environment ]], [[ FormalParameters ]]
내부 메서드 : [[ Call ]], [[ Construct ]]
- 함수가 일반 함수로 호출 되면 함수 객체의 내부 메서드 [[ Call ]]이 호출
- new 연산자, 생성자 함수가 호출 되면 내부 메서드 [[ Construct ]]가 호출
[[ Call ]]을 갖는 함수 객체 callable
[[ Construct ]]를 갖는 함수 객체 constructor
[[ Construct ]]를 갖지 않는 함수 객체non-constructor
* callable : 호출할 수 있는 객체, 함수
* constructor : 생성자 함수로서 호출할 수 있는 함수
* non-constructor : 객체를 생성자 함수로 호출할 수 없는 함수
- 호출할 수 없는 객체는 함수 객체가 아니다.
- 호출이 가능한 함수 객체는 반드시 callable이어야 한다.
** 모든 함수 객체는 내부 메서드 [[ call ]]을 가지고 있기 때문에 호출 가능
*** 그 함수 객체중 모두 [[ construct ]]를 갖는건 아니다.
그렇기 때문에 함수 객체는 모두 호출할 수 있지만, 생성자 함수로서 호출할 수는 없다.
그럼 constructor, non-constructor은 어떻게 구분할까?
- 함수 정의를 평가하고 함수 객체를 생성할 때 함수 정의 방식에 따라서 함수를 구분한다.
▶ constructor
- 함수 선언문, 함수 표현식, 클래스
▶ non-constructor
- 메서드, 화살표 함수
여기서 알 수 있는 TIP
- 함수를 프로퍼티 값으로 사용하면 일반적으로 메서드로 통칭
* 함수가 할당된 위치가 아닌 일반 함수, 함수 선언문, 함수 표현식으로 정의된 함수만 constructor
* 반대로 생각하면 축약 및 화살표 함수로 생성한 함수는 메서드다.
new 연산자로 호출하는 함수는 constructor 이어야 한다.
- 어렵게 생각하지말고 재사용할 함수는 첫 문자를 대문자로!
- this 바인딩
- new를 붙여 실행하면 된다.
function Person(name) {
// 암묵적으로 인스턴스 생성 및 this에 바인딩 this = {}
this.name = name;
this.sayHello = function () {
console.log(`내 이름은 ${this.name} 입니다.`);
};
}
const person1 = new Person("곽튜브");
person1.sayHello(); // 내 이름은 곽튜브 입니다.
new.target
* new.target은 this와 유사하게 constructor인 모든 함수 내부에서 암묵적인 지역 변수와 같이 사용되며, 메타 프로퍼티라 부른다.
function Person(name) {
this.name = name;
this.sayHello = function () {
console.log(`내 이름은 ${this.name} 입니다.`);
};
}
console.log(Person()); // undefined
console.log(new Person()); // Person { name: undefined, sayHello: [Function] }
- 간단하게 보면 new.target은 함수가 new연산자로 호출되었는지 아닌지 알 수 있다.
- 일반 함수로 호출이 되었다면 Undefined를 반환, new와 함께 호출 되었다면 함수를 반환
function Person(name) {
if (!new.target) {
return new Person(name);
}
this.name = name;
this.sayHello = function () {
console.log(`내 이름은 ${this.name} 입니다.`);
};
}
console.log(Person()); // Person { name: undefined, sayHello: [Function] }
console.log(new Person()); // Person { name: undefined, sayHello: [Function] }
- 위와 같은 코드이지만 if문을 통해서 new.target을 통해서 undefined가 나오지 않게 new를 붙여 호출하도록 해준다.
- 이렇게 하면 new 연산자를 사용하지 않아도 함수 호출시 new연산자로 사용이 가능하다.
그러나 코드를 보고 new가 붙어 있으면 생성자함수인것을 바로 알 수 있듯이 좋아 보이지는 않는다.
'Code note > 자바스크립트' 카테고리의 다른 글
프로토타입 기반의 객체지향 언어, 자바스크립트 프로토타입 이해 (0) | 2022.12.19 |
---|---|
자바스크립트 함수 객체 프로퍼티 정리 (0) | 2022.12.15 |
자바스크립트 프로퍼티 어트리뷰트(내부 슬롯, 내부 메서드) (0) | 2022.12.11 |
변수의 생명 주기 / 전역변수, 지역변수/ var의 문제점 정리, let, const (0) | 2022.12.09 |
자바스크립트 스코프(Scope) 이해하기( 렉시컬 스코프 ) (0) | 2022.12.08 |