자바스크립트는 객체 기반의 프로그래밍 언어이다.
자바스크립트에서 원시 값을 제외한 거의 모든 것이 객체이다.
- 원시 타입
- 단 하나의 값을 나타낸다.
- 원시 값은 변경이 불가능(
immutable value
)하다.
- 객체 타입
- 다양한 타입의 값을 하나의 단위로 구성한 복합적인 자료구조
- 객체는 변경이 가능(
mutable value
)하다.
let person = {
//person은 객체
name: "Lee", //이 행 하나가 프로퍼티
age: 20, //age는 프로퍼티의 key, 20은 프로퍼티의 value
};
- 위와 같이 객체는 0개 이상의 프로퍼티로 구성된 집합을 의미한다.
- 자바스크립트에서 사용될 수 있는 모든 값은 프로퍼티 값으로 사용될 수 있다.
- 함수 역시, 자바스크립트에서는
일급 객체
이므로, 프로퍼티가 될 수 있다. - 프로퍼티 값이 함수인 경우에는 이를
메서드(method)
라고 한다.
let counter = { //counter는 객체 num: 0, //이 행 하나가 프로퍼티 increase: () => { //increase는 메서드 this.num++; }, };
일급 객체
란, 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 의미함.
> 일급 객체 - 위키피디아 - 함수 역시, 자바스크립트에서는
결국
객체
는, 상태와 동작을 하나의 단위로 구조화할 수 있다는 점에서 유용하다!
- 프로퍼티
- 객체의 상태를 나타내는 값(data)
- 메서드
- 프로퍼티(상태 데이터)를 참조하고 조작할 수 있는 동작(behavior)
클래스 기반 객체지향 언어
에서의 객체 생성- 클래스를 사전에 정의
- 필요한 시점에
new
연산자로 생성자 호출 - 인스턴스를 생성
인스턴스
란, 클래스에 의해 생성되어 메모리에 저장된 실체를 의미한다.클래스
는 인스턴스를 생성하기 위한 템플릿의 역할을 한다.
프로토타입 기반 객체지향 언어(javascript)
에서의 객체 생성- 객체 리터럴
- 가장 표준의 방법
- 리터럴이란, 사람이 이해할 수 있는 문자나 기호를 통해 값을 생성하는 표기법
- Object 생성자 함수
- 생성자 함수
- Object.create 메서드
- 클래스(ES6)
- 객체 리터럴
리터럴의 의미와 같이, 객체 리터럴은 객체를 생성하기 위한 표기법이다.
let person = {
//중괄호 안에0개 이상의 프로퍼티를 정의
name: "중규리",
sayHello: () => {
console.log(`ㅎㅇ 내 이름은 ${this.name}`);
},
};
console.log(typeof person); //object
console.log(person); //{name: "중규리", sayHello: f}
- 위의 예제와 같이, 중괄호 안에 0개 이상의 프로퍼티를 정의하여 객체를 생성한다.
- 프로퍼티를 정의하지 않으면, 빈 객체가 생성된다.
- 기존의
클래스 기반 객체지향 언어
와 다르게 굉장히 유연하고 강력하다.- 원시 타입의 값을 만드는 것과 유사하게 객체를 생성할 수 있다.
- 프로퍼티를 포함하여 객체를 생성할 수 있다.
- 프로퍼티를 새롭게 만들 수 있다.
- 객체 생성 이후에 프로퍼티를 동적으로 추가할 수 있다.
- 객체 리터럴을 이용하지 않고 객체를 생성하기 위해선,
함수
를 사용할 수 있다.
프로퍼티는 {
key
:value
}로 이루어져있다.
- 프로퍼티를 나열할 때는 쉼표(
,
)를 사용한다.
-
프로퍼티 Key
- 빈 문자열을 포함하는 모든 문자열 또는 심벌 값
-
프로퍼티 Value
- 자바스크립트에서 사용할 수 있는 모든 값
-
반드시 따라야하는 것은 아니다.
-
따르지 않는다면, 반드시 따옴표로 묶어야한다.
-
가급적 네이밍 규칙을 준수하는 것이 좋다.
let person = { //올바른 예시 firstName: "중규", //식별자 네이밍 규칙O 'last-name': "리" //식별자 네이밍 규칙X }; let person2 = { //잘못된 예시 firstName: "중규", last-name: "리", //에러 } console.log(person); // {firstName: "중규", last-name: "리"}
person2
의last-name
은 식별자 네이밍 규칙을 준수하지 않는다.- 이 경우, 자바스크립트 엔진은 (-) 연산자가 있는 표현식으로 해석해버린다😨
let obj = {};
let key = "hello";
obj[key] = "world";
console.log(obj)l //{hello : "world"}
- 문자열 또는 문자열로 평가할 수 있는 표현식을 사용해 프로퍼티 키를 동적으로 생성 가능하다.
- 이 경우, 키를 대괄호로 묶어야한다.
-
빈 문자열을
Key
로 사용하는 경우- 에러는 없지만, 권장하지는 않는다.
-
Key
에 문자열이나 심벌 값 외의 값을 사용하는 경우- 암묵적 타입 변환을 통해 문자열이 된다.
let foo = { //프로퍼티 키로 숫자 리터럴 사용 0: 1, 1: 2, 2: 3, }; // 따옴표는 붙지 않지만, 내부적으로는 문자열로 변환됨 console.log(foo); //{0:1, 1:2, 2:3}
-
let
const
와 같은 예약어를Key
로 사용하는 경우- 에러는 없지만, 권장하지는 않는다.
-
이미 존재하는
Key
를 중복 선언 하는 경우- 나중에 선언한 프로퍼티가 먼저 선언된 프로퍼티를 덮어쓴다.
- 에러가 발생하지 않으니 주의할 것!
객체와 프로퍼티와 중복되는 부분이 존재합니다.
- 자바스크립트에서 사용될 수 있는 모든 값은 프로퍼티 값으로 사용될 수 있다.
- 함수 역시, 자바스크립트에서는
일급 객체
이므로, 프로퍼티가 될 수 있다. - 프로퍼티 값이 함수인 경우에는 이를
메서드(method)
라고 한다. - 즉, 메서드는 객체에 묶여있는 함수를 의미한다.
- 메서드에서 사용하는
this
는, 객체 자신을 가리키는 참조 변수이다.
let counter = { //counter는 객체 num: 0, //이 행 하나가 프로퍼티 increase: () => { //increase는 메서드 this.num++; }, };
일급 객체
란, 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 의미함.
> 일급 객체 - 위키피디아 - 함수 역시, 자바스크립트에서는
-
Key
가 네이밍 규칙을 준수하지 않는 경우, 사용할 수 없다.let person = { name: "중규리", }; console.log(person.name); // 중규리
- 마침표로
Key
에 접근한다.
- 마침표로
-
키가 네이밍 규칙을 준수하지 않는 경우에도 사용할 수 있다.
- 키가 숫자인 경우를 제외하고, 반드시 따옴표로 감싼 문자열이어야만 한다.
let person = { name: "중규리", }; console.log(person["name"]); // 중규리 console.log(person[name]); //에러
Key
를 따옴표로 감싸지 않으면, 자바스크립트 엔진은 식별자로 해석한다.
- 객체에 존재하지 않는 프로퍼티에 접근한다면?
undefined
을 반환한다.
let person = {
"last-name" : "중규리",
};
person.'last-name'; //2 _ 에러 -> Unexpected string
person.last-name; //3 _ 브라우저 : Nan | Node.js : 에러 -> name is not defined
person[last-name]; //4 _ 에러 -> last is not defined
person['last-name']; //중규리
Key
가 네이밍 규칙을 준수하지 않는 경우, 대괄호 표기법만 사용할 수 있다.- 브라우저는
Nan
, Node.js는ReferenceError
인 이유는?person.last
를 먼저 평가하게 된다.person
에last
프로퍼티 키가 없기 때문에undefined
로 평가한다.undefined
- name이 된다.name
이라는 식별자를 찾는다.name
은 프로퍼티 키가 아니라 식별자로 해석된다.
- Node.js
name
이라는 식별자가 존재하지 않는다.Reference Error
!
- 브라우저
name
이라는 전역 변수가 암묵적으로 존재한다.window
객체 속에 있다.- 현재 창의 이름을 가리키며, 기본 값은 문자열이다.
- 따라서
undefined
- ""와 같다.Nan
!
- 위와 동일한 이유이다.
이미 존재하는 프로퍼티에 값을 할당하면 프로퍼티 값이 갱신된다.
delete
연산자를 통해 프로퍼티를 삭제할 수 있다.- 존재하지 않는 프로퍼티를 삭제해도, 에러가 발생하지 않는다.
- 주의할 것!
더욱 간편하고 표현력 있는 확장 기능을 제공한다.
-
변수의 이름이
Key
, 값이Value
로 객체를 생성할 수 있다.//ES6 이전 var x = 1, y = 2; var obj = { x: x, y: y, }; //ES6에서 let obj2 = { x, y }; // obj와 obj2의 구성은 동일하다.
-
식을 통해 프로퍼티
Key
를 동적으로 생성할 수 있다.- 단, 표현식을 대괄호로 묶어야만 한다.
-
ES5
- 객체 리터럴 외부에서 대괄호 표기법을 사용한다.
var prefix = "prop"; var i = 0; var obj = {}; obj[prefix + "-" + ++i] = i; obj[prefix + "-" + ++i] = i; obj[prefix + "-" + ++i] = i; console.log(obj); //{prop-1: 1, prop-2: 2, prop-3: 3}
-
ES6
- 객체 리터럴 내부에서 대괄호 표기법을 사용할 수 있다.
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}
-
메서드 정의 시, 함수 생성 키워드 없이 축약할 수 있다.
-
축약한 함수는, 프로퍼티에 할당한 함수와 다르게 동작한다.
- 이에 대해선 26.2절에서 자세히 설명한다.
//ES5 let obj = { name: "중규리", sayHi: function () { console.log("ㅎㅇㅋㅋ"); }, }; //ES6 let obj2 = { name: "중규리", sayHi() { console.log("ㅎㅇㅋㅋ"); }, };