[JS CS] 객체
작성:    
업데이트:
카테고리: JS CS
태그: FE Language, JS, JS CS
객체
객체란?
- 속성(property)의 집합
- python의 dictionary
key-value 정의
- key는 문자열 타입만 가능
- key 이름에 띄어쓰기 같은 구분자가 있으면 따옴표로 묶어서 정의
- value는 모든 타입(함수포함) 가능
접근
- 객체 요소 접근은 점 또는 대괄호로 가능
- key 이름에 띄어쓰기 같은 구분자가 있으면 대괄호 접근만 가능
객체와 메서드
- 메서드는 어떤 객체의 속성이 참조하는 함수
- 객체.메서드명() 으로 호출
- 메서드 내부에서는 this 키워드가 객체를 의미
const me = {
firstName: 'John',
lastName: 'Doe',
fullName: this.firstName + this.lastName, // NaN 반환
getFullName: function () {
return this.firstName + this.lastName // 정상적으로 firstName+lastName 반환
}
}
- fullName 속성은 메서드가 아닌데 this를 사용 → 정상출력 되지 않음(NaN)
- getFullName 메서드는 메서드이므로 this 사용 가능 → 정상적으로 반환
객체 ES6 문법 1 : 속성명 축약(shorthand)
- 객체를 정의할 때 key와 할당하는 변수의 이름이 같으면 축약 가능
var books = ['Learning JS', 'Learning Python']
var magazines = ['Vogue', 'Science']
// ES5
var bookShop = {
books: books,
magazines: magazines,
}
// ES6
const bookShop = {
books,
magazines,
}
console.log(bookShop)
객체 ES6 문법 2 : 메서드명 축약(shorthand)
- 메서드 선언 시 function 키워드 생략 가능
// ES5
var obj = {
greeting: function () {
console.log('Hi!')
}
}
// ES6
const obj = {
greeting() {
console.log('Hi!')
}
}
obj.greeting() // Hi!
객체 ES6 문법 3 : 계산된 속성(computed property name)
- 객체를 정의할 때 key의 이름을 표현식을 이용하여 동적으로 생성 가능
const key = 'fruits'
const value = ['바나나', '사과', '파인애플', '참외']
const food = {
[key]: value,
}
console.log(food) // {fruits: Array(4)}
console.log(food.fruits) // ["바나나", "사과", "파인애플", "참외"]
객체 ES6 문법 4 : 구조 분해 할당(destructing assignment)
- 배열 또는 객체를 분해하여 속성을 변수에 쉽게 할당할 수 있는 문법
const userInformation = {
name: '홍길동',
userId: 'gildong1234',
phoneNumber: '010-1234-1234',
email: 'gildong@gmail.com',
}
const name = userInformation.name
const userId = userInformation.userId
const phoneNumber = userInformation.phoneNumber
const email = userInformation.email
const userInformation = {
name: '홍길동',
userId: 'gildong1234',
phoneNumber: '010-1234-1234',
email: 'gildong@gmail.com',
}
const { name } = userInformation
const { userId } = userInformation
const { phoneNumber } = userInformation
const { email } = userInformation
// 여러 개도 가능
const {name, userId} = userInformation
객체 ES6 문법 5 : Spread operator
- spread operator(…)를 사용하면 객체 내부에서 객체 전개 가능
- ES5까지는 Object.assign() 메서드 사용
- 얕은 복사에 활용 가능
const obj = {b: 2, c: 3, d: 4}
const newObj = {a: 1, ...obj, e: 5}
console.log(newObj) // {a: 1, b: 2, c: 3, d: 4, e: 5}
JSON
- JavaScript Object Notation
- key-value 쌍의 형태로 데이터를 표기하는 언어 독립적 표준 포맷
- 자바스크립트의 객체와 유사하게 생겼으나 실제로는 문자열 타입
-
JS의 객체로써 조작하기 위해서는 구문 분석(parsing)이 필수
- 자바스크립트에서는 JSON을 조작하기 위한 두 가지 내장 메서드 제공
- JSON.parse() : JSON → JS 객체
- JSON.stringify() : JS 객체 → JSON
예시
// object → JSON
const jsonData = JSON.stringify({
coffee: 'Americano',
iceCream: 'Cookie and cream',
})
console.log(jsonData) // "{"coffee":"Americano",...}
console.log(typeof jsonData) // string
// JSON → object
const jsonData = JSON.stringify({
coffee: 'Americano',
iceCream: 'Cookie and cream',
})
const parsedAta = JSON.parse(jsonData)
console.log(parsedData) // "{"coffee":"Americano",...}
console.log(typeof parsedData) // object
this
- JS의 this는 실행 문맥(execution context)에 따라 다른 대상을 가리킨다.
- class 내부의 생성자(constructor) 함수에서는 생성되는 객체를 가리킴(python의 self)
- 메서드에서는 해당 메서드가 소속된 객체를 가리킴
- 위의 두 경우를 제외하면 모두 최상위 객체(window)를 가리킴
function getFullName () {
return this.firstName + this.lastName
}
const me = {
firstName: 'John',
lastName: 'Doe',
getFullName: getFullName,
}
const you = {
firstName: 'Jack',
lastName: 'Lee',
getFullName: getFullName,
}
me.getFullName() // JohnDoe (this === me)
you.getFullName() // JackLee (this === you)
getFullName() // NaN (this === window)
function 키워드와 화살표 함수 ⭐
- this.radiuses는 메서드 소속이므로 정상적으로 접근 가능
- forEach의 콜백함수의 경우 메서드가 아님
-
때문에 콜백함수 내부의 this는 window가 되어 this.PI는 정상적으로 접근 불가능
- 이 콜백함수 내부에서 this.PI에 접근하기 위해서 함수객체.bind(this) 메서드 사용
- “너가 말하는 this가 obj 객체지? 내가 고정해줄게” 라는 기능
- 이 번거로운 bind 과정을 없앤 것이 화살표 함수
const obj = {
PI: 3.14,
radiuses: [1, 2, 3, 4, 5],
printArea: function () {
this.radiuses.forEach(function (r) {
console.log(this.PI * r * r)
}).bind(this)
},
}
const obj = {
PI: 3.14,
radiuses: [1, 2, 3, 4, 5],
printArea: function () {
this.radiuses.forEach((r) => {
console.log(this.PI * r * r)
})
},
}
Summary
- 함수 내부에 this 키워드가 존재할 경우
-
화살표 함수와 function 키워드로 선언한 함수가 다르게 동작
- 함수 내부에 this 키워드가 존재하지 않을 경우
- 완전히 동일하게 동작
lodash
A modern JavaScript utility library
- 모듈성, 성능 및 추가 기능을 제공하는 JavaScript 유틸리티 라이브러리
- array, object 등 자료구조를 다룰 때 사용하는 유용하고 간편한 유틸리티 함수들 제공
- reverse, sortBy, range, random, cloneDeep
사용 예시
<body>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<script>
// 위의 CDN import를 통해 _(underscore) 식별자 사용 가능
_.sample([1, 2, 3, 4]) // 3 (random 1 element)
_.sampleSize([1, 2, 3, 4], 2) // [2, 3] (random 2 element)
_.reverse([1, 2, 3, 4]) // [4, 3, 2, 1]
_.range(5) // [0, 1, 2, 3, 4]
_.range(1, 5) // [1, 2, 3, 4]
_.range(1, 5, 2) // [1, 3]
</script>
</body>
얕은 복사와 깊은 복사
<body>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<script>
// 위의 CDN import를 통해 _(underscore) 식별자 사용 가능
const original = {a: {b: 1}}
const ref = original
const copy = _.copyDeep(original)
console.log(original.a.b, ref.a.b, copy.a.b) // 1, 1, 1
ref.a.b = 10
console.log(original.a.b, ref.a.b, copy.a.b) // 10, 10, 1
copy.a.b = 100
console.log(original.a.b, ref.a.b, copy.a.b) // 10, 10, 100
</script>
</body>
lodash를 사용하지 않을 경우, 깊은 복사는 직접 함수를 만들어서 구현해야 함
댓글남기기