JS 객체

자바스크립트는 객체 기반의 프로그래밍 언어이다. 원시 타입을 제외한 나머지 값들은 모두 객체이다.

  • 프로퍼티: 객체의 상태를 나타내는 값(data).
  • 메소드: 프로퍼티를 참조하고 조작할 수 있는 동작(behavior). 프로퍼티의 값이 함수일 경우에 일반 함수와 구분하기 위해 메소드라 부름.
1
2
3
4
5
6
var animal = {
name: 'bunny', // 프로퍼티
introduction: function (){
console.log(`My name is ${this.name}.`);
} //메소드
};

리터럴을 생성하는 방법

  • 객체 리터럴
  • Object 생성자 함수
  • 생성자 함수
  • Object.create 메소드
  • 클래스 (ES6)

객체 리터럴에 의한 객체 생성

  • 가장 일반적이고 간단한 방법
  • 다양한 타입의 값을 생성할 수 있다.
  • 중괄호 안에 0개 이상의 프로퍼티를 정의.
  • 객체 리터럴의 중괄호는 코드블록이 아니기 때문에 세미콜론을 붙인다. (표현식)
1
2
3
4
5
6
7
8
var animal = {
name: 'bunny',
introduction: function (){
console.log(`My name is ${this.name}.`);
}
};
console.log(typeof animal); // object
console.log(animal); // {name: "bunny", introduction: ƒ}

프로퍼티

  • 객체는 프로퍼티(property)들의 집합
  • 프로퍼티는 키(key)와 값(value)로 구성되어 있으며 쉼표로 구분한다. (맨 마지막 프로퍼티에는 사용해도, 하지 않아도 괜찮다.)
  • 프로퍼티 키와 프로퍼티 값으로 사용할 수 있는 값
    • 프로퍼티 키: 빈 문자열을 포함한 모든 문자열(string) 또는 심볼값. 식별자 네이밍 규칙을 따르지 않는 이름에는 반드시 따옴표를 사용하여야 한다. 따옴표를 쓰지 않을 시 SyntaxError.
      1. 첫번째 글자는 반드시 문자, 밑줄(_), 달러 기호 ($)중 하나로 시작한다.
      2. 띄어쓰기나 하이픈(-)을 사용하면 안 된다.
    • 프로퍼티 값: 자바스크립트에서 사용할 수 있는 모든 자료형이 들어갈 수 있다.
  • 프로퍼티 키에 문자열이나 심볼값 이외의 값을 사용하면 암묵적 타입 변환이 되어 문자열 이 된다.
  • 프로퍼티 키를 중복 선언하면 나중에 선언한 프로퍼티가 먼저 선언한 프로퍼티를 덮어쓴다. 오류가 나지 않는다.
  • 빈문자열을 프로퍼티 키로 사용해도 에러가 발생하지는 않으나 키의 의미를 갖지 못하므로 사용하지 않는 것이 좋다.
  • let, funtion 등의 예약어를 프로퍼티 키로 사용해도 에러가 발생하지는 않으나 에러가 발생할 여지가 있으므로 사용하지 않는 것이 좋다.
1
2
3
4
5
6
var animal = {
first_animal: 'bunny', // 유효한 이름
'2nd-animal': 'rabbit' // 유효하지 않은 이름이기 때문에 따옴표 사용
}

console.log(animal);

계산된 프로퍼티 이름(Computed Property name)

문자열 또는 문자열로 변환 가능한 값을 반환하는 표현식을 사용해 프로퍼티 키를 동적으로 생성 가능하다. 프로퍼티 키로 사용할 표현식을 대괄호([ ])로 묶어야 한다.

1
2
3
4
5
6
var animal = {};
var key = 'bunny';

animal[key] = 'cute';

console.log(animal); // {bunny: "cute"}

메소드

객체에 제한되어 있는 함수. 연관성이 있는 함수를 한꺼번에 묶을 때에도 객체를 사용한다. 이런 함수를 객체의 메소드라고 한다.

1
2
3
4
5
6
7
8
var animal = {
name: 'bunny',
introduction: function () {
return this.name;
}
};

console.log(animal.introduction());
1
2
3
4
5
6
7
8
9
10
11
12
let gretings = {
sayHello: function () {
consonle.log('HELLO');
}
sayBye: function () {
consonle.log('BYE');
}
}

greetings.sayHello(); // HELLO
greetings.sayHello('bunny'); // HELLO bunny
grettings['sayHello']('bunny'); // HELLO bunny

프로퍼티 접근

  • 객체에서 데이터 접근하는 방법
    • 마침표 표기법(점표기법): 변수 삽입 불가능하다. ex) animal.name
    • 대괄호 표기법: 변수를 삽입할 수 있다. 대괄호 내부에 지정하는 프로퍼티키는 반드시 따옴표로 감싼 문자열 이어야 한다. 단 프로퍼티 키가 숫자로 이루져 있는 경우 따옴표 생략 가능. ex) animal['name'] → 자바스크립트 엔진은 대괄호 안에 이름이 따옴표로 감싸져 있지 않으면 식별자로 취급하기 때문.
  • 프로퍼티 키가 식별자 네이밍 규칙을 따르는 이름이면 마침표 / 대괄호 표기법 둘다 사용 가능하다.
  • 마침표 또는 대괄호 좌측: 객체로 평가할 수 있는 표현식 / 우측&대괄호 내부: 프로퍼티 키를 지정한다.
  • 존재하지 않는 프로퍼티에 접근하면 undeifned 반환.

프로퍼티 값 갱신

이미 존재하고 있는 프로퍼티에 값을 할당하면 갱신된다. (변수에 재할당하는 것과 비슷하다.)

1
2
3
4
5
6
7
8
var animal = {
name: 'snowball',
animal: 'bunny'
};

console.log(animal.name); // snowball
animal.name = 'cute';
console.log(animal.name); // cute

프로퍼티 동적 생성

존재하고 있지 않은 프로퍼티에 값을 할당하면 동적으로 생성되어 추가된 후에 할당까지 된다.

1
2
3
4
5
6
7
8
var animal = {
name: 'snowball',
animal: 'bunny'
};

console.log(animal.like); // undefined
animal.like = 'love';
console.log(animal.name); // love

프로퍼티 삭제

  • delete 연산자가 객체의 연산자를 삭제한다. 이때 delete 연산자의 피연산자는 프로퍼티 값에 접근이 가능한 표현식이어야 한다.
  • 피연산자의 프로퍼티가 존재하지 않으면 무시됨.
1
2
3
4
5
6
7
8
var animal = {
name: 'snowball',
animal: 'bunny'
};

console.log(animal.animal); // bunny
delete animal.animal;
console.log(animal.animal); // undefined

예시

1
2
3
4
5
6
7
8
9
10
11
let myVoca = {
addVoca: function (key, value) {
myVoca[key] = value;
},
deleteVoca: function (key) {
delete myVoca[key];
},
printVoca: function (key) {
console.log(`"${key}"의 뜻은 "${myVoca[key]}"입니다.`);
}
}

프로퍼티 존재 여부 확인

1
2
3
4
console.log(animal.name !== undefined);
console.log('name' in animal);
// 프로퍼티 in 객체이름 → 불리언값 리턴
// 프로퍼티 값에 undefined가 할당될 수 있으므로 in 연산자를 사용하는 것이 좋다.

for…in

프로퍼티 이름에는 숫자형(양수)를 작성해서 사용할 수는 있지만 사용될 때 문자열로 형변환이 된다. 이럴 경우 접근시에 대괄호표기법으로만 접근 가능하다. 객체는 정수형 프로퍼티 네임을 오름차순으로 먼저 정렬하고 나머지 프로퍼티들은 추가한 순서대로 정렬한다.

1
2
3
for (변수 in 객체) {
동작부분
}
1
2
3
4
5
6
7
8
9
10
11
let myObject = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3',
'key4': 'value4',
};

for (let key in myObject) {
console.log(key); // key1
console.log(myObject[key]); // value1
}

ES6에서 추가된 객체 리터럴의 확장 기능

프로퍼티 축약 표현

ES6에서는 프로퍼티 값으로 변수를 사용하는 경우 변수와 프로퍼티 키의 이름이 동일하면 프로퍼티 키 생략 가능하다.

1
2
3
4
let bunny = 'cute', puppy = 'sweet';
const obj = { bunny, puppy };
// bunny:bunny, puppy:puppy와 동일
console.log(obj); // {bunny: 'cute', puppy:'sweet'}

프로퍼티 키 동적 생성

ES5에서 프로퍼티키를 동적으로 생성하려면 객체 외부에서 대괄호 표기법을 사용해야 하지만 ES6에서는 객체 내부에서도 동적으로 프로퍼티 키를 생성할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
const animal = 'bunny';
let i = 0;

// 객체 리터럴 내부에서 프로퍼티 키 동적 생성
var animal_family = {
[`${animal} ${++i}`]: i,
[`${animal} ${++i}`]: i,
[`${animal} ${++i}`]: i
};

console.log(animal_family); // {bunny 1: 1, bunny 2: 2, bunny 3: 3}

메소드 축약 표현

ES6에서는 메소드를 정의할 때 function 키워드를 생략하여 축약 표현을 사용할 수 있다.

1
2
3
4
5
6
7
8
const animal = {
name: 'kitten',
sayHi() { // sayHi: function() {을 축약
console.log('mew mew ' + this.name);
}
};

animal.sayHi(); // mew mew kitten

프로퍼티 정의

  • 프로퍼티 어트리뷰트의 값을 정의하여 프로퍼티의 상태 관리한다.
    • 프로퍼티를 갱신 / 열거 / 재정의 가능하게 할 것인지 명확하게 정의
  • 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 정의한다.
  • 프로퍼티 동적 생성과 프로퍼티 정의는 다르다.
    • 프로퍼티 동적 생성: 존재하지 않는 프로퍼티를 생성하여 추가
    • 프로퍼티 정의: 프로퍼티 어트리뷰트를 정의 (프로퍼티 값, 값의 갱신 여부, 열거 가능 여부, 재정의 가능 여부)
  • Object.getOwnPropertyDescriptor 메소드를 사용해 참조 가능하다. 어트리뷰트 정보를 제공하는 객체인 프로퍼티 디스크립터(PropertyDescriptor) 반환
  • 존재하지 않는 프로퍼티나 상속 받은 프로퍼티에 대한 프로퍼티 디스크립터를 요구하면 undefined 반환
  • 인수는 객체의 참조와 데이터 프로퍼티의 키를 문자열로 전달
  • 프로퍼티가 동적 생성될 때 자바스크립트 엔진은 프로퍼티 어트리뷰트를 기본값으로 정의하지만 이미 정의된 어트리뷰트를 재정의할 수도 있다.
1
2
3
4
5
const obj = {};
obj.prop = 1;
Object.getOwnPropertyDescriptor(obj, 'prop');
// {value: 1, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(obj, 'name'); // undefined
  • 데이터 프로퍼티: 키와 값으로 구성된 일반적인 프로퍼티. value, writable, enumerable, configurable 프로퍼티 어트리뷰트를 갖는다.
  • 접근자 프로퍼티: 자체적으로는 값을 갖고 있지 않지만 다른 데이터 프로퍼티 값을 읽거나 저장할 때 사용자는 접근자 함수로 구성되어 있는 프로퍼티. get, set, enumerable, configurable 프로퍼티 어트리뷰트를 갖는다.

내부 슬롯 / 메소드

자바스크립트 엔진이 코드를 실행하는 알고리즘을 설명하기 위해 ECMAScript 스펙에서 사용하는 의사 프로퍼티(Pseudo property)와 의사 메소드(Pseudo method). 자바 스크립트 엔진의 내부 구현 사양 정의한 것 이라고 보면 됨. 객체의 프로퍼티가 아니기 때문에 직접적으로 접근하거나 호출할 수 없다. 접근하고 싶다면 간접적으로 접근해야 한다.

접근자 프로퍼티와 데이터 프로퍼티 구별 방법

1
2
3
4
5
6
7
// 일반 객체의 __proto__는 접근자 프로퍼티
Object.getOwnPropertyDescriptor(Object.prototype, '__proto__');
// {get: ƒ, set: ƒ, enumerable: false, configurable: true}

// 함수 객체의 prototype은 데이터 프로퍼티
Object.getOwnPropertyDescriptor(function() {}, 'prototype');
// {value: {…}, writable: true, enumerable: false, configurable: false}

접근자 프로퍼티

  • getter / setter 함수라고도 부른다. 둘다 정의해도 되고, 하나만 정의해도 된다.
  • 자체적으로 값(value 프로퍼티)를 가지지 않으며 읽거나 저장할 때만 관여한다.
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
32
33
34
35
const person = {
firstName: 'Minjee',
lastName: 'Kim',

// getter 함수
get fullName() {
return this.firstName + ' ' + this.lastName;
},

// setter 함수
set fullName(name) {
[this.firstName, this.lastName] = name.split(' ');
}
};

// 데이터 프로퍼티를 통한 프로퍼티 값의 참조.
console.log(person.firstName + ' ' + person.lastName); // Minjee Kim

// 접근자 프로퍼티를 통한 프로퍼티 값의 저장
// 접근자 프로퍼티 fullName에 값을 저장하면 setter 함수가 호출.
person.fullName = 'Mia Kim';
console.log(person); // {firstName: "Mia", lastName: "Kim"}

// 접근자 프로퍼티를 통한 프로퍼티 값의 참조
// 접근자 프로퍼티 fullName에 접근하면 getter 함수가 호출.
console.log(person.fullName); // Mia Kim


let descriptor = Object.getOwnPropertyDescriptor(person, 'firstName');
console.log(descriptor);
// {value: "Mia", writable: true, enumerable: true, configurable: true}

descriptor = Object.getOwnPropertyDescriptor(person, 'fullName');
console.log(descriptor);
// {get: ƒ, set: ƒ, enumerable: true, configurable: true}

프로퍼티 어트리뷰트

  • 프로퍼티 어트리뷰트: 모든 데이터 프로퍼티와 접근자 프로퍼티는 자신의 상태와 동작을 정의한 내부 슬롯과 내부 메소드를 가지고 있는데 이것을 프로퍼티 어트리뷰트라고 함.
  • 자바 스크립트 엔진이 프로퍼티를 생성할 때 자동 정의됨.
  • 각각의 프로퍼티의 세부 동작을 제어할 수 있음.

데이터 어트리뷰트

프로퍼티 어트리뷰트 설명
[[Value]] 프로퍼티 키로 프로퍼티 값에 접근하면 내부 메소드 [[Get]]에 의해 반환되는 값.
[[Writable]] 프로퍼티 값의 변경 가능 여부. 불리언 값을 갖는다.
값이 false인 경우, 해당 프로퍼티의 [[Value]]의 값을 변경할 수 없다.
[[Enumerable]] 프로퍼티의 열거 가능 여부. 불리언 값을 갖는다.
for…in 문 등으로 열거 불가.
[[Configurable]] 프로퍼티의 재정의 가능 여부. 불리언 값을 갖는다.
false인 경우, 해당 프로퍼티의 삭제, 프로퍼티 어트리뷰트 값의 변경이 금지된다.
[[Writable]]이 true인 경우, [[Value]]의 변경과 [[Writable]]을 false로 변경하는 것은 가능.

접근자 프로퍼티

프로퍼티 어트리뷰트 설명
[[Get]] 접근자 프로퍼티 키로 프로퍼티 값에 접근하면 getter 함수가 호출되고 그 결과가 프로퍼티 값으로 반환 된다.
[[Set]] 접근자 프로퍼티 키로 프로퍼티 값을 저장하면 setter 함수가 호출되고 그 결과가 프로퍼티 값으로 저장 된다.
[[Enumerable]] 데이터 프로퍼티의 [[Enumerable]]와 동일
[[Configurable]] 데이터 프로퍼티의 [[Configurable]]와 동일

Object.defineProperty 메소드로 정의할 때 프로퍼티 디스크립터 객체에서 누락된 어트리뷰트의 기본값

프로퍼티 디스크립터 객체의 프로퍼티 디스크립터 객체의 프로퍼티 누락시 기본값
value undefined
get undefined
set undefined
writable false
enumerable fasle
configurable false

전역 객체 (Global Object)

코드가 실행되기 이전 단계에 자바스크립트 엔진에 의해 생성되는 특수한 객체. 클라이언트 측 자바스크립트에서 제일 중요.

브라우저 환경: window(self, this, frames)
Node.js: global

전역 객체의 특징

  • 개발자가 의도적으로 생성 불가.
  • 전역 객체의 프로퍼티를 참조할 때, window(global)을 생략할 수 있다.
  • 모든 표준 빌트인 객체를 프로퍼티로 가지고 있다.
  • 실행 환경에 따라 추가적으로 프로퍼티와 메소드를 가질 수 있다.
  • var 키워드로 선언한 전역 변수 / 선언하지 않은 변수에 값을 할당한 암묵적 전역 변수 / 전역 함수는 전역 객체의 프로퍼티가 된다.

REFERENCE
https://poiemaweb.com

  • © 2020-2025 404 Not Found
  • Powered by Hexo Theme Ayer