[JavaScript] Unary (+) Operator | 단항 연산자 (+)로 문자열을 숫자로 변환하는 법, 활용예시

이은진·2020년 11월 20일
4

JavaScript Study

목록 보기
15/24
post-thumbnail
post-custom-banner

자바스크립트에서 문자열을 숫자로 변환할 때 parseInt(), parseFloat(), Number() 등의 메서드를 사용하기도 하지만, 단항 연산자(+)를 사용하면 더욱 간단하고 가독성 좋게 변환할 수 있다.

1. 단항 연산자(+)의 역할

단항 연산자(+)는 한 개의 피연산자, 즉 한 개의 인수와 짝을 이루어 역할을 합니다. 더하기를 의미하는 기존의 (+) 기호와는 달리, 숫자로 변환해주는 역할을 담당하는 단항 연산자 (+)는 인수의 바로 앞에 붙습니다. ECMA 공식 문서에 따르면 단항 연산자 (+)는 문자열인 인수를 숫자 형태로 빠르고 간단하게 바꾸어주는 문법입니다. 간단하게 형을 바꾸어준다는 장점이 있지만, 그렇게 할 수 없는 경우도 있기 때문에 각각의 경우를 알아보겠습니다.

1-2. 단항 연산자(+)가 적용될 수 있는 경우

문자열 앞에 단항 연산자 (+))를 붙여주면, 문자열을 숫자 타입으로 변환하여 리턴합니다. 문자열 뿐만 아니라 true, false, null값 또한 숫자 타입으로 변환합니다. 또 이진법과 16진법 수도 변환해줍니다. 다양한 경우에 어떤 숫자로 변환해주는지 알아봅시다.

console.log(+"10");  // 10
console.log(+"10.1");// 10.1
console.log(+"-10"); // -10

console.log(+true);  // 1
console.log(+false); // 0
console.log(+0xBABE) // 47806 (Hexadecimal)
console.log(+null)   // 0

원래 숫자일 경우에는 +를 붙여도 아무 변화가 없습니다. +를 붙인다는 것의 의미가 양수로 만들어준다는 뜻은 아닙니다.

const a = -10
console.log(+a); // -10

문자열의 내용에 해당하는 숫자를 합치려면, 예를 들어 "10"과 "25"를 합해서 "35"의 결과가 나오도록 하려면 각각 숫자로 변환한 후 더해야 합니다. 문자열 상태에서 더한다면 문자가 나열된 상태로 리턴되기 때문입니다. 예시를 보겠습니다.

let bread = "2500"
let cake = "30000"

console.log(+(bread+cake)) 		// 250030000
console.log(+bread + +cake)		//32500

1-2. 단항 연산자(+)가 적용될 수 없는 경우

문자열을 숫자로 변경할 수 없다면 NaN (Not a Number)를 리턴합니다. 대표적으로 문자열, 또는 빈 문자열이나 함수, 빈 객체는 숫자로 변환할 수 없기 때문에 NaN으로 리턴합니다.

console.log(+"abc"); // NaN
console.log(+function(val) {return val}) // NaN
console.log(+'')     // NaN
console.log(+'123a') // NaN
console.log(+{})     // NaN

2. 단항 연산자(+)를 활용한 예시

이전에 작업한 가계부 앱에서 단항 연산자를 사용했습니다. 폼으로 사용자의 거래 날짜와 금액을 받은 후 그 값대로 sort 및 filter를 하기 위해 단항 연산자(+)를 활용했습니다. 그리고 나서 사용자가 선택한 수입 또는 지출 선택지에 따라 따로 + 또는 - 기호를 붙여주었습니다.


//Add transaction
const addTransaction = (e) => {
  e.preventDefault()
  //Generate random ID
  const generateID = () => Math.floor(Math.random() * 100000000)

  if (text.value.trim() === '' || amount.value.trim() === '') {
    alert('내역과 금액을 모두 입력해주세요.')
  } else {
    const sign = radio[0].checked === true ? '+' : '-'
    const transaction = {
      id: generateID(),
      text: text.value,
      amount: +`${sign}${amount.value}`,
      date: +`${yearInput.value}${monthInput.value}${dayInput.value}`
    }

    transactions.push(transaction) //add the transaction into the transactions array
    updateValues() // update the calculated transaction
    
    radio[0].checked = false
    radio[1].checked = false
    yearInput.value = ''
    monthInput.value = ''
    dayInput.value = ''
    text.value = ''
    amount.value = ''
    
    updateLocalStorage()
    init()
  }
}

//Sort by date
const sortByDate = () => {
  return transactions.sort((a, b) => {
    if (a.date > b.date) {
      return 1
    } else if (a.date < b.date) {
      return -1
    } else {
      return 0
    }
  })
}

//Rendering storage data
const renderTransactions = () => {

  if (sort_plus.classList.contains('sort')) {
    list.innerHTML = ''
    const incomeTransactions = transactions.filter((transaction) => transaction.amount > 0)
    incomeTransactions.forEach((transaction) => {
      addTransactionDOM(transaction)
    })
  } else if (sort_minus.classList.contains('sort')) {
    list.innerHTML = ''
    const expenseTransactions = transactions.filter((transaction) => transaction.amount < 0)
    expenseTransactions.forEach((transaction) => {
      addTransactionDOM(transaction)
    })
  } 
}

//Update the balance, income and expense
const updateValues = () => {
  //map() method result array
  const amounts = transactions.map((transaction) => transaction.amount)

  const total = amounts.reduce((acc, item) => (acc += item), 0)
  const income = amounts
    .filter((item) => item > 0)
    .reduce((acc, item) => (acc += item), 0)
  const expense = amounts
    .filter((item) => item < 0)
    .reduce((acc, item) => (acc += item), 0)

  balance.innerText = `${numberWithCommas(total)}`
  money_plus.innerText = `${numberWithCommas(income)}`
  money_minus.innerText = `-${numberWithCommas(Math.abs(expense))}`
}
profile
빵굽는 프론트엔드 개발자
post-custom-banner

3개의 댓글

comment-user-thumbnail
2020년 11월 21일

안녕하세요! 좋은정보 감사합니다. 은진님 혹시 이런 토이 프로젝트들을 강의를 통해서 만드신다면 어떤 강의인지 알려주시면 감사하겠습니다. 😆

1개의 답글