티스토리 뷰
00. TL;DR
- 리터럴은 데이터를 직접 표현하는 방법이며, 객체는 키-값 쌍으로 구성된 데이터 구조입니다.
- 자바스크립트에서 객체를 생성하는 대표적인 방법은 객체 리터럴, 생성자 함수, Object.create이며, 각각 사용 목적과 특징이 다릅니다.
- 객체 내 프로퍼티는 데이터에 접근, 추가, 삭제, 변경이 가능하고, 메서드는 객체의 동작을 정의하는 함수입니다.
- ES6부터 메서드를 축약해서 간결하게 표현할 수 있지만, 일반 메서드, 축약 메서드, 화살표 함수는 this 바인딩, 생성자 사용 가능 여부,
- arguments 접근 등에서 큰 차이가 있으므로 정확한 이해가 필요합니다.
01. 리터럴이란?
리터럴(Literal)은 프로그래밍 언어에서 데이터 값을 소스 코드 내에 직접 표현하는 방식입니다.
이는 변수를 선언하면서 값을 즉시 할당하거나, 함수 호출 시 인수로 전달하는 등 다양한 상황에서 사용됩니다. 리터럴을 사용하면 별도의 객체 생성 과정 없이 간결하고 직관적으로 데이터를 나타낼 수 있습니다.
리터럴에 대한 추가 게시글: https://til-odin.tistory.com/48
01.01. 리터럴 종류
01.01.01. 숫자 리터럴(Number Literal)
const num = 42; // 10진수 정수 리터럴
const pi = 3.14; // 10진수 실수 리터럴
const binary = 0b1010; // 2진수 리터럴 (10)
const octal = 0o52; // 8진수 리터럴 (42)
const hexadecimal = 0x2a; // 16진수 리터럴 (42)01.01.02. 문자열 리터럴(String Literal)
const greeting = "Hello, odin!"; // 큰따옴표
const name = "odin"; // 작은따옴표
const template = `Hello, ${name}!`; // 템플릿 리터럴 (ES6)01.01.03. 불리언 리터럴(Boolean Literal)
const isAdult = true;
const isStudent = false;01.01.04. 객체 리터럴(Object Literal)
const person = { name: "odin", age: 30 };01.01.05. 배열 리터럴(Array Literal)
const arr = [1, 2, 3, 4];01.01.06. 정규표현식 리터럴 (RegExp Literal)
const regex = /^[a-z]+@[a-z]+\.[a-z]{2,3}$/; 01.01.07. null 리터럴
const emptyValue = null;리터럴은 변수에 직접 값을 할당하거나 데이터 구조를 정의하는 데 사용되어 코드의 가독성을 높이고 초기화 과정을 간편하게 만들어 줍니다.
02. 객체란?
객체(Object)는 키(key)와 값(value)의 쌍으로 데이터를 구조화하는 데이터 타입입니다.
키는 문자열 또는 Symbol 타입으로 정의 가능하고, 값은 모든 데이터 타입을 포함할 수 있습니다.
객체는 참조 타입(Reference Type) 이므로, 변수에 객체를 할당하면 실제 데이터가 아닌 메모리 상의 주소(참조)가 저장됩니다.
따라서 여러 변수가 동일한 객체를 참조할 수 있으며, 한 변수를 통해 객체의 내용을 변경하면 다른 변수에서도 그 변경 사항이 반영됩니다.
const person = {
name: "odin",
age: 30,
location: "Asgard",
hobbies: ["reading", "coding"],
greet: function () {
console.log(`Hello, I'm ${this.name}`);
},
};
객체는 현실 세계의 사물이나 개념을 프로그래밍적으로 표현하는 데 핵심적인 역할을 하며, 관련된 데이터와 기능을 하나의 논리적인 단위로 묶어 관리할 수 있게 해줍니다.
02.01. 객체에는 모든 참조 타입이 포함된다.
객체는 모든 참조 타입의 기반이 되는 자료형입니다.
다음은 각 자료형에 대한 객체 여부를 정리한 표입니다.
| 예시 코드 | 설명 | 객체인가? | 인스턴스인가? | 비고 |
|---|---|---|---|---|
{ name: "Alice" } |
일반 객체 (리터럴) | ✅ | ❌ | 클래스 기반 아님 |
[] |
배열 | ✅ | ✅ | Array 클래스의 인스턴스 |
new Date() |
날짜 객체 | ✅ | ✅ | Date 클래스의 인스턴스 |
function greet() {} |
함수 | ✅ | ❌ | Function 클래스의 객체지만 인스턴스보다는 함수 자체 |
new Car() |
사용자가 정의한 클래스 인스턴스 | ✅ | ✅ | Car 클래스의 인스턴스 |
Car |
클래스 정의 자체 | ✅ | ❌ | Function의 객체, 설계도 |
/abc/ |
정규 표현식 | ✅ | ✅ | RegExp 클래스의 인스턴스 |
123, "hello" |
원시 값 (숫자, 문자열 등) | ❌ | ❌ | 객체 아님 (프리미티브) |
null, undefined |
특수 값 | ❌ | ❌ | 객체 아님 (typeof null은 예외적으로 "object") |
03. Object 생성자 함수
Object 생성자 함수는 자바스크립트의 내장 객체로, new 연산자를 통해 빈 객체를 생성할 수 있습니다.
const obj = new Object();
obj.name = "odin";
obj.age = 30;
console.log(obj); // { name: 'odin', age: 30 }03.01. 사용 목적과 응용
- 초기 프로퍼티 없이 빈 객체를 생성할 때:
- 이후 필요에 따라 프로퍼티를 동적으로 추가할 수 있습니다.
- 다양한 타입의 인수를 처리하는 경우:
Object생성자는 인수의 타입에 따라 다른 동작을 합니다.
03.02. 실제 응용 예시
const person = new Object();
person.firstName = "odin";
person.lastName = "son";
person.age = 30;
person.greet = function() {
console.log(`Hello, my name is ${this.firstName} ${this.lastName}.`);
};
person.greet(); // Hello, my name is odin son.
const config = new Object();
config.timeout = 5000;
config.apiUrl = "/api/data";
console.log(config); // { timeout: 5000, apiUrl: '/api/data' }03.03. Object() 생성자에 인수를 넘기는 경우
Object() 생성자에 인수를 넘기면 다음과 같은 동작을 합니다.
03.03.01. 빈 값, undefined, null을 넘기는 경우
빈 객체를 반환합니다.
let o = new Object();
let o1 = new Object(undefined);
let o2 = new Object(null);
console.log(o); // {}
console.log(o1); // {}
console.log(o2); // {}03.03.02. 불리언 값을 넘기는 경우
new Boolean()을 호출한 것과 동일하게 불리언 래퍼 객체를 반환합니다
let o3 = new Object(true);
// 이는 아래와 동일합니다.
// let o3 = new Boolean(true);
console.log(o3); // Boolean {true}
console.log(typeof o3); // object
let o4 = new Object(false);
// 이는 아래와 동일합니다.
// let o4 = new Boolean(false);
console.log(o4); // Boolean {false}
console.log(typeof o4); // objectObject 생성자 함수는 기본적인 객체 생성을 제공하며, 인수의 타입에 따라 특별한 동작을 수행하여 주의해서 사용해야합니다.
04. 생성자 함수
생성자 함수(Constructor Function)는 new 연산자와 함께 호출되어 객체를 생성하고 초기화하는 함수입니다.
일반적인 함수와 문법적으로는 동일하지만, 주로 특정 속성과 메서드를 갖는 객체를 반복적으로 생성하기 위한 템플릿 역할을 합니다.
04.01. 생성자 함수 정의 및 사용 방법
생성자 함수는 일반적으로 첫 글자를 대문자로 시작하는 관례를 따릅니다.
내부에서는 this 키워드를 사용하여 생성될 객체의 프로퍼티를 정의하고 초기화합니다.
function User(name, age) {
this.name = name;
this.age = age;
this.greet = function () {
console.log(
`Hello, my name is ${this.name} and I am ${this.age} years old.`
);
};
}
// new 연산자를 사용하여 객체 생성
const user1 = new User("odin", 30);
const user2 = new User("thor", 35);
user1.greet(); // Hello, my name is odin and I am 30 years old.
user2.greet(); // Hello, my name is thor and I am 35 years old.04.02. this 바인딩
생성자 함수 내부의 this는 new 연산자를 통해 생성된 새로운 객체를 가리킵니다.
생성자 함수가 실행될 때, 다음과 같은 과정이 내부적으로 일어납니다.
- 빈 객체가 생성됩니다.
this는 새로 생성된 빈 객체에 바인딩됩니다.- 생성자 함수 내부의 코드가 실행되며,
this를 사용하여 객체의 프로퍼티와 메서드를 추가합니다. - 특별한 반환문이 없는 경우,
this에 바인딩된 새로 생성된 객체가 반환됩니다.
04.03. prototype 속성
모든 자바스크립트 함수는 prototype이라는 속성을 가지고 있습니다.
생성자 함수의 prototype 속성은 해당 생성자 함수를 통해 생성된 모든 객체가 공유할 프로퍼티와 메서드를 정의하는 객체를 참조합니다.
이를 통해 메모리 사용을 효율적으로 관리하고 상속과 유사한 패턴을 구현할 수 있습니다.
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function () {
console.log(`${this.name} makes a sound.`);
};
const dog = new Animal("Buddy");
const cat = new Animal("Whiskers");
dog.speak(); // Buddy makes a sound.
cat.speak(); // Whiskers makes a sound.
console.log(dog.__proto__ === Animal.prototype); // true (숨겨진 프로퍼티)
console.log(cat.__proto__ === Animal.prototype); // true04.04. 생성자 함수의 활용
생성자 함수는 다음과 같은 상황에서 유용하게 사용됩니다.
- 특정 구조를 가진 객체를 여러 개 생성해야 할 때: 예를 들어, 사용자 정보, 상품 정보 등을 담는 객체를 반복적으로 만들 때 유용합니다.
- 객체의 초기 상태를 설정해야 할 때: 생성 시 필요한 기본적인 프로퍼티 값을 설정할 수 있습니다.
- 메서드를 공유하여 메모리 효율성을 높이고 싶을 때: 프로토타입을 통해 메서드를 정의하면 모든 인스턴스가 해당 메서드를 공유합니다.
ES6에서는 class 키워드가 도입되어 생성자 함수를 더욱 편리하게 정의하고 사용할 수 있게 되었지만, 내부적으로는 여전히 프로토타입 기반으로 동작합니다.
05. Object.create
Object.create() 메서드는 지정된 프로토타입 객체 및 속성(선택 사항)을 사용하여 새로운 객체를 생성합니다.
이는 프로토타입 기반 상속을 구현하거나, 프로토타입이 없는 순수한 객체를 만들 때 매우 유용합니다.
05.01. 주요 특징
- 명시적인 프로토타입 지정:
- 첫 번째 인수로 전달된 객체를 새로 생성되는 객체의 프로토타입으로 설정합니다.
- 생성된 객체는 해당 프로토타입 객체의 프로퍼티와 메서드를 상속받습니다.
- 프로토타입 없는 객체 생성:
- 첫 번째 인수로
null을 전달하면 프로토타입이 없는 완전히 새로운 빈 객체를 생성할 수 있습니다. - 이는
hasOwnProperty와 같은 기본적인Object.prototype의 메서드조차 상속받지 않는 순수한 딕셔너리 형태의 데이터 구조를 만들 때 사용됩니다.
- 첫 번째 인수로
- 두 번째 인수를 통한 속성 정의:
- 선택적으로 두 번째 인수를 통해 생성될 객체의 속성을 정의할 수 있습니다.
- 이 인수는 각 속성에 대한 설명자(descriptor)를 포함하는 객체입니다.
- 속성 설명자를 통해 속성의 값, 쓰기 가능 여부, 열거 가능 여부, 재정의 가능 여부 등을 세밀하게 설정할 수 있습니다.
예제 코드:
const proto = {
greet() {
console.log(`Hello, I'm ${this.name}`);
},
};
const odin = Object.create(proto);
odin.name = "odin";
odin.greet(); // Hello, I'm odin
console.log(Object.getPrototypeOf(odin) === proto); // true
const thor = Object.create(proto, {
name: {
value: "thor",
// 값 수정 가능
writable: true,
// 열거 가능
enumerable: true,
// 재정의 가능
configurable: true,
},
});
// Hello, I'm thor
thor.greet();
thor.name = "Thor Odinson";
// Thor Odinson
console.log(thor.name);
// 순수한 빈 객체 (dictionary)
const dict = Object.create(null);
dict["key"] = "value";
// "value"
console.log(dict["key"]);
// Error: dict.hasOwnProperty is not a function
dict.hasOwnProperty("key");
// true (Object.prototype 메서드를 빌려 사용)
console.log(Object.prototype.hasOwnProperty.call(dict, "key"));
Object.create()는 객체 생성 시 프로토타입을 직접 제어해야 하는 경우, 또는 프로토타입 체인에서 특정 객체를 상속받는 객체를 만들 때 유용하게 사용됩니다. 또한, 프로토타입이 없는 순수한 데이터 저장소를 만들 때도 활용될 수 있습니다.
06. 프로퍼티
객체의 데이터를 표현하는 키(key)-값(value) 쌍을 프로퍼티(property)라고 합니다.
각 프로퍼티는 객체의 상태나 특징을 나타냅니다.
06.01. 프로퍼티 접근 방식 사용 기준
06.01.01. 점 표기법 (obj.key)
- 프로퍼티 이름이 유효한 자바스크립트 식별자(문자, 숫자, 밑줄, 달러 기호로 시작하고 숫자로 시작하지 않는 이름)이고, 미리 이름이 확정되어 있을 때 사용합니다.
- 간결하고 직관적인 코드를 작성할 수 있습니다.
const person = { name: "odin", age: 30 };
console.log(person.name); // "odin"
console.log(person.age); // 3006.01.02. 대괄호 표기법 (obj["key"])
- 프로퍼티 이름이 유효한 자바스크립트 식별자가 아니거나(예: 공백, 특수문자 포함),
- 프로퍼티 이름을 동적으로 결정해야 할 때 (변수를 사용하여 접근),
- 숫자형 키를 사용할 때 (객체를 배열처럼 접근하는 경우) 사용합니다.
- 유연성이 높고, 변수를 통해 프로퍼티에 접근할 수 있다는 장점이 있습니다.
const person = { "first name": "odin", 1: "one" };
const propName = "first name";
console.log(person["first name"]); // "odin"
console.log(person[propName]); // "odin"
console.log(person[1]); // "one" (숫자형 키는 문자열로 취급됨)06.01.03. 접근 방식 선택 기준
일반적으로 프로퍼티 이름이 정적이고 유효한 식별자라면 점 표기법을 사용하는 것이 가독성이 좋습니다.
반면, 프로퍼티 이름이 동적이거나 유효한 식별자가 아닌 경우에는 대괄호 표기법을 사용해야 합니다.
06.02. 프로퍼티 추가/수정/삭제
06.02.01. 프로퍼티 추가
const car = {};
car.brand = "Tesla"; // 점 표기법으로 추가
car["model"] = "Model 3"; // 대괄호 표기법으로 추가
console.log(car); // { brand: 'Tesla', model: 'Model 3' }06.02.02. 프로퍼티 값 변경
car.brand = "BMW"; // 점 표기법으로 변경
car["model"] = "X5"; // 대괄호 표기법으로 변경
console.log(car); // { brand: 'BMW', model: 'X5' }06.02.03. 프로퍼티 삭제
delete 키워드를 사용하여 삭제합니다.
delete car.model;
console.log(car); // { brand: 'BMW' }07. 메서드
메서드(Method)는 객체에 포함된 함수(function)를 의미합니다.
메서드는 객체의 프로퍼티 값으로 할당되며, 해당 객체의 데이터를 기반으로 특정 행동(동작)을 수행하거나 객체의 상태를 변경하는 역할을 합니다.
const calculator = {
value: 0,
add: function (num) {
this.value += num;
},
subtract: function (num) {
this.value -= num;
},
getValue: function () {
return this.value;
},
};
calculator.add(5);
calculator.subtract(2);
console.log(calculator.getValue()); // 3위 예시에서 add, subtract, getValue는 calculator 객체의 메서드입니다.
메서드 내부에서는 this 키워드를 사용하여 해당 메서드를 호출한 객체(calculator)에 접근하여 프로퍼티 값을 읽거나 수정할 수 있습니다.
08. 메서드 축약 표현
08.01. 메서드 축약이란?
메서드 축약(Method Shorthand) 표현은 ES6(ECMAScript 2015)에서 도입된 문법으로, 객체 리터럴 내에서 메서드를 정의할 때 function 키워드와 콜론(:)을 생략하고 더욱 간결하게 표현할 수 있도록 합니다.
08.01.01. 기존 방식
const personOld = {
greet: function () {
console.log("Hello!");
},
};08.01.02. 축약 표현
const personNew = {
greet() {
console.log("Hello!");
},
};
personNew.greet(); // Hello!
메서드 축약 표현은 코드의 가독성을 높이고 작성해야 하는 코드를 줄여주는 장점이 있습니다.
08.02. 일반 메서드 vs 축약 메서드 vs 화살표 함수 (자세히)
객체 리터럴 내에서 함수를 정의할 때 일반적인 함수 표현식(function 키워드 사용), 축약 메서드 표현식(ES6), 그리고 화살표 함수 표현식(ES6)을 사용할 수 있습니다.
이 세 가지 방식은 문법적으로 유사해 보이지만, this 바인딩 방식, 생성자로서의 사용 가능 여부, arguments 객체 접근 가능 여부 등에서 중요한 차이점을 가집니다.
| 특징 | 일반 메서드 (function) |
축약 메서드 (ES6) | 화살표 함수 (ES6) |
|---|---|---|---|
| 문법 | key: function() {} |
key() {} |
key: () => {} |
this 바인딩 |
메서드를 호출한 객체 | 메서드를 호출한 객체 | 상위 스코프의 this (렉시컬 스코프) |
| 생성자 사용 가능 | 가능 | 불가능 | 불가능 |
arguments 접근 |
가능 (유사 배열 객체) | 가능 (유사 배열 객체) | 불가능 |
super 키워드 |
사용 가능 | 사용 가능 | 사용 불가능 |
08.02.01. 일반 메서드 사용 상황
- 객체의 동작을 정의하고, 메서드 내부에서 해당 객체의 프로퍼티에 접근(
this)해야 할 때- 대부분의 객체 메서드에 적합합니다.
this는 메서드를 호출한 객체에 동적으로 바인딩됩니다.
- 생성자 함수로 사용해야 할 때
new연산자와 함께 호출하여 객체를 생성하고 초기화하는 역할을 수행해야 하는 경우에 사용합니다.
08.02.02. 축약 메서드 사용 상황
- 객체 리터럴 내에서 메서드를 간결하고 명확하게 표현하고 싶을 때:
- 일반 메서드와 동일하게
this는 메서드를 호출한 객체에 바인딩됩니다. - 가독성을 높이는 데 유용합니다.
- 일반 메서드와 동일하게
super키워드를 사용하여 프로토타입 체인 상의 부모 메서드를 호출해야 할 때:- 축약 메서드 내에서도
super키워드를 사용할 수 있습니다.
- 축약 메서드 내에서도
08.02.03. 화살표 함수를 메서드로 사용하지 않는 이유
- 예측 불가능한
this바인딩- 화살표 함수는 자신만의
this컨텍스트를 생성하지 않고, 자신을 둘러싸고 있는 (상위) 렉시컬 스코프의this를 그대로 상속받습니다. - 객체 리터럴 내에서 화살표 함수를 메서드로 사용하면
this가 객체 자신이 아닌 전역 객체(window또는undefinedin strict mode)를 참조하게 되어 예기치 않은 동작을 일으킬 수 있습니다.
- 화살표 함수는 자신만의
- 생성자로 사용할 수 없음:
- 화살표 함수는
new연산자와 함께 호출하여 생성자 함수로 사용할 수 없습니다.
- 화살표 함수는
arguments객체 접근 불가:- 화살표 함수 내부에서는
arguments객체에 접근할 수 없습니다. - 대신 Rest 파라미터(
...args)를 사용하여 모든 인수를 배열 형태로 받을 수 있습니다.
- 화살표 함수 내부에서는
super키워드 사용 불가:- 화살표 함수 내에서는
super키워드를 사용할 수 없습니다.
- 화살표 함수 내에서는
08.02.04. 화살표 함수 사용이 적합한 상황
콜백 함수 내부에서 외부 스코프의 this를 유지하고 싶을 때 사용합니다.
- 배열 메서드(
map,filter,forEach등)의 콜백 함수나 비동기 처리 콜백 함수 등에서 유용합니다. - 이때 화살표 함수는 주변 스코프의
this를 캡처하여 사용할 수 있습니다.
const counter = {
count: 0,
start: function () {
setInterval(() => {
// 화살표 함수 사용, this는 counter 객체를 가리킴
this.count++;
console.log(this.count);
}, 1000);
},
};
counter.start();
const numbers = [1, 2, 3];
const doubled = numbers.map((num) => num * 2); // 화살표 함수 사용, this는 없음
console.log(doubled); // [2, 4, 6]'books > deep-dive' 카테고리의 다른 글
| [Deep-Dive JavaScript] 13장 - 스코프 (0) | 2025.03.26 |
|---|---|
| [Deep-Dive JavaScript] 12장 - 함수 (0) | 2025.03.26 |
| [Deep-Dive JavaScript] 6장 - 데이터 타입 (0) | 2025.03.24 |
| [Deep-Dive JavaScript] 11장 - 원시 값, 객체 (0) | 2025.03.23 |
| [Deep-Dive JavaScript] 4장 - 변수 (0) | 2025.03.23 |
- Total
- Today
- Yesterday
- deep dive
- 모노레포 스크립트
- interning
- refrerence
- pnpm 명령어
- npm ci
- nuxt
- react-router
- object literal
- bundler
- JIT
- 바이트 코드
- string
- JavaScript
- useasyncdata
- react
- double-linked-list
- scoped slot
- uselazyasyncdata
- vue
- premitive
- string table
- pakage-lock.json
- primitive
- webpack
- library mode
- TypeScript
- vee-validate
- ViTE
- prototype
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
