생성자 함수에 의한 객체 생성
1. 생성자 함수란?
- 정의 : 생성자 함수는 특정 객체 형태를 생성하는 데 사용되는 함수입니다. 생성자 함수는 일반 함수와 문법적으로 차이가 없지만, 관례적으로 함수 이름의 첫 글자를 대문자로 시작합니다.
- 사용 방법 : `new` 키워드와 함께 호출하여 새로운 객체를 생성합니다.
2. 생성자 함수의 동작 원리
`new` 키워드로 생성자 함수를 호출할 때 다음과 같은 일이 발생합니다.
1. 새로운 객체 가 생성됩니다.
2. this 는 생성된 새로운 객체를 참조하게 됩니다.
3. 생성자 함수 내에서 `this`에 프로퍼티나 메서드를 추가하면, 새로운 객체에 해당 프로퍼티와 메서드가 정의됩니다.
4. 명시적으로 `return` 값을 지정하지 않으면, 함수가 자동으로 새로 생성된 객체를 반환합니다.
3. 생성자 함수 작성 및 사용 예시
function User(name, age) {
this.name = name;
this.age = age;
this.sayHello = function() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};
}
let user1 = new User("Alice", 25);
let user2 = new User("Bob", 30);
user1.sayHello(); // "Hello, my name is Alice and I am 25 years old."
user2.sayHello(); // "Hello, my name is Bob and I am 30 years old."
4. 생성자 함수의 특징
- 객체 프로퍼티와 메서드 초기화 : 생성자 함수 내부에서 `this`를 사용하여 객체의 프로퍼티와 메서드를 초기화합니다. 각 객체는 생성자 함수에 전달된 인수에 따라 고유의 값을 가지게 됩니다.
- 메모리 효율성 : 메서드가 생성자 함수 내부에 정의될 경우, 생성된 각 객체마다 독립적인 메서드가 생성되어 메모리를 다소 비효율적으로 사용할 수 있습니다. 이를 개선하기 위해 프로토타입을 활용해 공통 메서드를 정의할 수 있습니다.
5. 프로토타입을 통한 메서드 공유
생성자 함수에서 프로토타입 객체를 사용하여 메서드를 정의하면, 해당 메서드는 생성된 모든 객체가 공유하므로 메모리를 절약할 수 있습니다.
function User(name, age) {
this.name = name;
this.age = age;
}
User.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};
let user1 = new User("Alice", 25);
let user2 = new User("Bob", 30);
user1.sayHello(); // "Hello, my name is Alice and I am 25 years old."
user2.sayHello(); // "Hello, my name is Bob and I am 30 years old."
6. 생성자 함수와 클래스의 차이
ES6에서는 클래스 문법이 도입되어 생성자 함수와 유사한 기능을 제공합니다. 하지만 클래스 문법이 더 간결하고, 생성자 함수와 달리 클래스는 상속 및 정적 메서드를 간편하게 지원합니다. 클래스는 생성자 함수보다 더 직관적인 객체 지향 프로그래밍 스타일을 제공합니다.
요약
- 생성자 함수 : 객체를 초기화하는 함수로, `new` 키워드를 통해 호출됩니다.
- 프로퍼티와 메서드 : `this`를 사용하여 객체의 프로퍼티와 메서드를 정의합니다.
- 프로토타입 : 메서드를 공유하여 메모리 효율성을 높일 수 있습니다.
- 클래스와의 관계 : 클래스는 생성자 함수의 대안으로, 더 직관적인 객체 생성 및 관리 방식을 제공합니다.
생성자 함수는 여전히 객체 생성을 위한 기본 개념으로 활용되며, 클래스를 통해 더욱 간편하게 사용할 수 있습니다.
함수와 일급객체
1. 일급 객체란?
일급 객체(first-class citizen)란 다른 데이터와 마찬가지로 함수가 변수에 할당되거나, 다른 함수의 인자로 전달되거나, 함수의 반환값이 될 수 있는 특성을 가진다는 의미입니다. 자바스크립트에서 함수는 일급 객체이기 때문에 다음과 같은 작업들이 가능합니다:
-변수에 함수 할당 : 함수를 변수에 할당할 수 있습니다.
- 함수 인자로 전달 : 함수를 다른 함수의 인자로 전달할 수 있습니다.
- 함수에서 함수 반환 : 함수를 다른 함수의 결과값으로 반환할 수 있습니다.
- 객체의 프로퍼티로 할당 : 함수를 객체의 프로퍼티로도 사용할 수 있습니다.
2. 함수가 일급 객체로서 가지는 특징
자바스크립트에서 함수가 일급 객체로서 갖는 특징은 아래와 같습니다.
(1) 변수에 할당할 수 있다
const greet = function() {
console.log("Hello, World!");
};
greet(); // "Hello, World!"
(2) 함수의 인자로 전달될 수 있다
function executeFunction(fn) {
fn();
}
executeFunction(greet); // "Hello, World!"
(3) 함수에서 함수를 반환할 수 있다
function createGreeter(name) {
return function() {
console.log(`Hello, ${name}!`);
};
}
const greeter = createGreeter("Alice");
greeter(); // "Hello, Alice!"
(4) 객체의 프로퍼티로 할당할 수 있다
const user = {
name: "Bob",
greet: function() {
console.log(`Hello, ${this.name}!`);
}
};
user.greet(); // "Hello, Bob!"
3. 함수가 일급 객체로서 유용한 이유
- 고차 함수 : 함수가 일급 객체이기 때문에, 자바스크립트는 고차 함수를 지원합니다. 고차 함수는 함수를 인자로 받거나 함수를 반환하는 함수로, 다양한 함수형 프로그래밍 기법을 가능하게 합니다.
- 예시: `Array.prototype.map`, `Array.prototype.filter`, `Array.prototype.reduce` 등
- 콜백 함수 : 비동기 작업에서 함수가 일급 객체로 사용되면서 콜백 패턴이 가능해집니다. 예를 들어, `setTimeout`이나 `addEventListener` 같은 비동기 함수에 콜백 함수를 전달하여 작업이 완료되면 특정 로직을 실행할 수 있습니다.
setTimeout(function() {
console.log("This runs after 2 seconds");
}, 2000);
- 클로저 : 함수가 일급 객체이기 때문에 클로저를 사용할 수 있습니다. 클로저는 함수가 생성될 때의 스코프를 기억하여 함수 외부의 변수를 참조할 수 있는 기능입니다. 클로저는 함수가 외부 환경을 캡처하여 지속적으로 접근할 수 있게 합니다.
function createCounter() {
let count = 0;
return function() {
count++;
console.log(count);
};
}
const counter = createCounter();
counter(); // 1
counter(); // 2
4. 함수형 프로그래밍과 일급 객체로서의 함수
자바스크립트는 함수가 일급 객체로서 기능하기 때문에, 함수형 프로그래밍의 다양한 패러다임을 쉽게 적용할 수 있습니다. 특히, 순수 함수, 불변성, 고차 함수 등의 개념을 활용하여 복잡한 로직을 간결하게 구현할 수 있습니다.
요약
자바스크립트에서 함수는 일급 객체로 취급되며, 변수 할당, 인자 전달, 함수 반환 등의 작업을 자유롭게 수행할 수 있습니다. 이를 통해 고차 함수 , 콜백 함수 , 클로저 와 같은 패턴이 가능해지며, 자바스크립트는 함수형 프로그래밍에 유리한 언어로서의 특성을 가지게 됩니다. 이러한 특성들은 자바스크립트를 강력하고 유연한 프로그래밍 언어로 만들어 주며, 다양한 프로그래밍 스타일을 지원할 수 있게 해줍니다.
프로토타입
1. 프로토타입이란?
- 정의 : 프로토타입은 객체가 상속받는 부모 객체 또는 그 객체의 청사진 역할을 합니다. 모든 자바스크립트 객체는 숨겨진 `[[Prototype]]`이라는 링크를 가지고 있으며, 이를 통해 상위 객체의 프로퍼티와 메서드에 접근할 수 있습니다.
- 역할 : 프로토타입을 통해 객체가 다른 객체의 메서드와 속성을 상속받아 사용하고, 반복적으로 정의하지 않고도 공통 메서드를 공유할 수 있게 해줍니다.
2. `__proto__`와 `prototype` 속성의 차이
- `__proto__` : 자바스크립트 객체의 숨겨진 링크로, 객체가 직접 상속하는 프로토타입 객체를 참조합니다. 모든 객체는 `__proto__`를 통해 부모 객체와 연결됩니다.
- `prototype` : 함수(특히 생성자 함수)에서만 존재하는 속성으로, 이 속성은 해당 생성자 함수를 통해 생성된 모든 인스턴스가 공유하는 프로토타입 객체를 가리킵니다.
function User(name) {
this.name = name;
}
User.prototype.greet = function() {
console.log(`Hello, ${this.name}!`);
};
const user1 = new User("Alice");
user1.greet(); // "Hello, Alice!"
위 예제에서 `User.prototype` 객체가 모든 인스턴스의 `__proto__`로 연결되며, 이를 통해 `greet` 메서드를 공유하게 됩니다.
3. 프로토타입 체인
프로토타입 체인은 객체가 특정 프로퍼티나 메서드를 찾을 때, 해당 객체의 `__proto__`를 따라 상위 프로토타입 객체로 거슬러 올라가는 과정입니다. 프로토타입 체인을 통해 상속을 구현하며, 프로퍼티가 발견되거나 최상위 객체인 `Object.prototype`에 도달할 때까지 탐색합니다.
- 동작 방식 : 자바스크립트 엔진은 객체에 없는 속성이나 메서드를 호출할 때 `__proto__` 링크를 따라 프로토타입 체인에서 찾습니다.
const obj = {};
console.log(obj.toString()); // Object.prototype의 메서드 toString을 호출
4. 프로토타입 상속의 활용
프로토타입 상속을 활용하면 메서드를 모든 인스턴스에 개별적으로 정의하지 않고도 공유할 수 있습니다. 생성자 함수나 클래스를 사용할 때 프로토타입에 메서드를 정의하면 메모리를 절약하고 효율적으로 메서드를 관리할 수 있습니다.
- 공통 메서드 정의 : 프로토타입에 공통 메서드를 정의하여 메모리 효율성을 높일 수 있습니다.
- 상속 관계 설정 : 자바스크립트에서 `Object.create` 또는 `class` 문법을 통해 객체 간 상속 관계를 설정할 수 있습니다.
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a noise.`);
};
const dog = new Animal("Dog");
dog.speak(); // "Dog makes a noise."
5. 클래스와 프로토타입
ES6의 클래스 문법은 프로토타입 기반 상속을 더 직관적으로 사용할 수 있도록 도입된 문법적 설탕입니다. 클래스는 생성자 함수와 프로토타입을 쉽게 작성하고 상속 관계를 설정할 수 있게 합니다.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
const cat = new Animal("Cat");
cat.speak(); // "Cat makes a noise."
요약
- 프로토타입 : 객체가 상속받는 부모 객체로, 다른 객체의 프로퍼티와 메서드를 공유할 수 있습니다.
- `__proto__` : 객체가 직접 상속받는 프로토타입 객체를 가리킵니다.
- `prototype` : 함수(특히 생성자 함수)가 가지는 속성으로, 생성된 모든 인스턴스가 이 프로토타입 객체를 공유합니다.
- 프로토타입 체인 : 객체가 특정 속성을 찾을 때 프로토타입 체인에서 검색하는 과정입니다.
- ES6 클래스 : 프로토타입 기반 상속을 더 직관적으로 사용할 수 있도록 도입된 문법으로, 자바스크립트의 객체지향 프로그래밍을 더 쉽게 만듭니다.
프로토타입은 객체 상속과 재사용성 면에서 중요한 개념이며, 클래스와 함께 사용하면 객체지향 프로그래밍을 더 쉽게 구현할 수 있습니다.