Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 코테
- 문자열
- JavaScript
- 카카오
- Linux
- 코딩테스트
- 리눅스
- 월간코드챌린지
- map
- Memoir
- 연습문제
- 스프링 컨테이너
- 프로그래머스
- Kotlin
- GoingBus
- 반복문
- 자바
- 고잉버스
- 자바스크립트 코딩의 기술
- 개발자 회고록
- 리눅스마스터 1급 정리
- 리눅스마스터 3과목
- Java
- 백준 javascript
- toCharArray
- 리눅스마스터1급
- 백준 java
- java 백준 1차원 배열
- 명령어
- 스프링 빈
Archives
- Today
- Total
hoon's bLog
Javascript 자바스크립트 코딩의 기술 6장 매개변수와 return 문을 정리하라 본문
반응형
6장 매개변수와 return 문을 정리하라
tip28. 매개변수 기본값을 생성하라
- pound를 kilogram으로 변환하는 코드를 보면서 알아보자.(pound를 2.2로 나눠야 kilogram으로 변환)
function convertWeight(weight) {
return weight / 2.2;
}
- 온스(ounce)도 변환해야 한다는 요구사항이 생겼다.(온스는 1pound === 16ounce 이므로 ounce / 16으로 계산)
function convertWeight(weight, ounces) {
const oz = ounces ? ounces / 16 : 0;
const total = weight + oz;
return total / 2.2;
}
convertWeight(44, 11);
// 20.3125
convertWeight(44, 8);
// 20.227272727272727
convertWeight(6, 9.6);
// 2.9999999999999996
- convertWeight(6, 9.6); 를 실행하면 3이 나와야 되는데 2.999999...가 나온다.
- 9.6 / 16 = 0.6이므로 6.6 / 2.2는 3이 되어야 하는데, 3이 나오지 않는 이유는 부동 소수점 연산 때문!!!!!!
(아래 참고 링크를 통해 부동소수점 참고!) - 따라서 반올림을 해야 하므로, 소수점은 2자리까지 표시할 것이다.
function roundToDecimalPlace(number, decimalPlaces) {
const round = 10 ** decimalPlaces; // decimalPlaces만큼 제곱
console.log(round);
console.log(number * round);
console.log(Math.round(number * round));
return Math.round(number * round) / round;
}
roundToDecimalPlace(30.8412, 2);
// result
// 100
// 3084.12
// 3084
// 30.84
roundToDecimalPlace(30.8452, 2);
// result
// 100
// 3084.52
// 3085
// 30.85
function convertWeight(weight, ounces, roundTo) {
const oz = ounces / 16 || 0;
const total = weight + oz;
const conversion = total / 2.2;
const round = roundTo === undefined ? 2 : roundTo;
return roundToDecimalPlace(conversion, round);
}
- 위와 같이 코드를 작성하면 잘 동작하지만, 정의되지 않은 변수(매개변수)로 인해 발생하는 삼항 연산자나 단락 평가 때문에 코드가 길어졌다.
- 이 부분은 매개변수에 기본값을 할당하면 더 효율적이고 가독성이 좋은 코드가 된다.
function convertWeight(weight, ounces = 0, roundTo = 2) {
const total = weight + ounces / 16;
const conversion = total / 2.2;
return roundToDecimalPlace(conversion, roundTo);
}
convertWeight(100, 5, 3);
// 1000
// 45596.590909090904
// 45597
// 45.597
convertWeight(4, 0, 2);
// 100
// 181.8181818181818
// 182
// 1.82
convertWeight(4, null, 2);
// 100
// 181.8181818181818
// 182
// 1.82
- 매개변수에 타입도 확인 가능하다.
- 매개변수에 값을 넣으면 해당하는 값에 대한 연산을, 특정 매개변수에 값이 null이라면 coverWeight에 할당된 기본값인 0이 들어가서 연산 됨
- 하지만, 매개변수 기본값 사용시 단점은 사용하지 않는 매개 변수도 순서대로 입력해야 한다.
- 이 문제를 해결하기 위해 매개변수로 객체를 전달해야 하는데 이 방법은 다음 팁에서 알아보겠다!!!!
tip29. 해체 할당으로 객체 속성에 접근하라
다음 코드들을 통해 객체와 배열에서 정보를 빠르게 가져오는 방법을 알아보자.
const landscape = {
title: 'Landscape',
photographer: 'Nathan',
equipment: 'Canon',
format: 'digital',
src: '/landscape-nm.jpg',
location: [32.7122222, -103.1405556],
};
- 위 객체에서 속성들을 특순서에 따라 보여지고 나머지 속성들을 나열하려면?(아래 HTML 코드처럼 반환)
<img alt="Landscape 사진 Nathan 촬영" src="/landscape-nm.jpg" />
<div>Landscape</div>
<div>Nathan</div>
<div>위도: 32.7122222</div>
<div>경도: -103.1405556</div>
<div>
equipment: Canon <br />
format: digital
</div>
- 아래 코드처럼 photo라는 객체를 매개변수로 하고 photo.key 이런식으로 속성에 하나하나 점표기법으로 접근해야 한다.
- 많은 양의 정보를 다룰 때는 순서를 정할 속성들을 변수로 선언하고, 이 속성들을 객체에서 제거한다.
- 그리고 나중에 객체를 나열하게되면 모든 정보를 나열할 수 있다.
function displayPhoto(photo) {
const title = photo.title;
const photographer = photo.photographer || 'Anonymous';
const location = photo.location;
const url = photo.src;
const copy = { ...photo };
delete copy.title;
delete copy.photographer;
delete copy.location;
delete copy.src;
const additional = Object.keys(copy).map((key) => `${key}: ${copy[key]}`);
return `
<img alt="${title} 사진 ${photographer} 촬영" src="${url}" />
<div>${title}</div>
<div>${photographer}</div>
<div>위도: ${location[0]} </div>
<div>경도: ${location[1]} </div>
<div>${additional.join(' <br/> ')}</div>
`;
}
물론 이런 방법도 있지만, 객체를 가져오는 수고를 덜기 위해 해체 할당을 해보면 아래 코드와 같다.
const landscape = {
photographer: 'LEE',
};
const { photographer } = landscape;
console.log(photographer);
// LEE
이런 식으로 원래 코드를 수정해보면 아래와 같다.
function displayPhoto(photo) {
const {
title,
photographer = 'Anonymous',
location: [latitude, longitude],
src: url,
...other
} = photo;
const additional = Object.keys(other).map((key) => `${key}: ${other[key]}`);
return `
<img alt="${title} 사진 ${photographer} 촬영" src="${url}" />
<div>${title}</div>
<div>${photographer}</div>
<div>위도: ${latitude} </div>
<div>경도: ${longitude} </div>
<div>${additional.join(' <br/> ')}</div>
`;
}
- 해체 할당의 가장 큰 장점은 해체 할당을 함수의 매개변수에 적용할 수 있다는 것이다.
- 대신 매개변수에 적용하게되면 const 대신 let으로 선언하므로 재할당이 가능해진다.
- 매개변수에 해체 할당을 적용하면 아래 코드와 같다.
function displayPhoto({
title,
photographer = 'Anonymous',
location: [latitude, longitude],
src: url,
...other
}) {
const additional = Object.keys(other).map((key) => `${key}: ${other[key]}`);
return `
<img alt="${title} 사진 ${photographer} 촬영" src="${url}" />
<div>${title}</div>
<div>${photographer}</div>
<div>위도: ${latitude} </div>
<div>경도: ${longitude} </div>
<div>${additional.join(' <br/> ')}</div>
`;
}
사실 처음 사용해보면 다소 복잡하고, 직관성이 떨어져 보일 수 있다.
하지만 사용법에 적응이 된다면 오히려 위 코드가 가독성과 유지 보수 측면에 더 어울릴지도 모르겠다.
(필자는 배운다는 생각으로 보고 있지만, 실무에서는 하나하나 선언하는 타입..)
tip30. 키-값 할당을 단순화하라
const landscape = {
title: 'Landscape',
photographer: 'Nathan',
location: [32.7122222, -103.1405556],
};
function determineCityAndState([latitude, longitude]) {
// 좌표 탐색을 처리
const region = {
city: 'Hobbs',
county: 'Lea',
state: {
name: 'New Mexico',
abbreviation: 'NM',
},
};
// location정보 기반으로 region을 리턴받았다고 가정.
return region;
}
function getCityAndState({ location }) {
const { city, state } = determineCityAndState(location);
return {
city, // 위 코드를 통해 받아온 값.
state: state.abbreviation, // 전통적인 객체 키-값 선언을 하고 있음에 주의
};
// {
// city: 'Hobbs',
// state: 'NM'
// }
}
function setRegion({ location, ...details }) { // landscape 객체를 해체할당
const { city, state } = determineCityAndState(location);
return {
city,
state: state.abbreviation,
...details, // 리턴 값에 주목
};
}
setRegion(landscape);
// {
// title: 'Landscape',
// photographer: 'Nathan',
// city: 'Hobbs',
// state: 'NM',
// };
- 변수와 이름이 같은 키를 갖는 키-값 쌍을 객체에 추가하려면 변수 이름을 적으면 된다
- 객체 펼침 연산자와 키-값 할당을 함께 사용하여 객체에서 한 가지 정보만 제거 가능!!
(location을 빼서, 나머지 매개변수를 사용하면 location 정보만 제거)
tip31. 나머지 매개변수로 여러 개의 인수를 변수로 전달하라
- 나머지 매개변수(rest parameter)를 이용해 개수를 알 수 없는 다수의 매개변수를 전달하는 방법을 살펴보자.
- 펼침연산자(spread operator)와 매개변수는 반드시 구분해야 한다.
- 펼침연산자(spread operator) : 배열, 문자열, 객체 등 반복 가능한 객체 (Iterable Object)를 개별 요소로 분리
- 나머지 매개변수(rest parameter) : 함수가 정해지지 않은 수의 매개변수를 배열로 받을 수 있음!
- 사진 앱으로 예를 들어보자. 사진 태그의 길이를 일정 수준으로 제한하려고 한다.
- 아래 코드는 제한 크기, 태그 배열을 매개변수로 받는 함수이다.
function validateCharacterCount(max, items) {
return items.every((item) => item.length < max);
}
validateCharacterCount(10, ['Hobbs', 'Eagles']);
// true
- items.length가 max보다 모두 작으면 true를 반환하는 every메서드를 사용한 함수이다.
- 이 함수의 단점은 items의 컬렉션 형식을 강제한다.(배열) 예를 들어 'Hobbs'대신 ['Hobbs']로 전달해야 한다.
- 이 문제는 arguments 객체를 이용해 해결할수 있는데 아래 코드와 같다.
function getArguments() {
return arguments;
}
getArguments('Bloomsday', 'June 16');
// { '0': 'Bloomsday', '1': 'June 16' }
function validateCharacterCount(max) {
console.log(arguments);
// Arguments(2) [10, "wvoquie", callee: ƒ, Symbol(Symbol.iterator): ƒ]
const items = Array.prototype.slice.call(arguments, 1);
console.log(items);
// ["wvoquie"]
return items.every((item) => item.length < max);
}
validateCharacterCount(10, 'wvoquie');
// true
const tags = ['Hobbs', 'Eagles'];
validateCharacterCount(10, ...tags);
// true
- arguments는 유사배열이므로 배열로 변환한 다음 배열 메서드를 호출!
- 전달할 변수가 이미 배열이라면 펼침 연산자를 사용(...tags)
- 물론 이 코드도 작동을 잘 되지만, arguments 객체를 다루기 떄문에 문법이 난해하고, 가독성도 좋지 않다.
- 나머지 매개변수(rest parameter)를 사용해 개선해보자.
function getArguments(...args) {
return args;
}
getArguments('Bloomsday', 'June 16');
// ['Bloomsday', 'June 16']
function validateCharacterCount(max, ...items) {
return items.every((item) => item.length < max);
}
validateCharacterCount(10, 'wvoquie');
// true
validateCharacterCount(10, ...['wvoquie']);
// true
const tags = ['Hobbs', 'Eagles'];
validateCharacterCount(10, ...tags);
// true
// true
validateCharacterCount(10, 'Hobbs', 'Eagles');
- 단순, 간결해지고 예측가능성이 높아졌다.
- 함수를 보자마자 최소 2개 이상의 인수를 받을 수 있다는 것을 알 수 있다.
- 나머지 매개변수를 사용하는 이유
- 인수를 배열로 다루는 것을 다른 개발자들한테 알리는 경우
- 추가 매개변수를 가져오는 것으로 추정되는 라이브러리 함수를 해석하는데 도움이 되고 나열된 인수 확인이 가능하여 코드 디버깅에 유리하다.
Reference
- 자바스크립트 코딩의 기술 요약 / 정리
- 부동소수점 관련 포스팅
https://steemit.com/kr/@modolee/floating-point
728x90
반응형
'IT > Javascript' 카테고리의 다른 글
Javascript 자바스크립트 코딩의 기술 7장 유연한 함수를 만들어라 (2) (0) | 2024.02.23 |
---|---|
Javascript 자바스크립트 코딩의 기술 7장 유연한 함수를 만들어라 (1) (2) | 2024.02.21 |
Javascript 자바스크립트 코딩의 기술 5장 반복문을 단순하게 만들어라 (2) (0) | 2024.02.06 |
Javascript 자바스크립트 코딩의 기술 5장 반복문을 단순하게 만들어라 (1) (0) | 2024.01.24 |
Javascript 자바스크립트 코딩의 기술 4장 조건문을 깔끔하게 작성하라 (0) | 2024.01.18 |