const firstName = "poco";
const lastName = "jang";
const person = {
firstName: firstName,
lastName: lastName,
getFullName: function () {
return this.firstName + this.lastName;
},
};
아래처럼 속성을 축약해서 나타낼 수 있다.
const firstName = "poco";
const lastName = "jang";
const person = {
firstName, // shorthand properties
lastName, // shorthand properties
getFullName() { // concise method
return this.firstName + this.lastName;
},
};
// {
// firstName: 'poco',
// lastName: 'jang',
// getFullName: [Function: getFullName]
// }
계산된 값을 속성명으로 사용할 수 있다. (대괄호 안에 넣어서 사용)
const handleChange = (e) => {
setState({ [e.target.name]: e.target.value });
};
return (
<>
<input value={state.id} onChange={handleChange} name="name" />
<input value={state.password} onChange={handleChange} name="password" />
</>
);
key, value가 리스트로 쭉 나열되어 있는 것
// switch
function getUserType(type) {
switch (type) {
case "ADMIN":
return "관리자";
case "INSTRUCTOR":
return "강사";
case "STUDENT":
return "수강생";
default:
return "해당 없음";
}
}
// lookup table => 굿!
function getUserType(type) {
// 상수 파일을 따로 관리하여 import해서 간단하게 사용할 수도 있음
const USER_TYPE = {
ADMIN: "관리자",
INSTRUCTOR: "강사",
STUDENT: "수강생",
UNDEFINED: "해당 없음",
};
return USER_TYPE[type] ?? USER_TYPE.UNDEFINED;
}
// 바로 리턴하기
function getUserType(type) {
return (
{
ADMIN: "관리자",
INSTRUCTOR: "강사",
STUDENT: "수강생",
}[type] ?? "해당 없음"
);
}
아래처럼 작성하면 매개변수 순서가 강제된다.
function Person(name, age, location) {
this.name = name;
this.age = age;
this.location = location;
}
const poco = new Person("poco", 30, "korea");
// 값을 안 넘기려면 아래처럼 undefined로 써야 함
// const poco = new Person("poco", undefined, "korea");
object destructuring을 사용하면 순서를 지키지 않아도 되서 훨씬 편리하다.
function Person({ name, age, location }) {
this.name = name;
this.age = age ?? 30;
this.location = location ?? 'korea';
}
// 순서 달라도 상관없음
const poco = new Person({
age: 30,
name: "poco",
location: "korea",
});
// 값 안 넘겨도 상관없음
const poco = new Person({
location: "korea",
});
name만 필수로 받고 나머지는 선택으로 받으려면 아래처럼 만들 수 있다.
function Person(name, { age, location }) {
this.name = name;
this.age = age;
this.location = location;
}
const poco = new Person("poco", {
age: 30,
location: "korea",
});
배열에서 특정 변수를 꺼낼 때도 활용할 수 있다.
const orders = ["First", "Second", "Third"];
// 배열로 하면 안 쓰는 값을 비워두어야 하지만 객체로 하면 원하는 값만 골라 쓰면 된다.
// const [first, , third] = orders;
const { 0: first, 2: second } = orders;
React에서도 props를 다룰 때 많이 사용되고 있다!
객체를 동결시킬 수 있다.(원본 유지, 객체를 변경할 수 없음)
Object.isFrozen()
: 객체 동결 여부 확인const STATUS = Object.freeze({
PENDING: "PENDING",
SUCCESS: "SUCCESS",
FAIL: "FAIL",
OPTIONS: {
GREEN: "GREEN",
RED: "RED",
},
});
Object.isFrozen(STATUS); // true
주의 : 깊은 영역까지는 freeze가 되지 않는다.
const STATUS = Object.freeze({
PENDING: "PENDING",
SUCCESS: "SUCCESS",
FAIL: "FAIL",
OPTIONS: {
GREEN: "GREEN",
RED: "RED",
},
});
STATUS.OPTIONS.GREEN = "G"; // 이렇게 깊은 영역은 수정할 수 있다.
Object.isFrozen(STATUS.OPTIONS.GREEn); // false
해결 방법
- 대중적인 유틸 라이브러리(lodash)
- 직접 유틸 함수 생성(deep freeze하는 함수 생성)
- 객체 순회, 값이 객체인지 확인, 재귀적으로 object.freeze()
- stackoverflow
- TypeScript => readonly 사용
특정 프로퍼티를 가지고 있는지 확인
주의 : hasOwnProperty가 이미 선언되어 있으면 해당 메서드가 덮어씌워질 수 있다.
이럴 때는 Object.prototype.hasOwnProperty.call()를 사용하면 안전하게 쓸 수 있다.
const foo = {
hasOwnProperty: function () {
return "hasOwnProperty";
},
bar: "string",
};
console.log(foo.hasOwnProperty("bar")); // x
console.log(Object.prototype.hasOwnProperty.call(foo, "bar")); // o
model 객체를 여러 함수에서 직접 변경하고 있다.
const model = {
isLogin: false,
isValidToken: false,
};
function login() {
model.isLogin = true;
model.isValidToken = true;
}
function logout() {
model.isLogin = false;
model.isValidToken = false;
}
객체를 직접 다루는 영역을 따로 분리하여 더 안전하게 쓸 수 있다.
// 직접 접근 지양
const model = {
isLogin: false,
isValidToken: false,
};
// model에 대신 접근
function setLogin(bool) {
model.isLogin = bool;
}
// model에 대신 접근
function setValidToken(bool) {
model.isValidToken = bool;
}
// model에 직접 접근 x
function login() {
setLogin(true);
setValidToken(true);
}
// model에 직접 접근 x
function logout() {
setLogin(false);
setValidToken(false);
}
예측 가능한 코드를 작성해서 동작이 예측 가능한 앱 만들기!
?.
: 선택적으로 프로퍼티를 선택할 수 있다.
const obj = {
name: "value",
};
obj?.name;
서버에서 데이터를 받아올 때 값이 있는지 확인하려면
const response = {
data: {
userList: [
{
name: "Lee",
info: {
tel: "010",
email: "lee@gmail.com",
},
},
],
},
};
// 방법 1 : if문으로 하나하나 점검 => 너무 번거로움
function getUserEmailByIndex(userIndex) {
if (response.data) {
if (response.data.userList) {
if (response.data.userList[userIndex]) {
return response.data.userList[userIndex].info.email;
}
}
}
return "알 수 없는 에러가 발생했습니다.";
}
// 방법 2 : && 으로 단축 => 여전히 김
function getUserEmailByIndex(userIndex) {
if (
response.data &&
response.data.userList &&
response.data.userList[userIndex]
) {
return response.data.userList[userIndex].info.email;
}
return "알 수 없는 에러가 발생했습니다.";
}
// 방법 3 : optional chaining 활용 => 간편함!
function getUserEmailByIndex(userIndex) {
if (response.data?.userList?.[userIndex]?.info?.email) {
return response.data.userList[userIndex].info.email;
}
return "알 수 없는 에러가 발생했습니다.";
}