[JavaScript] Objects (객체)
1. Objects (객체)
Objects(객체)는 관련 데이터와 기능을 저장하는 컨테이너다.
객체를 이용해 복잡한 데이터 구조를 표현할 수 있다.
2. Creating Object Literals (객체 리터럴 생성)
객체는 다른 데이터 타입처럼 변수에 할당될 수 있고, key-value 쌍으로 이루어진다.
key는 값을 가지고 있는 메모리 위치를 가리키는 변수 이름이고,
value는 함수나 다른 객체를 포함하는 모든 데이터 타입이 될 수 있다.
객체 리터럴을 생성하기 위해 { }에 key : value를 입력한다. 각 key-value는 , 로 구분한다.
let spaceship = {
'Fuel Type' : 'diesel',
color : 'silver'
};
3. accessing properties (객체 속성 접근)
객체 속성에 접근하는 방법은 두 가지다.
1️⃣ . (dot notation)
객체 이름 뒤에 .을 쓰고, 그 뒤에 속성 이름(key)을 쓴다.
let spaceship = {
homePlanet: 'Earth',
color: 'silver'
};
spaceship.homePlanet; // 'Earth'
spaceship.color; // 'silver'
spaceship.favoriteIcecream; // undefined
존재하지 않는 속성에 접근하려 하면 undefined가 반환된다.
2️⃣ [ ] (bracket notation)
[ ] 에 속성 이름(키)을 문자열로 전달한다.
키에 숫자, 공백 또는 특수 문자가 포함된 경우 반드시 [ ]를 사용해야 한다.
. 을 사용하면 에러가 발생한다.
let spaceship = {
'Fuel Type': 'Turbo Fuel',
'Active Duty': true,
homePlanet: 'Earth',
numCrew: 5
};
spaceship['Active Duty']; // true
spaceship['Fuel Type']; // 'Turbo Fuel'
spaceship['numCrew']; // 5
spaceship['!!!!!!!!!!!!!!!']; // undefined
변수를 사용하여 객체의 키를 선택할 때에도 대괄호 표기법을 사용한다.
let returnAnyProp = (objectName, propName) => objectName[propName];
returnAnyProp(spaceship, 'homePlanet'); // 'Earth'
object.propName을 사용하면 propName을 매개변수가 아닌 키로 인식하여,
'propName'이라는 키를 찾으려고 할 것이다.
💡고정된 프로퍼티 이름을 사용할 때에는 점 표기법,
동적인 프로퍼티 이름을 사용할 때에는 대괄호 표기법을 사용한다.
4. property assignment (객체 속성 할당)
객체는 변경 가능하기 때문에 생성한 후에 수정할 수도 있다.
새로운 키-값 쌍을 추가하거나, 기존 속성의 값을 변경할 수 있다.
- 객체에 해당 속성이 이미 존재한다면, 그 속성 값이 새로운 값으로 대체된다.
- 해당 속성이 없었다면, 객체에 새로운 속성이 추가된다.
- const로 선언된 객체는 재할당할 수 없지만, 속성을 변경하거나 새 속성을 추가하는 것은 가능하다.
- delete 연산자를 사용하여 객체에서 속성을 삭제할 수도 있다.
const spaceship = {
type: 'shuttle'
'Fuel Type': 'Turbo Fuel',
mission: 'Explore the universe'
};
spaceship = {type: 'alien'}; // TypeError: Assignment to constant variable.
spaceship.type = 'alien'; // type 속성의 값을 'alien'으로 변경
spaceship.speed = 'Mach 5'; // 새로운 키 'speed'와 값 'Mach 5' 추가
delete spaceship.mission; // mission 속성을 삭제
5. methods (메소드)
객체에 저장된 데이터가 함수일 때, 이를 메서드(method)라고 한다.
속성(property)은 객체가 가지고 있는 것을 의미하며, 메서드는 객체가 하는 일을 나타낸다.
객체 리터럴 메서드는 키-값 쌍을 사용하여 작성할 수 있다.
키(key)는 메서드의 이름이 되고, 값(value)은 익명 함수 표현식이 된다.
const alienShip = { invade: function () {
console.log('Hello! We have come to dominate your planet.') }
};
콜론과 function 키워드는 생략할 수 있다.
const alienShip = { invade () { console.log('Hello! We have come to dominate your planet.') } };
객체 메서드는 객체 이름에 . 연산자를 사용해 메서드 이름과 괄호를 붙여 호출한다.
alienShip.invade(); // 출력: 'Hello! We have come to dominate your planet.'
6. nested objects (중첩 객체)
객체는 또 다른 객체를 속성으로 가질 수 있으며, 그 속성 역시 배열이나 더 많은 객체를 포함할 수 있다.
const spaceship = {
telescope: { yearBuilt: 2018,
model: '91031-XLT',
focalLength: 2032},
crew: { captain:
{ name: 'Sandra',
degree: 'Computer Engineering',
encourageTeam() { console.log('We got this!') } } },
engine: { model: 'Nimbus2000' },
nanoelectronics: { computer: { terabytes: 100, monitors: 'HD' },
'back-up': { battery: 'Lithium', terabytes: 50 } }
};
연산자를 연결하여 중첩된 속성에 접근할 수 있다.
spaceship.nanoelectronics['back-up'].battery; // 'Lithium' 반환
7. pass by reference
객체는 참조에 의해 전달된다.
객체를 할당한 변수를 함수의 인수로 전달할 때, 컴퓨터가 해당 매개변수 이름을 그 객체가 저장된 메모리 공간을 가리키는 것으로 해석하여 객체의 속성을 변경하는 함수는 해당 객체를 영구적으로 수정하게 된다.
const spaceship = { homePlanet: 'Earth', color: 'silver' };
let paintIt = obj => { obj.color = 'glorious gold'; };
paintIt(spaceship);
spaceship.color; // 'glorious gold' 반환
paintIt() 함수는 spaceship 객체의 color 속성을 영구적으로 변경했다.
하지만 spaceship 변수를 재할당하려고 할 때는 같은 방식으로 작동하지 않는다.
let spaceship = { homePlanet: 'Earth', color: 'red' }; let tryReassignment = obj => { obj = { identified: false, 'transport type': 'flying' }; console.log(obj); // {'identified': false, 'transport type': 'flying'} 출력 }; tryReassignment(spaceship); // 재할당 시도는 작동하지 않음 spaceship; // 여전히 {homePlanet: 'Earth', color: 'red'} 반환 spaceship = { identified: false, 'transport type': 'flying' }; // 일반 재할당은 여전히 작동
8. looping through objects
for .. in 구문을 사용하면 객체의 각 속성에 접근하여 코드를 반복 실행할 수 있다.
let spaceship = { crew: {
captain: {
name: 'Lily',
degree: 'Computer Engineering',
cheerTeam() { console.log('You got this!') }
},
'chief officer': {
name: 'Dan',
degree: 'Aerospace Engineering',
agree() { console.log('I agree, captain!') }
},
medic: {
name: 'Clementine',
degree: 'Physics',
announce() { console.log(`Jets on!`) }
},
translator: {
name: 'Shauna',
degree: 'Conservation Science',
powerFuel() { console.log('The tank is full!') }
}
}
};
for (let crewMember in spaceship.crew) {
console.log(`${crewMember}: ${spaceship.crew[crewMember].name}`);
}
/*
captain: Lily
chief officer: Dan
medic: Clementine
translator: Shauna
*/
9. this keyword
goat 객체의 속성 dietType을 출력하는 메소드 .diet()를 생성하려고 한다.
그런데 .diet() 메소드 범위 내에서는 goat 객체의 속성에 접근할 수 없기 때문에 에러가 발생한다.
const goat = {
dietType: 'herbivore',
makeSound() {
console.log('baaa');
},
diet() {
console.log(dietType);
}
};
goat.diet(); // "ReferenceError: dietType is not defined"
this 키워드를 사용하면 이 문제를 해결할 수 있다.
this 키워드는 호출하는 객체를 참조하며, 호출하는 객체의 속성에 접근할 수 있게 해준다.
this를 사용하면 goat 객체 자체에 접근하여, dietType 속성에 접근할 수 있다.
const goat = {
dietType: 'herbivore',
makeSound() {
console.log('baaa');
},
diet() {
console.log(this.dietType);
}
};
goat.diet(); // herbivore
메소드에서 호출 객체는 해당 메소드가 속한 객체이다.
메소드 내에서 this 키워드를 사용하면 this의 값은 호출 객체가 된다.
const goat = {
dietType: 'herbivore',
makeSound() { console.log('baaa'); },
diet: () => { console.log(this.dietType); }
};
goat.diet(); // undefined
10. privacy
객체에서 프라이버시(privacy)는 특정 속성만 수정하거나 값을 변경할 수 있도록 하는 것이다.
자바스크립트에는 객체의 프라이버시 기능이 없기 때문에
속성이 변경되지 말아야 한다는 의미를 전달하는 네이밍 규칙을 따른다.
속성 이름 앞에 _를 붙이는 것이 가장 일반적인 규칙이다.
const bankAccount = { _amount: 1000 }
_amount는 변경되지 말아야 한다는 의미를 전달하고 있지만, _amount를 재할당하는 것은 가능하다.
bankAccount._amount = 1000000;
11. getters
getter 메서드는 객체의 내부 속성을 가져와 반환하는 역할을 한다.
get 키워드로 메서드를 정의하고, _firstName과 _lastName이 존재하는지 확인한 후 결과에 따라 다른 값을 반환한다.
const person = {
_firstName: 'John',
_lastName: 'Doe',
get fullName() {
if (this._firstName && this._lastName) {
return `${this._firstName} ${this._lastName}`;
} else {
return 'Missing a first name or a last name.';
}
}
}
// Getter 메서드 호출
person.fullName; // 'John Doe'
일반적으로 getter 메서드는 속성처럼 호출되므로 괄호가 필요 없다.
속성 이름과 getter 메서드 이름이 같으면 무한 호출 스택 오류가 발생할 수 있으므로 주의한다.
12. setters
Setter 메서드는 객체의 기존 속성 값을 다시 할당하는 메서드이다.
const person = { _age: 37,
set age(newAge) {
if (typeof newAge === 'number') {
this._age = newAge;
} else {
console.log('You must assign a number to age');
}
}
};
person.age = 40;
console.log(person._age); // 출력: 40
person.age = '40'; // 출력: You must assign a number to age
this._age에 새 값을 할당하기 전에, newAge 값이 숫자인지 확인한다.
setter 메서드를 통해 숫자 값만 this._age에 재할당될 수 있다.
setter 메서드는 괄호 없이 속성처럼 호출된다.
Setter 메서드를 사용하더라도 여전히 객체의 속성에 직접 접근하여 값을 변경할 수 있다.
13. factory functions
객체의 여러 인스턴스를 빠르게 생성해야 할 때 사용하는 것이 팩토리 함수이다.
팩토리 함수는 객체를 반환하고 여러 객체 인스턴스를 생성하는 데 재사용할 수 있는 함수다.
또한, 팩토리 함수에는 매개변수를 사용할 수 있어 반환되는 객체를 사용자 맞춤형으로 만들 수 있다.
const monsterFactory = (name, age, energySource, catchPhrase) => {
return {
name: name,
age: age,
energySource: energySource,
scare() {
console.log(catchPhrase);
}
}
};
필요한 인수와 함께 monsterFactory를 호출하고 반환된 값을 변수에 할당하면 ghost 객체를 생성할 수 있다.
이렇게 하면 새로운 몬스터가 필요할 때마다 객체 리터럴을 만들 필요가 없다.
const ghost = monsterFactory('Ghouly', 251, 'ectoplasm', 'BOO!');
ghost.scare(); // 'BOO!'
14. Property Value Shorthand (속성 값 축약법)
const monsterFactory = (name, age) => {
return {
name: name,
age: age
}
};
const monsterFactory = (name, age) => { return { name, age } };
15. Destructured Assignment (구조 분해 할당)
const vampire = {
name: 'Dracula',
residence: 'Transylvania',
preferences: {
day: 'stay inside',
night: 'satisfy appetite'
}
};
위 코드에서 residence 속성을 변수로 추출하고 싶다면, 다음과 같은 코드를 사용할 수 있다.
const residence = vampire.residence;
console.log(residence); // 'Transylvania'
이때 구조 분해 할당을 이용하면, 키 입력을 줄일 수 있다.
객체의 키 이름을 중괄호 { }로 감싸고, 객체에 할당하여 변수를 생성한다.
const { residence } = vampire;
console.log(residence); // 'Transylvania'
구조 분해 할당을 사용하면 객체의 중첩된 속성도 추출할 수 있다.
const { day } = vampire.preferences;
console.log(day); // 'stay inside' 출력
예제 코드 : https://github.com/inyeongjang/Snoopy/blob/main/week03/8-Objects.js
Snoopy/week03/8-Objects.js at main · inyeongjang/Snoopy
Contribute to inyeongjang/Snoopy development by creating an account on GitHub.
github.com
참고자료 : https://www.codecademy.com/enrolled/courses/introduction-to-javascript
Learn JavaScript | Codecademy
Begin your web development journey with our JavaScript course. Explore dynamic scripting for interactive web solutions.
www.codecademy.com