본문 바로가기
Frontend/JavaScript

[JavaScript] 객체 리터럴

by 모너아링 2022. 11. 8.

객체란?

원시 타입 vs 객체 타입

  • 원시 타입
    • 구성
      • 숫자 타입(number)
      • 문자열 타입(string)
      • 불리언 타입(boolean) → 참, 거짓
      • undefined 타입(undefined) → var 키워드 선언 변수에 암묵적으로 할당되는 값
      • null 타입(null) → 값이 없다는 것을 명시할 때 사용
      • 심벌 타입(symbol) → ES6에서 추가
    • 변경 불가능한 값
  • 객체 타입
    • 구성
      • 객체(object) → 프로퍼티, 메서드로 구성
      • 배열(array)
      • 함수(function)
    • 변경 가능한 값

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

객체 리터럴

var person = {
	name: 'Lee', //프로퍼티
	sayHello: function(){ //메서드
		console.log(`Hello! My name is ${this.name});
	}
};
console.log(person); // {name: "Lee", sayHello: f}
  • 객체 리터럴에 의한 객체 생성은 중괄호 내에 0개 이상의 프로퍼티를 정의하는 것으로 진행된다.
  • 해당 person 객체의 구성
    • name: ‘Lee’ → 프로퍼티
    • sayHello: fuction()→ 메서드
  • 프로퍼티를 0개 정의한다면?
var empty = {};
console.log(empty); // {}

-> 빈 객체가 생성됨

 

  • 객체에 메소드만 정의한다면?
var person = {
	hello: function () {
	 console.log('hello!');
	}
};
console.log(person); // { hello: [Function: hello] }

프로퍼티

  • 객체의 상태를 나타내는 값
  • 으로 구성되어 있다.
  • 프로퍼티 키가 식별자 네이밍 규칙을 따르지 않으면 반드시 따옴표를 사용
var foo = {
	name: 'Kim' //키와 값으로 구성
}

 

식별자 네이밍 규칙

  • 식별자는 특수문자를 제외한 문자, 숫자, _ , $ 만을 포함
  • 식별자는 특수문자를 제외한 문자, 숫자, _ , $ 로 시작해야 한다. 숫자로 시작하는 것은 허용하지 않는다.
  • 예약어는 식별자로 사용할 수 없다.
//식별자 네이밍 규칙을 위반하는 프로퍼티 키
'last-name': 'Lee'
'last name': 'Lee'
'2lastname': 'Lee'
if: 'Lee' //예약어는 규칙 위반이지만 허용은 한다.

프로퍼티 선언 시 주의할 점

var foo = {
	name: 'Kim' //정상적 선언

	0: 1 //숫자 리터럴 사용시 문자열로 변환
	'': '' //빈 문자열도 키로 사용 가능
	name: 'Lee' //중복선언 시 값 덮어씀
}
console.log(foo); // { '0': 1, name: 'Lee', '': '' }

메서드

  • 프로퍼티 값이 함수인 것
var circle = {
	radius: 5,
	getDiameter: function(){
		return 2 * this.radius;
	}
};
console.log(circle.getDiameter()); // 10

프로퍼티 접근

마침표 표기법

var person = {
	name: 'Lee'
};
console.log(person.name); // Lee
console.log(person.age); // undefined
  • 객체에 존재하지 않는 프로퍼티 접근 시 undefined 반환

대괄호 표기법

var person = {
	name: 'Lee'
};
console.log(person['name']); // Lee
console.log(person[name]); // Error
  • 반드시 따옴표로 감싼 문자열이어야 함
  • 따옴표로 감싸지 않으면 에러 발생

이처럼 프로퍼티 키가 식별자 네이밍 규칙을 준수하는 이름이면 마침표 표기법, 대괄호 표기법 둘 다 사용 가능하다.

그렇다면 이를 위반하는 이름이면 어떨까?

var person = {
	'last-name': 'Lee',
	1: 10
}

 

  • 마침표 표기법

마침표 표기법을 이용하면 원하는 값에 접근할 수 없다.

*NaN이 발생하는 이유?

더보기

💡 ‘-’ 를 연산자로 인식하기 때문이다. 이 때문에 person.last와 name을 나누어 생각하는데 person.last는 undefined를 반환하고, name는 전역변수로 암묵적으로 존재하기 때문에 빈 문자열을 반환한다. 결국 **undefine - ‘’**형태가 되므로 이는 NaN라는 결과가 나오는 것이다.

  • 대괄호 표기법
person[last-name]; //Error
person['last-name']; //Lee

person[1]; //10
person['1']; //10

대괄호 내에서는 따옴표를 반드시 써주어야 한다. 하지만 숫자 리터럴의 경우, 문자열로 자동 변환되기 때문에 person[1]과 person[’1’]은 같은 표현이 된다. 결국 키 값이 숫자 리터럴인 경우 따옴표를 쓰지 않아도 된다.

더보기

💡 결론적으로, 프로퍼티 키가 식별자 네이밍 규칙을 위반하는 이름이면 마침표 표기법은 사용할 수 없고, 대괄호 표기법은 조건부 허용된다.


프로퍼티 CRUD

프로퍼티 갱신

ver person = {
	name: 'Lee'
};
person.name = 'Kim';
person['name'] = 'Kim';

console.log(person); //{name: 'Kim'}

이미 존재하는 프로퍼티에 값을 할당한다.

 

프로퍼티 생성

var person = {
	name: 'Lee'
};
person.age = 20;
console.log(person); //{name: 'Lee', age: 20}

//프로퍼티 키 동적 생성
var key = 'hello';
person[key] = 'world';
console.log(person); //{name: 'Lee', age: 20, hello: 'world'}

존재하지 않는 프로퍼티에 값을 할당한다.

 

프로퍼티 삭제

var person = {
	name: 'Lee'
};
delete person.name; //삭제
delete person.address; //에러 발생하지 않음

console.log(person); // {}

delete 연산자를 이용하여 삭제한다. 이때, 존재하지 않는 프로퍼티를 삭제하면 무시된다.


이 외의 기능

프로퍼티 축약

//프로퍼티 값인 변수 이름과 프로퍼티 키가 동일한 이름일 경우
var x = 1, y = 2;
var obj = {
	x: x, 
	y: y
};

var obj = { x, y };

프로퍼티 값으로 변수를 사용하는 경우 변수 이름과 프로퍼티 키가 동일한 이름일 때 프로퍼티 키를 생략할 수 있다.

메서드 축약

var obj = {
	name: 'Lee',
	sayHi: function(){
		console.log('Hi! ' + this.name);
	}
	sayHi() {
		console.log('Hi! ' + this.name);
	}
	//두 메서드는 동일한 표현
}

function 키워드를 생략한 축약 표현 사용 가능하다.

 

계산된 프로퍼티

//프로퍼티 키가 대괄호로 둘러쌓인 프로퍼티
const fs = require('fs');
console.log('과일을 입력하세요: ');
var fruit = fs.readFileSync(0, 'utf8').toString().split(' ');

var bag = {
    [fruit]: 5,
};
console.log(bag.apple);
//fruit가 'apple'일 때 5출력
//아닐 때 undefined 출력

var i = 0;
var prefix = 'prop';
var obj = {};

obj[prefix + '-' + ++i] = i;
obj[`${prefix}-${++i}`]: i;
console.log(obj); //{prop-1: 1}

문자열 또는 문자열로 타입 변환할 수 있는 값으로 평가되는 표현식을 사용해 프로퍼티 키를 동적으로 생성할 수 있다.

반드시 대괄호 표기법을 사용해야 한다.

 

존재 여부 확인

let user = { name: "John", age: 30 };
console.log("age" in user); //true
console.log("asdf" in user); //false

in을 이용해 프로퍼티가 존재하는지 확인할 수 있다.

‘따옴표로 감싸진 프로퍼티 키 in 객체 이름’ 형태로 대입해야 한다.

프로퍼티가 존재하면 true, 존재하지 않으면 false 반환

 

키 순회

let user = { name: "John", age: 30 };
for(let key in user){
	console.log(key); //name, age -> 프로퍼티 키
	console.log(user[key]); //John, 30 -> 프로퍼티 값
}

for…in 을 이용하여 프로퍼티 키를 모두 순회한다.

이때 프로퍼티 값에 접근하려면 user[key] 형태를 이용한다.

 


간단한 응용

var person = {
    firstName: ['Lee', 'Kim'], //프로퍼티
    "last name": ['name', 'nname'], //프로퍼티
    age: 20, //프로퍼티
    getAge: function () { //메서드
        return this.age;
    },
    increase: function () { //메서드
        this.age++;
    },
    sayHello: function (i) { //메서드
				
        person.firstName.forEach((curElement, curIndex) => {
            if (i === curIndex) {
								//person['firstName'][i] 대신 this.firstName[i] 도 사용 가능
								//하지만 person['last name'][i] 대신 this.'last name[i]' || this.'last name'[i] 사용 불가
                console.log(`Hello! My name is ${person['firstName'][i]} ${person['last name'][i]}`)
            }
        });
    }
};

firstName

  • 프로퍼티
  • 값을 배열로 선언
firstName: ['Lee', 'Kim']

//마침표 표기법
console.log(person.firstName); //[ 'Lee', 'Kim' ]
console.log(person.firstName[0]); //Lee
//프로퍼티 값이 배열일 때 접근 방법
//대괄호 표기법
console.log(person['firstName'][0]); //Lee

console.log(person['firstName[0]']); //undefined
//하위 namespace 생성
firstName: {
	first: 'Lee',
	last: 'Kim'
}

//호출 시
console.log(person.name.first);
console.log(person['name']['first'])

console.log(person.name.last)
console.log(person['name']['last'])

 

last name

  • 프로퍼티
  • 값을 배열로 선언
  • 식별자 네이밍 규칙 위반 ⇒ 따옴표 생략 불가
"last name": ['name', 'nname']

//마침표 표기법
console.log(person.last name); //오류
console.log(person.'last name'); //오류

//대괄호 표기법
console.log(person['last name']); //[ 'name', 'nname' ]
console.log(person['last name'][0]); //name
  • 대괄호 표기법만 사용 가능

age

  • 프로퍼티
  • 값을 숫자로 선언
age: 20

//마침표 표기법
console.log(person.age); //20

//대괄호 표기법
console.log(person['age']); //20

 

getAge()

  • 메소드
  • age 값을 반환
getAge: function () {
     return this.age;
}

console.log(person.getAge()); //20

 

increase()

  • 메소드
  • age 값을 +1 한 후 반환
increase: function () {
    this.age++;
}

person.increase();
console.log(person.age); //21

 

sayHello()

  • 메소드
  • 인덱스 번호를 인수로 하면 그 번호의 firstName과 last name 출력하는 함수
sayHello: function (i) {
    person.firstName.forEach((curElement, curIndex) => {
        if (i === curIndex) {
						//person['firstName'][i] 대신 this.firstName[i] 도 사용 가능
						//하지만 person['last name'][i] 대신 this.'last name[i]' || this.'last name'[i] 사용 불가
            console.log(`Hello! My name is ${person['firstName'][i]} ${person['last name'][i]}`)
        }
    });
}

for (let i = 0; i < person['firstName'].length; i++) {
    person.sayHello(i);
}
//Hello! My name is Lee name
//Hello! My name is Kim nname

'Frontend > JavaScript' 카테고리의 다른 글

[JavaScript] 제너레이터와 async/await  (0) 2023.02.16
[JavaScript] DOM 이벤트  (0) 2023.02.16
[JavaScript] Set  (2) 2023.02.16
[JavaScript] 이터러블  (1) 2023.02.16
[JavaScript] 함수와 일급 객체  (0) 2022.11.08