일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- 이해할 수 있는
- 오블완
- javascript
- 노개북
- 최원영 저자
- K-Digital Credit
- 프로그래머스
- 제로베이스
- 자격증
- CodeStates
- 자바스크립트
- 개발자북클럽
- Do it! 시리즈
- 모던 자바스크립트 deep dive
- SQLD
- boj
- SQL 개발자
- nomadcoders
- 공부를 가장한 일기일지도
- 알고리즘
- js
- 엘리스코딩
- 톺아보기
- 노마드 코더
- 백준
- 노마드코더
- 비전공자를 위한
- 티스토리챌린지
- 구름edu
- IT 지식
- Today
- Total
개발자를 희망하는 초보의 자기개발 이야기
모던 자바스크립트 Deep Dive 10장 객체 리터럴 본문
스터디를 진행하면서 책을 읽고 내용과 떠오르는 생각, 용어들을 정리하고 있습니다.
문제 되는 부분이나 틀린 부분이 있다면 편하게 말씀해 주세요.
10장 객체 리터럴
10.1 객체란?
자바스크립트는 객체(object) 기반의 프로그래밍 언어이며, 원시 값을 제외한 자바스크립트를 구성하는 거의 모든 것 (함수, 배열, 정규 표현식 등) 이 객체다. 객체 타입은 다양한 타입의 값을 하나의 단위로 구성한 복합적인 자료구조(data structure)다. 원시 값은 변경 불가능한 값(immutable value)이지만 객체 타입의 값은 변경 가능(mutable value)하다. 객체는 0개 이상의 프로퍼티로 구성된 집합이며, 프로퍼티는 키와 값으로 구성된다. 이는 콜론( : )으로 구분한다.
var human = {
name: 'Lee',
age: 30
sayHello : function () {
console.log`Hello! My name is ${this.name}.`);
};
자바스크립트의 함수는 일급 객체이므로 값으로 취급할 수 있다. 프로퍼티 값이 함수일 경우, 일반 함수와 구분하기 위해 메서드라 부른다. 위의 코드에서 human.sayHello()가 메서드다. 객체는 프로퍼티와 메서드로 구성된 집합체로 위의 코드에서 name과 age는 프로퍼티에 해당한다. 이처럼 상태와 동작을 하나의 단위로 구조화할 수 있어 유용하다. 객체의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임을 객체지향 프로그래밍(OOP, Object Oriented Programming)이라 한다.
※ 일급 객체란?
: 객체가 함수의 변수로 활용이 가능하거나 인자로 넘길 수 있거나, 변수에 할당할 수 있는 등, 연산을 지원할 때 일급객체라 한다. 일반적으로 객체 내에 자바스크립트의 함수는 표현식으로 할당되는데 표현식이 결과가 값으로 반환되는 것과 마찬가지라 볼 수 있다.
※ 객체와 함수의 연관관계란?
: 자바스크립트의 객체는 함수와 밀접한 관계를 가진다. 함수로 객체를 생성할 수도 있고, 함수 자체가 객체이기도 하기 때문에 함수와 객체는 분리해서 생각할 수 없다.
10.2 객체 리터럴에 의한 객체 생성
클래스기반 객체지향 언어는 new 연산자와 함께 생성자(Constructor)를 호출하여 인스턴스를 생성하는 방식으로 객체를 생성한다. 하지만 자바스크립트는 프로토타입 기반 객체지향 언어로 다양한 객체 생성 방법을 지원한다.
※ 인스턴스란?
: 클래스는 인스턴스를 생성하기 위한 템플릿 역할을 하며 이 템플릿을 통해 메모리에 저장된 실체를 인스턴스라 한다.
※ 프로토타입이란?
: 모든 기능을 내려받아 이용할 수 있는 모체 같은 것이다. 자바스크립트에서는 기본적으로 클래스가 없는 대신 객체의 원형을 이루는 프로토타입이라는 것이 존재한다. 최근 자바스크립트에 클래스 문법이 추가되었다.
- 객체 리터럴
- Object 생성자 함수
- 생성자 함수
- Object.create 메서드
- 클래스(ES6)
var person = {
name: 'Lee',
sayHello: function () {
console.log(`Hello! My name is ${this.name}.`);
}
};
가장 일반적이고 간단한 방법은 위와 같이 객체 리터럴을 사용하는 방법으로 중괄호 내에 0개이상의 프로퍼티를 정의해서 생성한다. 중괄호 내에 프로퍼티를 정의하지 않으면 빈 객체가 생성된다. 코드 블록은 중괄호를 닫을 때 세미콜론을 붙이지 않는다. 하지만 객체 리터럴은 중괄호가 코드 블록을 의미하지 않는다. 값으로 평가되는 하나의 표현식으로 평가하기 때문에 블록 끝에 세미콜론을 붙인다. 클래스 정의와 new 연산자를 통한 생성자 호출이 필요 없기 때문에 자바스크립트의 유연함과 강력함을 대표하는 생성 방식이다. 그 이외에 생성 방식은 모두 함수를 사용한다.
10.3 프로퍼티
객체는 프로퍼티의 집합이며, 프로퍼티는 키와 값으로 구성된다.
- 프로퍼티 키 : 빈 문자열을 포함한 모든 문자열 또는 심벌 값
- 프로퍼티 값 : 자바스크립트에서 사용할 수 있는 모든 값
프로퍼티 키는 문자열이므로 따옴표( '...' 또는 "..." )로 묶어야 한다. 식별자 네이밍 규칙을 따르지 않는 이름에는 반드시 따옴표를 사용해야 한다.
var person = {
firstName : 'Dong-won',
'last-name' : 'Kang',
'': '',
0:0,
'last-name' : 'Kim'
};
네이밍 규칙을 준수하는 경우 따옴표를 생략할 수 있으나, 예를 들어 last-name은 식별자 네이밍 규칙을 준수하지 않기 때문에 따옴표를 생략할 수 없다.( -를 연산자가 있는 표현식으로 해석한다.) 빈 문자열도 프로퍼티 키로 사용할 수 있으나 의미를 갖지 못하므로 권장하지 않는다. 프로퍼티 키에 문자열이나 심벌 값 외의 값을 사용하면 암묵적 타입 변환을 통해 문자열이 된다. 프로퍼티 키를 중복 선언하면 먼저 선언한 프로퍼티를 덮어쓰고 나중에 선언한 프로퍼티가 적용된다. 이때 에러가 발생하지 않는다는 것에 주의해야 한다.
※ 네이밍 규칙이란?
: 카멜케이스( 예: myVariable, calculateTotal), 파스칼케이스( 예: MyClass, CalculateTotal), 스네이크케이스( 예: my_variable, calculate_total)와 같이 식별자의 네이밍을 일정한 형식으로 하는 것을 의미한다.
10.4 메서드
프로퍼티의 값이 함수일 경우 일반 함수와 구분하기 위해 메서드라 부른다. 즉, 메서드는 객체에 묶여 있는 함수를 의미한다.
var user = {
str: 20,
int: 20,
attack: function() {
console.log("공격하였습니다.")
return this.str*2; // 40
}
}
console.log(user.attack.call()); // NaN
window.str = 20;
console.log(user.attack.call()); // 40
메서드 내부에서 사용한 this 키워드는 객체 자신(위 예제에서는 user 객체)을 가리키는 참조변수다. 메서드 외부에서 사용한 this는 window 객체를 가리키게 되고 window내에 str은 ""로 선언될 것이기 때문에 call()함수로 호출 시 NaN이 출력된다. window 객체의 str에 20을 따로 할당하면 동일한 결과가 나오는 것으로 this가 호출위치에 따라 달라짐을 알 수 있다.
10.5 프로퍼티 접근
프로퍼티에 접근하는 방법은 다음과 같이 두 가지다.
- 마침표 프로퍼티 접근 연산자(.)를 사용하는 마침표 표기법(dot notation)
- 대괄호 프로퍼티 접근 연산자([...])를 사용하는 대괄표 효기법(bracket notation)
대괄호 프로퍼티 접근 연산자 내부에서 지정하는 프로퍼티 키는 반드시 따옴표로 감싼 문자열이어야 한다. 네이밍 규칙을 준수하지 않는 이름은 반드시 대괄호 표기법을 사용해야 하며, 객체에 존재하지 않는 프로퍼티에 접근하면 undefined를 반환한다. 이때 ReferenceError가 발생하지 않는데 주의해야 한다.
var key = 'age';
var person = {};
person[key] = 30;
console.log(person.age); // 30
위의 코드는 빈 person 객체에 새로운 프로퍼티를 추가하고 있다. 이 때 key라는 프로퍼티 키가 person 객체 내부에 없기 때문에 변수 key를 가져오게 되고, person['age']와 같은 결과가 된다. 즉, person['age'] = 30으로 age 키에 30 값을 할당한다.
10.6 프로퍼티 값 갱신
이미 존재하는 프로퍼티에 값을 재할당하면 프로퍼티 값이 갱신된다. 이는 단점이 더 큰데 기존에 동일한 프로퍼티가 있다는 어떠한 메세지도 나타나지 않기 때문이다. 타입스크립트가 나온 여러 이유 중 하나이기도 하다.
10.7 프로퍼티 동적 생성
존재하지 않는 프로퍼티에 대해 값을 할당하면 프로퍼티가 동적으로 생성 및 추가되고 값이 할당된다.
var human = {
name: 'Lee'
};
human.age = 30;
console.log(human); // {name: 'Lee', age: 30}
10.8 프로퍼티 삭제
delete 연산자는 객체의 프로퍼티를 삭제한다. delete 연산자의 피연산자는 프로퍼티 값에 접근할 수 있는 표현식이어야 한다. 주의할 것은 존재하지 않는 프로퍼티를 삭제하더라도 에러가 발생하지 않는다.
var person = {
name : 'Lee',
age : 20
}
delete person["a"+"ge"] // true
console.log(person) // {name: 'Lee'}
10.9 ES6에서 추가된 객체 리터럴의 확장 기능
10.9.1 프로퍼티 축약 표현
프로퍼티 값은 변수에 할당된 값, 즉 식별자 표현식일 수도 있다. 프로퍼티의 값으로 전역객체에 있는 변수를 값으로 할당할 수 있다는 뜻이다.
var num = 20;
var obj = {
output : num
};
console.log(obj.output); // 20
프로퍼티 값으로 변수를 사용하는 경우 변수 이름과 프로퍼티 키가 동일한 이름일 때 프로퍼티 키를 생략할 수 있다. 이때 프로퍼티 키는 변수 이름으로 자동 생성된다. 즉 아래와 같이 객체를 리터럴로 생성하면서 프로퍼티 키만 기재하면 동일한 변수명이 있다면 해당 변수의 할당된 값이 프로퍼티 값으로 자동 할당된다.
let x = 1, y = 2;
const obj = { x, y };
console.log(obj); // { x: 1, y: 2 }
10.9.3 메서드 축약 표현
ES6에서는 메서드를 정의할 때 function 키워드를 생략한 축약 표현을 사용할 수 있다.
const obj = {
name: 'Lee',
sayHi() {
console.log('Hi! ' + this.name);
}
};
일반적인 function 형태로 메서드를 생성 시 new 생성자를 통해 인스턴스를 생성할 수 있다. 그런데 축약형으로 메서드를 생성하면 해당 메서드 자체에 생성자(constructor)가 없는 형태로 생성되기 때문에 new 생성자 함수로 인스턴스 생성이 되지 않는다.
정리
오래전에 자바책을 먼저 접했었는데 클래스를 기반으로 한 new 생성자로 객체와 인스턴스 챕터를 보면서 절망했던 기억이 난다. 객체와 인스턴스는 많은 교재에서 설명할 때 자동차나 붕어빵을 전통적으로 선호하는 것 같다. 물론 그 설명도 좋지만 나는 인강 중에 객체와 인스턴스를 게임 신규 캐릭터 생성으로 설명해 주신 강의로 확실히 개념을 잡았다. 그리고 자바스크립트에서는 객체 리터럴로 간단히 객체가 생성되는 것을 보니 신세계였다.
객체 프로퍼티 접근 시에는 마침표와 대괄호 둘 다 접근이 가능한데 json 파일에서 반복해서 프로퍼티를 가져와야 할 때 json파일 자체에 네이밍 규칙을 준수하지 않는 데이터가 종종 있어서 대괄호 접근 연산자를 좀 더 선호하게 되는 것 같다. 여담으로 과거 부트캠프 수강 시 강사님이 '둘 다 똑같은데 반복문 쓸 때는 대괄호로 하세요'라고 해서 한동안 이유도 모르고 대괄호로 썼다...; ES6의 축약형 같은 경우 추후 나올 객체 구조분해할당과 일맥상통하는 부분이 있어서 알고 넘어가면 리액트 공부시 도움이 된다.
'도서 > 모던 자바스크립트 Deep Dive' 카테고리의 다른 글
모던 자바스크립트 Deep Dive 9장 타입 변환과 단축 평가 (0) | 2023.11.13 |
---|---|
모던 자바스크립트 Deep Dive 8장 제어문 (0) | 2023.11.10 |
모던 자바스크립트 Deep Dive 7장 연산자 (2) | 2023.11.09 |
모던 자바스크립트 Deep Dive 6장 데이터 타입 (0) | 2023.11.08 |
모던 자바스크립트 Deep Dive 5장 표현식과 문 (0) | 2023.11.07 |