[aboutJS] Functions

Adela·2020년 8월 6일
1

aboutJS

목록 보기
4/9
post-thumbnail

자바스크립트의 꽃🌹

참고영상: 드림코딩 | 자바스크립트 기초 강의

들어가기 앞서..

(추후 더 자세히 공부하겠지만) 자바스크립트도 절자지향 언어라고 할 수 있다.
👉🏻 function이 매우 중요한 기능을 담당

서브 프로그램이라고 할 정도로 각각의 작은 기능들을 하는 것이 바로 함수, function !

function이란 모름지기..

input이 들어가면, 이걸 잘 처리한 다음에 output을 return하는 것 !

  • 그래서 언어 자체에 있는 함수를 쓰거나 API를 쓸때 함수의 이름을 보고 "어떤 기능을 하겠구나~" 생각할 수 있음
  • 전달해야 하는 파라미터가 무엇인지 어떤 값으로 리턴해야할지 기대할 수 있음
  • 함수의 인풋, 아웃풋, 함수 이름을 잘 정하는 것이 매우 중요 !!

function

  • 프로그램의 building block
  • 서브프로그램이라고도 할 수 있음
  • 재사용 가능
  • 한가지의 task나 어떤 값을 계산하기 위해 사용됨

function 정의

  1. function name
function name(param1, param2){
  body 
  ...
  return 
}
  • 하나의 함수 === 한가지의 일
  • 이름:
    • (변수는?) 명사
    • 동작하는 것이기 때문에 command나 동사 형태로 짓기
    • 함수 이름 정하기 어렵다? 내가 너무 많은 동작을 하고 있는건 아닌지 생각해보기
    • ex. createCardAndPoint -> createCard, createPoint로 나누는게 👍🏻
  • 자바스크립트에서 함수는 Object
    • 변수나 파라미터로 할당 가능
    • 함수를 리턴 가능
function printHello(){
  console.log('Hello')
}
printHello() // 함수 호출

여기서 좀 더 유용한 함수를 만든다카면?

function log(msg){
  console.log(msg)
}
log('Hello')

이런식으로 파라미터로 전달 받아서 얘를 가지고 출력하는 형식이 더 좋다.

※ 자바스크립트는 타입이 따로 없다!

  • 그래서 함수 자체의 인터페이스만 보았을 때 숫자 or 문자열 전달해야 하는지 명확하지 않음
  • 숫자가 문자열로 변환되어 출력되어 상관없지만, 타입이 중요한 경우에는 자바스크립트가 약간 난해할 수 있다.
  • 타입스크립트 배우면..ㅎㅎ 꼭 배우자..!

Parameters

  • primitive parameters: 메모리에 value가 그대로 저장되어 있어서 value가 전달
  • object parameters: 메모리에 ref가 저장되어있어서 ref가 전달
function changeName(obj){
  obj.name = 'park'
}

const yang = {name: 'kim'}
changeName(yang)
console.log(yang)

전달된 object의 이름을 무조건 park으로 바꾸는 함수를 작성하였다.

  • 이 object는 ref를 가리키고 있음
  • 이 ref가 가리키고 있는 name의 이름을 park으로 바꾸는 것.

default parameters

ES6에 추가됨

function showMsg(msg, from){
    console.log(`${msg} by ${from}`)
}

showMsg('hi')

만약 from의 파라미터를 전달하지 않으면?

정해지지 않았기 때문에 undefined가 출력된다.

추가되기 전에는 만약 undefined면 'unknown'이 출력되도록 만들어 사용하곤 했다.

function showMsg(msg, from){
    if(from === undefined){
        from = 'unknown'
    }
    console.log(`${msg} by ${from}`)
}

showMsg('hi')

rest parameters

ES6에 추가됨
...을 사용하면 배열 형태로 전달됨

function printAll(...args){
    for(let i=0; i<args.length; i++){
        console.log(args[i])
    }
}

printAll("yang", 'won', 'kim', 'cheerup!!')

"yang", 'won', 'kim', 'cheerup!!' 이 배열 형태로 전달된다.
함수를 실행시키면,

이렇게 잘 나오는 것을 확인 !

(+) 간단하게 for문 쓰기

for(const arg of args){
   console.log(arg)
}

이렇게 하면 args 안에 있는 원소들이 arg가 되어 차례로 출력된다.

args.forEach((arg) => console.log(arg))

그냥 한줄로도 쌉가능~

local scope

밖에서는 안이 보이지 않고, 안에서만 밖을 볼 수 있다.

let globalMessage = 'global'
function printMessage(){
    let message = 'hello'
    console.log(message)
    console.log(globalMessage)
}
printMessage()
  • message는 안에서만 볼 수 있음.
    그래서 밖에서 호출하면 에러가 난다.
  • 그러나 안에서는 globalMessage를 호출할 수 있음
let globalMessage = 'global'
function printMessage(){
    let message = 'hello'
    console.log(message)
    console.log(globalMessage)
  function printAnother(){
        console.log(message)
        let childMessage = 'what?'
    }
}
printMessage()

printMessage의 안에 있는 printAnother 역시 마찬가지다.

  • printAnotherprintMessage에 있는 변수를 볼 수 있음
  • printMessagechildMessage를 호출할 수 없음

함수가 중첩 -> closure
이부분은 나중에 더 자세히..

return

모든 함수는 return undefined 이거나 return (지정한 무엇) 이다.

function sum(a, b){
  return a+b
}
const result = sum(1, 2)
console.log(`sum: ${sum(1, 2)}`)

early return

function upgradeUser(user){
  if(user.point > 10){
    // upgrade logic...
  }
}

👎🏻 이건 가독성이 떨어지는 안좋은 방법

function upgradeUser(user){
  if(user.point <= 10){
    return
  }
  // upgrade logic..
}

👍🏻 좋은 방법

📌 즉, 조건에 맞지 않으면 그냥 끝내버리고, 조건에 맞는 경우에만 긴 logic을 시행하도록 하는 것!

다시 말해,

  • 조건이 맞지 않는 경우
  • 값이 undefined 인 경우
  • 값이 -1인 경우

빨리 return을 하고, 필요한 로직들을 그 밑에 작성하는 것이 더 좋음

function expression

const print = function(){ // anonymous function
    console.log('print')
}
print()

함수를 print라는 변수에 할당

  • 함수에 이름이 없는 것: anonymous function
  • 함수에 이름이 있는 것: named function

print라는 변수에 함수를 호출하듯이 하면됨

const print = function(){
    console.log('print')
}
print()

const printAgain = print;
printAgain()

새로운 변수에 print를 할당하면?

함수를 할당하였으므로, 똑같이 실행된다.

함수를 변수에 할당해서 함수처럼 사용할 수 있다.

callback

function randomQuiz(answer, printYes, printNo){
    // printYes, printNo 라는 각각의 함수를 전달
    if(answer === 'love you'){
        printYes();
    } else {
        printNo()
    }
}

두가지의 콜백 함수가 전달됨

function randomQuiz(answer, printYes, printNo){
    // printYes, printNo 라는 각각의 함수를 전달
    if(answer === 'love you'){
        printYes();
    } else {
        printNo()
    }
}

const printYes = function(){
    console.log("yes")
}

const printNo = function print(){
    // named => 디버깅할때 함수 이름이 나오게 하기 위하여
    // 혹은 재귀를 돌리기 위해
    // print()
    console.log("no")
}

randomQuiz("wrong", printYes, printNo)
randomQuiz("love you", printYes, printNo)

arrow function

※ 이름이 없는 anonymous function

const simplePrint = function(){
    console.log("simplePrint")
}

기존 function 선언 방식은 이렇게 function도 써야하고.. {} 처리도 해줘야 하고..
너무 번거로움 ㅜㅜ

👍🏻 그러나 이를 arrow function으로 하면 정말 간단함

const simplePrint = () => console.log("simplePrint")

한줄이면 끝 !

물론 parameters도 전달할 수 있다.

const add = (a, b) => a + b

이렇게 한줄인 경우에는 {} 없이 가능하다.
만약 좀 더 다양한 일들을 해야 한다면

const add = (a, b) => {
// do something..
  return a + b
}

블럭 처리를 해야 한다.
📌 블럭처리를 한다면 return을 써줘야 한다.

IIFE

원래 함수를 만들었으면, 따로 함수를 호출해야 하는게 정석.
하지만 선언과 동시에 호출하려면??

(function hello(){
  console.log('IIFE')
})();

최근엔 잘 쓰이지 않지만,
함수를 바로바로 사용하고 싶을 때 유용하다.

profile
개발 공부하는 심리학도

0개의 댓글