모던 자바 스크립트 Deep Dive 를 읽고 정리한 글 입니다.
10. 1 객체란?
자바스크립트는 객체 기반의 프로그래밍 언어 (원시 값을 제외한 나머지 값은 모두 객체)
원시 타입 | 객체 타입 |
단 하나의 값만 나타냄 | 다양한 타입의 값 (원시 포함)을 하나의 단위로 구성한 복합적 자료구조 |
변경 불가능한 값 | 변경 가능한 값 |
객체
0개 이상의 프로퍼티와 메서드로 구성된 집합
상태와 동작을 하나의 단위로 구조화 할 수 있음
자바스크립트의 객체는 함수와 밀접한 관계
프로퍼티
객체의 상태를 나타내는 값
자바스크립트에서 사용할 수 있는 모든 값은 프로퍼티 값이 될 수 있음
키와 값으로 구성
메서드
프로퍼티(상태 데이터)를 참조하고 조작할 수 있는 동작
메서드 = 프로퍼티 값이 함수, 일반 함수와 구분 됌
객체지향 프로그래밍
객체의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임
클래스와 인스턴스 포함한 개념
- 클래스 : 인스턴스를 생성하기 위한 템플릿 역할
- 인스턴스 : 클래스에 의해 생성되어 메모리에 저장된 실체
10. 2 객체 리터럴에 의한 객체 생성
클래스 기반 객체지향 언어
- 언어 : C++, Java
- 객체 생성 방법
- 클래스를 사전에 정의
=> 필요한 시점에 new 연산자와 함께 생성자 호출
=> 인스턴스 생성
=> 객체 생성
- 클래스를 사전에 정의
프로토타입 기반 객체지향 언어
- 언어 : 자바스크립트
- 객체 생성 방법
- 객체 리터럴 : 객체를 생성하기 위한 표기법
=> 중괄호({...}) 내에 0개 이상의 프로퍼티 정의
=> 변수 할당되는 시점 - 객체 리터럴 해석
=> 객체 생성
- 객체 리터럴 : 객체를 생성하기 위한 표기법
- 중괄호 내 프로퍼티 미정의 => 빈 객체 생성
- 객체 리터럴의 중괄호는 코드 블럭을 의미하지 않음 -> 세미콜론 붙이기
- 객체를 생성하기 위해 클래스 정의, new 연산자와 함께 생성자 호출 : 생략 가능
- 프로퍼티를 포함하여 객체 생성과 동시에 프로퍼티 제작 가능, 그 후 동적 추가 가능
- Object 생성자 함수
- 생성자 함수
- Object.create 메서드
- 클래스(ES6)
10. 3 프로퍼티
프로퍼티
프로퍼티를 나열할 때 쉼표로 구분
마지막 프로퍼티 뒤에 쉼표는 선택
var person ={
name: 'Lee', // 프로퍼티 키: name, 프로퍼티 값: 'Lee'
age: 20 // 프로퍼티 키: age, 프로퍼티 값: 20
};
- 프로퍼티 값
- 자바스크립트에서 사용할 수 있는 모든 값
- 프로퍼티 키
- 빈 문자열을 포함하는 모든 문자열 또는 심벌 값
- 프로퍼티 값에 접근할 수 있는 이름, 식별자
빈 문자열 프로퍼티 키로 사용 가능 - 키로서 의미 X, 비권장
var foo = {
' ':' '
};
console.log(foo); // => {" ":" "}
식별자 네이밍 규칙 선택 사용
(식별자 네이밍 규칙을 따르지 않은 경우에는 따옴표 생략 불가능)
var person = {
firstName: 'Ung-mo', // 식별자 네이밍 규칙 준수
'last-name': 'Lee', // 식별자 네이밍 규칙 미준수
last-name: 'Lee' // 식별자 네이밍 규칙 미준수 따옴표 생략
// => SyntaxError: Unexpected token
};
문자열 / 문자열 평가 표현식 사용으로 프로퍼티 키 동적 생성 가능
(프로퍼티 키로 사용할 표현식을 대괄호([...])로 묶음)
var obj = {};
var key = 'hello';
obj[key] = 'world';
// var obj = { [key]: 'world' };
console.log(obj); // => {hello: "world"}
문자열, 심벌 값 외의 값 - 암묵적 타입 변환으로 문자열이 됌
var foo = {
0: 1,
1: 2,
2: 3
};
console.log(foo); // => {0: 1, 1: 2, 2: 3}
예약어를 프로퍼티 키로 사용 가능 - 비권장
var foo = {
var: ' ',
function: ' '
};
console.log(foo); // => {var: " ", function: " "}
프로퍼티 키 중복 선언시 먼저 선언한 프로퍼티 덮어씀
var foo = {
name: 'Lee',
name: 'Kim'
};
console.log(foo); // => {name: "Kim"}
10. 4 메서드
메서드
프로퍼티 값이 함수
객체에 묶여 있는 함수
var circle = {
redius: 5, // 프로퍼티
// 원의 지름
getDiameter: function () { // 메서드
return 2 * this.readius; // this = circle
}
}
};
console.log(circal.getDiameter()): // => 10
10. 5 프로퍼티 접근
마침표 표기법 (.) | 대괄호 표기법 ([...]) |
마침표 프로퍼티 접근 연산자 | 대괄호 프로퍼티 접근 연산자 |
접근 연산자 : 객체로 평가되는 표현식 | 좌측 : 객체로 평가되는 표현식 |
우측 : 프로퍼티 키 지정 | 접근 연산자 내부 : 프로퍼티 키 지정 |
따옴표 필수 |
var person = {
name: 'Lee'
};
// 마침표 표기법에 의한 프로퍼티 접근
consloe.log(person.name); // => Lee
// 대괄호 표기법에 의한 프로퍼티 접근
consloe.log(person['name']); // => Lee
// 대괄호 표기법에 의한 프로퍼티 접근 : 따옴표 생략
consloe.log(person[name]); // => ReferenceError: name is not defined
// 객체에 존재하지 않는 프로퍼티
consloe.log(person.age); // => undefined
객체에 존재하지 않는 프로퍼티에 접근하면 undefined 반환
RefrenceError 발생하지 않음
자바스크립트에서 사용 가능한 유효 이름은 반드시 대괄호 표기법 사용
(프로퍼티 키가 숫자로 이뤄진 문자열인 경우 따옴표 생략가능)
var person = {
'last-name' : 'Lee'
1: 10
};
person.'last-name'; // => SyntaxError: Unexpected string
person.last-name;
// 브라우저 환경
//=> 전역변수 name -> window 이름 기본값 빈문자열 -> undefined-'' -> NaN
// Node.js 환경
//=> 식별자 name 탐색 -> ReferenceError: name is not defind
// 자바스크립트 환경
//=> person 객체의 프로퍼티 키 last 탐색 -> undefined-name -> 식별자 name 탐색
person.[last-name]; // => ReferenceError: last is not defined
person.['last-name']; // => Lee
//프로퍼티 키가 숫자로 이뤄진 문자열인 경우 따옴표 생략 가능
person.1; // => SyntaxError: Unexpected number
person.'1'; // => SyntaxError: Unexpected string
person.[1]; // => 10 : perxon[1] -> person['1']
person.['1']; // => 10
10. 6 프로퍼티 값 갱신
프로퍼티 값 갱신
이미 존재하는 프로퍼티에 값을 할당
var person = {
name: 'Lee'
};
// person 객체에 name 프로퍼티 존재 -> name 프로퍼티 값 갱신
person.name = 'Kim';
console.log(person); // => {name: "kim"}
10. 7 프로퍼티 동적 생성
프로퍼티 동적 생성
존재하지 않는 프로퍼티에 값을 할당
var person = {
name: 'Lee'
};
// person 객체에 age 프로퍼티 존재하지 않음
// person 객체에 age 프로퍼티 동적 생성, 값 할당
person.age = 20;
console.log(person); // => {name: "Lee", age: 20}
10. 8 프로퍼티 삭제
프로퍼티 삭제
delete 연산자는 객체의 프로퍼티 삭제
delete 연산자의 피연산자는 프로퍼티 값에 접근할 수 있는 표현식
존재하지 않는 프로퍼티 삭제시 무시
var person = {
name: 'Lee'
};
// 프로퍼티 동적생성
person.name = 20;
// person 객체에 age 프로퍼티 존재
// delete 연산자로 age 프로퍼티 삭제
delete person.age;
// person 객체에 address 프로퍼티 미존재
// delete 연산자로 address 프로퍼티 삭제 불가, 에러 X
delete person.address;
console.log(person); // => {name: "Lee"}
10. 9 ES6에서 추가된 객체 리터럴의 확장 기능
프로퍼티 축약 표현
프로퍼티 값으로 변수를 사용할 때 변수 이름과 프로퍼티 키가 동일 이름
=> 프로퍼티키 생략 가능, 프로퍼티키는 변수 이름으로 자동 생성
let x = 1, y = 2;
const obj = { x, y};
console.log(obj); // => {x: 1, y: 2}
계산된 프로퍼티 이름
객체 리터럴 내부에서 계산된 프로퍼티 이름으로 프로퍼티 키 동적 생성 가능
const prefix = 'prop';
let i = 0;
const obj = {
['${prefix}-${++i}']: i,
['${prefix}-${++i}']: i,
['${prefix}-${++i}']: i
};
console.log(obj); // => {prop-1: 1; prop-2: 2, prop-3: 3}
메서드 축약 표현
메서드 정의할 때 function 키워드 생략 가능
const obj = {
name: 'Lee',
sayhi() {
console.log('hi!' + this.name);
}
};
obj.sayhi(); // => hi! Lee
계산된 프로퍼티 이름
객체 리터럴 내부에서 계산된 프로퍼티 이름으로 프로퍼티 키 동적 생성 가능
메서드 축약 표현으로 정의한 메서드는 프로퍼티에 할당한 함수와 다르게 동작
const prefix = 'prop';
let i = 0;
const obj = {
['${prefix}-${++i}']: i,
['${prefix}-${++i}']: i,
['${prefix}-${++i}']: i
};
console.log(obj); // => {prop-1: 1; prop-2: 2, prop-3: 3}