자료형에는 8가지 자료형이 있는데 그 중 7개는 원시형이다.
원시형은 오직 하나의 데이터(문자열, 숫자 등)만 담을 수 있기 때문에 '원시형'이라 부른다.
그러나 객체형은 원시형과 달리 다양한 데이터를 담을 수 있다.
📍객체형
- 키로 구분된 데이터 집합이나 복잡한 개체(entity)를 저장할 수 있다.
- {...} 중괄호를 사용해 만들고, 중괄호 안에는 'key-value' 형태인 프로퍼티를 여러 개 넣을 수 있다.
- 중괄호를 이용해 객체를 선언하는 것을 객체 리터럴이라고 부르며 객체 선언 시 주로 이 방법을 사용한다.
- key -> 문자형만 허용 / value -> 모든 자료형 허용
- 프로퍼티 키는 프로퍼티의 이름 또는 식별자라고도 한다.
📍 리터럴과 프로퍼티
// 'user' 라는 객체 리터럴은
let user = {
name: 'john', // name: 'john' 이라는 프로퍼티와
age: 30 // age: 20 이라는 프로퍼티들로 구성되어있다.
}
👩💻 프로퍼티 값 읽어오기
let user = {
name: 'John',
age: 30,
'likes birds': true
};
1) 대괄호 표기법
- 여러 단어를 조합해 프로퍼티 키를 만든 경우 사용한다.
console.log(user['likes birds']); // true
2) 점 표기법
console.log(user.name); // John
⚠️ const로 선언된 객체는 수정이 가능하다.
const user = {
name: 'John'
}
user.name = 'Amy';
console.log(user.name); // Amy
- const는 user의 값을 고정하지만 해당 내용은 고정하지 않는다.
🧮 계산된 프로퍼티
- 객체를 만들 때 객체 리터럴 안의 프로퍼티 키가 대괄호로 둘러싸여 있는 경우
let age = '나이';
let soo = {
name: 'soo',
[age]: 27
}
console.log(soo); // {name: 'soo', 나이: 27}
console.log(soo[age]); //27
👀 단축 프로퍼티
- 프로퍼티 값을 기존 변수에서 받아와 사용하는 경우에 사용
function makeUser(name, age) {
return {
name: name, // 이름과 값이 변수의 이름과 동일하다
age: age,
}
}
let user = makeUser('John', 20);
console.log(user.name); // John
// 이럴 경우 프로퍼티 값 단축 구문을 사용하면 코드를 짧게 줄일 수 있다.
function makeUser(name, age) {
return {
name, // 프로퍼티 값 단축 구문
age,
}
}
let user = makeUser('John', 20);
console.log(user.name); // John
🙌 프로퍼티 이름의 제약 사항
- 변수 이름에는 'for', 'let', 'return' 같은 예약어를 사용해서는 안되는데, 객체에는 이런 제약이 있지는 않다.
- 그러나 특별하게 제약이 되는 이름이 하나 있다. --> '__proto__'
🔍 프로퍼티 존재 여부 확인 in'
- 'in' 연산자 사용
let user = { age: 30 };
let key = "age";
console.log(key in age); // true
🔁 for...in 반복문
- 객체의 모든 키를 순회할 수 있다.
for(key in object) {
...
}
let user = {
name: 'soo',
age: 27,
isAdmin: true
}
for(let key in user) {
// 키
console.log(key); // name, age, isAdmin
// 키에 해당하는 값
console.log([key]); // soo, 27, true
}
✨ 메서드, Method
- 객체 프로퍼티에 저장된 함수
- this로 객체를 참조한다.
let user = {
name: 'John',
age: 30
}
// 객체 프로퍼티 user.sayHi에 함수를 할당해줌
// 할당된 함수가 Method!
user.sayHi = function() {
alert('hello')
}
user.sayHi();
- 메서드 단축 구문
user = {
sayHi: function() {
alert('Hello');
}
};
// 위의 함수를 단축 구문으로 바꿔보기
user = {
sayHi() {
alert('Hello');
}
};
🙋♀️ 메서드와 this
- 메서드는 객체에 저장된 정보에 접근할 수 있어야 제 역할을 할 수 있다.(대부분의 메서드가 객체 프로퍼티의 값을 활용한다.)
- 메서드 내부에서 this 키워드를 사용하면 객체에 접근할 수 있다.
let user = {
name: 'John',
age: 30,
// 이때 this가 가리키는 객체는 '현재 객체' 즉, user
sayHi() {
console.log('hello ' + this.name); // hello John
}
}
// user.sayHi()가 실행되는 동안에 this는 user 나타낸다.
user.sayHi();
- this는 자유롭다 -> 'strict mode' 가 아닐때는 this는 전역 객체를 참조한다.
🙌 자유로운 this가 만든 결과
- this가 항상 메서드가 정의된 객체를 참조할 것이라고 착각하게 된다. -> bound this
- 자바스크립트에서 this는 런타임 때 결정된다.
- 메서드가 어디서 정의되었던간에 상관없이 '.' 앞에 객체가 무엇인가에 따라 자유롭게 결정된다.
- ES6에서는 Arrow function 도입(자신만의 this를 가지지 않기 때문)
- Arrow fucntion 에서 this 참조하면 arrow function 내부가 아닌 평범한 외부함수에서 this 값을 가져온다.
- 별개의 this가 만들어지는건 원하지 않고, 외부에 있는 this를 참조하고 싶은 경우 사용
✨ new 연산자, 생성자 함수
- 유사한 객체를 여러 개 만들어야 할때 사용한다.
👩💻 생성자 함수 만들기
1) 함수 이름의 첫 글자는 대문자로 시작
2) 반드시 'new' 연산자를 붙여 실행한다.
- new User() 써서 함수 실행할때의 알고리즘
1) 빈 객체를 만들어 this에 할당
2) 함수 본문 실행, this에 새로운 프로퍼티 추가해 this 수정
3) this 반환
function User(name) {
// this = {}; 빈 객체가 임시적으로 만들어짐
// 새로운 프로퍼티를 this에 추가
this.name = name;
this.isAdmin = false;
// return this; this 암시적으로 반환
}
// 1) 함수 이름의 첫 글자는 대문자로 시작
// 2) 반드시 'new' 연산자 붙여 실행
let user = new User('수영');
console.log(user.name); // 수영
console.log(user.isAdmin); // false
🕵️ 익명 생성자 함수
- 재사용할 필요가 없는 복잡한 객체를 만들어야 할 때 사용
- 익명함수는 어디에도 저장되지 않는다.
- 처음부터 단 한번의 호출을 위해 만들어졌기 때문에 재사용 불가
- 재사용을 막으면서 코드를 캡슐화 할 수 있다.
let user = new function() {
this.name = '수영';
this.isAdmin = true;
}
🙋♀️ 캡슐화?
- Encapsulation
- 객체 지향 프로그래밍에서
1) 객체의 속성과 행위를 하나로 묶고
2) 실제 구현 내용 일부를 내부에 감추어 은닉한다.
- 클래스 내부 변수와 메소드를 하나로 패키징 하는 것.