자료쳥 챕터에서 배웠듯이 자바스크립트엔 여덟 가지 자료형이 있다. 이 중 일곱 개는 오직 하나의 데이터만 담을 수 있어 '원시형'이라 부릅니다.
그런데 객체형은 원시형과 달리 다양한 데이터를 담을 수 있습니다. 키로 구분된 데이터 집합이나 복잡한 개체를 저장할 수 있다. 객체는 자바스크립트 거의 모든 면에 녹아 있는개념이므로 자바스크립트를 잘 다루려면 객체를 잘 이해야 함
객체는 중괄호 {...}를 이용해 만들 수 있다. 중괄호 안에는 '키(key): 값(value)'쌍으로 구성된 프로퍼티를 여러 개 넣을 수 있는데, 키엔 문자형, 값엔 모든 자료형이 허용
let user= new Object();//'객체 생성자'문법
let user = {} //'객체 리터럴'문법
let user = { //객체
name:"john", // 키:'name', 값: "john"
age: 30 // 키:'age', 값:30
}
객체 user에는 프로퍼티가 두 개 있습니다.
1. 첫 번째 프로퍼티 - "name"(이름)과 "john"(값)
2. 두 번째 프로퍼티 - "age"(이름)과 30(값)
//프로퍼티 값 얻기
console.log(user.name)//John
console.log(user.age)//30
user.inAdmin = true;
delete user.age;
let user = {
name: "John",
age: 30,
"likes birds": true; //복수의 단어는 따음표로 묶어야 함
}
let user = {
name: "John",
ange: 30,
}
상수 객체는 수정될 수 있다.
const user = {
name:"John"
};
user.name = "Pete" //(*)
console.log(user.name) //pate
(*)로 표시한 줄에서 오류를 일으키는 것처럼 보일 수 있지만 그렇지 않습니다. const는 user의 값을 고정하지만, 그 내용은 고정하지 않습니다.
const는 user=...를 전체적으로 설정하려고 할 때만 오류가 발생합니다.
///문법 에러
user.likes birds = true;
자바스크립트는 위와 같은 코드를 이해하지 못함. user.likes까지는 이해하다가 예상치 못한 birds를 만나면 문법 에러
'점'은 키가 '유효한 변수 식별자'인 경우에만 사용할 수 있습니다. 유효한 변수 식별자엔 공백이 없어야 합니다. 또한 숫자로 시작하지 않아야 하며 $와_를 제외한 특수 문자가 없어야 합니다.
let user = {};
// set
user["likes birds"] = true;
// get
alert(user["likes birds"]); // true
// delete
delete user["likes birds"];
let key = "likes birds"
//user["likes birds" = ture;와 같다
user[key] = true;
let user = {
name: "John",
age: 30,
};
let key = "name";
// 변수로 접근
console.log(user[key]);
let user = {
name: "John",
age: 30
};
let key = "name";
console.log( user.key ) // undefined
let fruit = "apple";
let bag = {
[fruit]: 5, // 변수 fruit에서 프로퍼티 이름을 동적으로 받아 옵니다.
};
console.log(bag.apple); // fruit에 "apple"이 할당되었다면, 5가 출력됩니다.
let fruit = "apple";
let bag = {};
// 변수 fruit을 사용해 프로퍼티 이름을 만들었습니다.
bag[fruit] = 5;
let fruit = "apple";
let bag = {
[fruit + "Computers"]: 5, // bag.appleComputers = 5
};
console.log(bag.appleComputers); // 5
대괄호 표기법은 프로퍼티 이름과 값의 제약을 없애주기 때문에 점 표기법보다 훨씬 강력 그런데 작성하기 번거롭다는 단점이 존재
이런 이유로 프로퍼티 이름이 확정된 상황이고, 단순한 이름이라면 처음엔 점 표기법을 사용하다가 뭔가 복잡한 상황이 발생했을 때 대괄호 표기법으로 바꾸는 경우가 많습니다.
function makeUser(name, age) {
return {
name: name,
age: age,
// ...등등
};
}
let user = makeUser("John", 30);
console.log(user.name); // John
위 예시의 프로퍼티들은 이름과 값이 변수의 이름과 동일, 이렇게 변수를 사용해 프로퍼티를 만드는 경우는 아주 흔한대, 프로퍼티 값 단축 구문을 사용하면 코드를 짧게 줄일 수 있음.
name:name 대신 name만 죽어주어도 프로퍼티를 설정
function makeUser(name, age) {
return {
name, // name: name 과 같음
age, // age: age 와 같음
// ...
};
}
let user = {
name, //name:name과 같음
age:30
}
아시다시피 변수 이름(키)엔 ‘for’, ‘let’, ‘return’ 같은 예약어를 사용하면 안됩니다.
그런데 객체 프로퍼티엔 이런 제약이 없습니다.
//예약어를 키로 사용해도 괜찮습니다.
let obj ={
for: 1,
let: 2,
return : 3
}
console.log(obj.for + obj.let + obj.return // 6
이와 같이 프로퍼티 이름엔 특별한 제약이 없습니다. 어떤 문자형, 심볼형 값도 프로퍼티 키가 될 수 있죠(식별자로 쓰이는 심볼형에 대해선 뒤에서 다룰 예정입니다).
문자형이나 심볼형에 속하지 않은 값은 문자열로 자동 형 변환됩니다.
예시를 살펴봅시다. 키에 숫자 0을 넣으면 문자열 "0"으로 자동변환됩니다.
let obj = {
0: "test", // "0": "test"와 동일합니다.
};
// 숫자 0은 문자열 "0"으로 변환되기 때문에 두 얼럿 창은 같은 프로퍼티에 접근합니다,
console.log(obj["0"]); // test
console.log(obj[0]); // test (동일한 프로퍼티)
let obj = {};
obj.__proto__ = 5; // 숫자를 할당합니다.
alert(obj.__proto__); // [object Object] - 숫자를 할당했지만 값은 객체가 되었습니다. 의도한대로 동작하지 않네요.
자바스크립트 객체의 중요한 특징 중 하나는 다른 언어와는 달리, 존재하지 않는 프로퍼티에 접근하려 해도 에러가 발생하지 않고 undefined를 반환
이런 특징을 응용하면 프로퍼티 존재 여부를 쉽게 확인
let user = {};
console.log( user.noSuchProperty === undefined ); // true는 '프로퍼티가 존재하지 않음'을 의미합니다.
이렇게 undefined와 비교하는 것 이외에도 연산자 in을 사용하면 프로퍼티 존재 여부를 확인할 수 있습니다.
문법은 다음과 같습니다.
"key" in object
let user = { name: "John", age: 30 };
console.log("age" in user); // user.age가 존재하므로 true가 출력됩니다.
console.log("blabla" in user); // user.blabla는 존재하지 않기 때문에 false가 출력됩니다.
in 왼쪽엔 반드시 프로퍼티 이름이 와야 합니다. 프로퍼티 이름은 보통 따옴표로 감싼 문자열입니다.
따음표를 생략하면 아래 예시와 같이 엉뚱한 변수가 조사 대상
let user = { age: 30 };
let key = "age";
console.log( key in user ); // true, 변수 key에 저장된 값("age")을 사용해 프로퍼티 존재 여부를 확인합니다.
그런데 이쯤 되면 "undefined랑 비교해도 충분한데 왜 in 연산자가 있는 거지?"라는 의문이 들 수 있습니다.
대부분의 경우, 일치 연산자를 사용해서 프로퍼티 존재 여부를 알아내는 방법("=== undefined")은 꽤 잘 동작합니다. 그런데 가끔은 이 방법이 실패할 때도 있습니다. 이럴 때 in을 사용하면 프로퍼티 존재 여부를 제대로 판별할 수 있습니다.
let obj = {
test: undefined
};
console.log( obj.test ); // 값이 `undefined`이므로, 얼럿 창엔 undefined가 출력됩니다. 그런데 프로퍼티 test는 존재합니다.
console.log( "test" in obj ); // `in`을 사용하면 프로퍼티 유무를 제대로 확인할 수 있습니다(true가 출력됨).
for...in 반복문을 사용하면 객체의 모든 키를 순회할 수 있음.
for..in은 앞서 학습했던 for(;;) 반복문과는 완전히 다릅니다.
for(key in object){
//각 프로퍼티 키(key)를 이용하여 본문(body)를 실행
}
let user = {
name: "John",
age: 30,
isAdmin: true
};
for (let key in user) {
// 키
console.log( key ); // name, age, isAdmin
// 키에 해당하는 값
console.log( user[key] ); // John, 30, true
}
for..in 반복문에서도 for(;;)문처럼 반복 변수(looping variable)를 선언(let key)했다는 점에 주목해 주시기 바랍니다.
반복 변수명은 자유롭게 정할 수 있습니다. 'for (let prop in obj)'같이 key 말고 다른 변수명을 사용해도 괜찮습니다.
객체와 객체 프로퍼티를 다루다 보면 "프로퍼티엔 순서가 있을까"라는 의문이 생기기 마련 반복문은 프로퍼티를 추가한 순서대로 실행될지, 그리고 이 순서는 항상 동일할지 궁금해지죠.
답은 간단하다. 객체는 '특별한 방식으로 정렬'됩니다. 정수 프로퍼티는 자동으로 정렬되고, 그외의 프로퍼티는 객체에 추가한 순서 그대로 정렬
let codes = {
"49": "독일",
"41": "스위스",
"44": "영국",
// ..,
"1": "미국"
};
for (let code in codes) {
console.log(code); // 1, 41, 44, 49
}
현재 개발 중인 애플리케이션의 주 사용자가 독일인이라고 가정 나라 번호를 선택하는 화면에서 49가 맨 앞에 오도록 하는 게 좋음
그런데 코드를 실행해 보면 예상과는 전혀 다른 결과가 출력
이유는 나라 번호(키)가 정수이어서 1, 41, 44, 49 순으로 프로퍼티가 자동 정렬되었기 때문입니다.
정수 프로퍼티? 그게 뭔가요?
// 함수 Math.trunc는 소수점 아래를 버리고 숫자의 정수부만 반환합니다.
console.log(String(Math.trunc(Number("49"))) ); // '49'가 출력됩니다. 기존에 입력한 값과 같으므로 정수 프로퍼티입니다.
console.log( String(Math.trunc(Number("+49"))) ); // '49'가 출력됩니다. 기존에 입력한 값(+49)과 다르므로 정수 프로퍼티가 아닙니다.
console.log( String(Math.trunc(Number("1.2"))) ); // '1'이 출력됩니다. 기존에 입력한 값(1.2)과 다르므로 정수 프로퍼티가 아닙니다.
let user = {
name: "John",
surname: "Smith"
};
user.age = 25; // 프로퍼티를 하나 추가합니다.
// 정수 프로퍼티가 아닌 프로퍼티는 추가된 순서대로 나열됩니다.
for (let prop in user) {
console.log( prop ); // name, surname, age
}
let codes = {
"+49": "독일",
"+41": "스위스",
"+44": "영국",
// ..,
"+1": "미국"
};
for (let code in codes) {
console.log( +code ); // 49, 41, 44, 1
}
위 내용은 javascript.info 사이트에서 공부한 내용 정리
자세한 내용은 아래 링크를 참고하세요
https://ko.javascript.info/object