객체(Object)란 이름(key)와 값(value)이 한 쌍으로 이루어진 프로퍼티(property)들의 정렬되지 않은 집합을 말한다. 프로퍼티 키에는 빈 문자열을 포함한 모든 문자열 또는 symbol 값이 올 수 있고, 프로퍼티 값으로는 모든 자료형의 값이 올 수 있다. 만약 프로퍼티 값으로 함수가 올 경우, 이 프로퍼티를 메소드(method)라고 부른다.
객체의 예
- Object: 고양이, 강아지, 책, 자동차 등
- Key: 이름, 종, 나이, 무게
- Value: "나비", "코리안 숏 헤어", "1", 300
- Property: cat.name = "나비", cat.family="코리안 숏 헤어"...
- Method: cat.eat(), cat.sleep(), cat.play()
자바스크립트는 객체 지향 언어이다. 숫자, 문자열, 불리언, undefined 타입을 제외한 모든 것이 객체이며, 숫자, 문자, 불리언과 같은 원시 타입 또한 값이 정해진 객체로 취급된다. 즉, 원시 타입 또한 객체로서의 특징을 가지고 있다.
내장객체: 프로그래밍을 할 때 자주 사용하는 요소들을 미리 정의해 놓은 객체
문서 객체 모델(DOM): 웹 문서를 관리하는 객체
브라우저 객체 모델(BOM): 웹 브라우저의 주소 표시줄이나 창크기, 사용자의 브라우저 및 기기 정보 등을 다루는 객체
사용자 객체: 사용자가 정의한 객체
가장 일반적인 객체 생성 방식이다. 객체의 프로퍼티를 한 눈에 보고 파악할 수 있기 때문에 직관적이지만, 프로퍼티가 같은 객체를 여러 개 생성할 때마다 매번 같은 프로퍼티를 기술해야 한다는 단점이 있다.
//syntax: 객체명 = {키1: 값1, 키2: 값2 ...}
let cat1 = {
name: "나비",
family: "코리안 숏 헤어",
weight: 300,
info: function(){
console.log("name: " + this.name + "family: " + this.family)
}
};
let cat2 = {
name: "키티",
family: "페르시안",
weight: 400,
info: function(){
console.log("name: " + this.name + "family: " + this.family)
}
};
cat1.eyeColor = "노랑";
console.log(cat1.name); //나비
console.log(cat2["name"]); //키티
console.log(cat1.eyeColor); // 노랑
console.log(cat2.eyeColor); //undefined
cat1.info(); // name: 나비 family: 코리안 숏헤어
cat2.info();//name: 키티 family: 페르시안
리터럴 방식으로 객체를 생성할 때는 키와 값 사이에 콜론(:)을 입력해야 하고, 프로퍼티들은 쉼표(,)로 구분해주어야 한다. 마지막 프로퍼티에는 쉼표 생략이 가능하다.
new 연산자와 Object 생성자 함수를 통해 빈 객체를 만들고, 프로퍼티 또는 메소드를 추가하는 방식이다. 리터럴 방식과 마찬가지로 프로퍼티가 같은 객체를 여러 개 생성할 때마다 매번 같은 프로퍼티를 기술해야 한다는 단점이 있다.
/* syntax
객체명 = new Object();
변수명.키1 = 값1;
변수명.키2 = 값2;
... */
var cat1 = new Object();
var cat2 = new Object();
cat1. name = "나비";
cat1.family = "코리안 숏 헤어";
cat1.info: function(){
console.log("name: " + this.name + "family: " + this.family);
}
cat2. name = "키티";
cat2.family = "페르시안";
cat2.info: function(){
console.log("name: " + this.name + "family: " + this.family);
}
cat1["weight"] = 300;
cat2.weight = 400;
console.log(cat1.name); //나비
console.log(cat2["name"]); //키티
cat1.info(); // name: 나비 family: 코리안 숏헤어
cat2.info();//name: 키티 family: 페르시안
자바스크립트 엔진은 객체 리터럴로 객체를 생성하는 코드를 읽으면 Object 생성자 함수를 사용해 객체를 생성하기 때문에 Object 생성자 함수를 사용해 객체를 생성하는 일은 거의 없다.
생성자 함수를 사용해 객체를 만드는 방식으로 프로퍼티가 동일한 함수를 만들 때 유용한 프로토 타입을 생성하는 가장 기본적인 방법이다.
/* syntax:
function 객체명(매개변수1,매개변수2...){
this.키1 = 매개변수1; >> 매개변수1에 담긴 인수가 프로퍼티 값이 됨
this.키2 = 매개변수2;
} */
function Cat(name, family, weight){
this.name = name;
this.family = family;
this.weight = weight;
this.info = function(){
console.log("name: " + this.name + "family: " + this.family);
}
}
cat1 = new Cat("나비", "코리안 숏헤어", 300);
cat2 = new Cat("키티", "페르시안", 400);
console.log(cat1.name); //나비
console.log(cat2["name"]); // 키티
cat1.info(); // name: 나비 family: 코리안 숏헤어
cat2.info(); // name: 키티 family: 페르시안
생성자 함수의 이름은 일반적으로 대문자로 시작한다.
프로퍼티 키와 메소드명 앞에 붙은 this는 생성자 함수가 생성할 인스턴스를 가리킨다. 여기서 인스턴스란 생성자 함수로 생성한 객체를 의미한다.
this와 연결된 프로퍼티와 메소드는 외부에서도 참조 가능하지만, 생성자 함수 내에 선언된 일반 변수는 외부에서 참조가 불가능하다.
프로퍼티 키는 프로퍼티 값에 접근할 수 있도록 하는 식별자 역할을 한다. 보통 문자열이나 symbol 값을 부여하는데 만약, 문자열이나 symbol 값 이외의 값을 지정할 경우 암묵적으로 문자열 타입으로 변경된다.
프로퍼티 키는 문자열이기 때문에 따옴표를 사용해야 하지만, 프로퍼티 키가 문자열이고 식별자 네이밍 규칙에 준수하는 경우 따옴표를 생략할 수 있다. 반면 규칙에 어긋나는 경우 따옴표를 사용해야만 SyntaxError가 발생하지 않는다.
식별자 네이밍 규칙
var person = {
first_name : "Hong-yun", //따옴표 생략 가능
last-name : "Choi", // SyntaxError
"last-name": "Choi"
};
프로퍼티의 값을 출력하는 방법에는 마침표(.) 표기법과 대괄호([ ]) 표기법이 있다.
var person = {
"first-name": "Hong-yun",
"last-name": "Choi",
"age": 25
};
console.log(person.fist-name); // NaN
console.log(person[first-name]); // ReferenceError
console.log(person["first-name"]); // Hong-yun
console.log(person.age); // 25
console.log(person[age]); // ReferenceError
console.log(person["age"]); // 25
console.log(person.height); //undefined
프로퍼티 키가 식별자 네이밍 규칙에 준수하는 경우 마침표 표기법과 대괄호 표기법을 모두 사용할 수 있다.
하지만 이에 준수하지 않을 경우 무조건 대괄호 표기법을 사용해야 한다. 대괄호 내에 들어가는 프로퍼티 키는 반드시 문자열이어야 한다.
객체에 존재하지 않는 프로퍼티 키를 통해 프로퍼티 값을 출력하면 undefined 가 반환된다.
var person = {
"first-name": "Hong-yun",
"last-name": "Choi",
"age": 25
};
person.gender = "female";
console.log(person.gender); // female
person.age = 26;
console.log(person.age); // 26
객체에 존재하지 않는 프로퍼티 키에 값을 할당할 경우, 입력한 키와 값으로 프로퍼티를 생성하여 객체에 추가한다.
하지만, 이미 객체에 존재하는 프로퍼티 키에 값을 할당할 경우, 해당 키의 프로퍼티 값을 갱신한다.
var person = {
"first-name": "Hong-yun",
"last-name": "Choi",
"age": 25
};
delete person.age;
console.log(person.age); //undefined
delete person;
console.log(person); // Object{first-name: "Hong-yun", last-name: "Choi"}
프로퍼티를 삭제할 때는 delete 연산자를 사용한다. 프로퍼티가 아닌 객체는 delete 연산자로 삭제할 수 없다.
let cat = {
name: "나비",
family: "코리안 숏 헤어",
weight: 300,
};
for (let key in cat){
console.log(key + ":" + cat[key]);
}
/* 출력값
name: "나비"
family: "코리안 숏 헤어"
weight: 300
*/
프로퍼티 값으로는 모든 자료형이 들어갈 수 있다. 즉, 객체도 들어갈 수 있다는 점이다. 이처럼 객체의 프로퍼티 값으로 객체가 들어간 것을 중첩된 객체라고 한다.
중첩된 객체에 접근하는 방법도 객체에 접근하는 방법과 동일하다.
let score = {
team1: {"하나": 80, "유진":89, "민석":100, "민형":90},
team2: {"우제": 98, "지은": 76, "윤아": 80},
scoreWrite: function(){
for(key in this.team1){
console.log(key + ":" + this.team1[key]);
}
}
}
score.scoreWrite();
/*하나:80
유진:89
민석:100
민형:90 */
console.log(score.team1."유진"); //89
console.log(score.team2["우제"]); //98
object.keys() 메소드는 주어진 객체의 프로퍼티 키들을 배열로 반환한다.
const obj1 = {
a: "string",
b: 94,
c: false
};
console.log(Object.keys(obj1)); // Array["a", "b", "c"]
object.values() 메소드는 프로퍼티 값들을 배열로 리턴한다.
const obj1 = {
a: "string",
b: 94,
c: false
};
console.log(Object.values(obj1)); // Array["string", 94, false]