본문 바로가기

JavaScript

20210210_JavaScript03 function, 함수선언, 매개변수, 지역전역 변수, 함수표현식, Arrow

JavaScript03

  • JavaScript에 대해 공부하기 위해서 유튜브 '드림코딩by엘리' JavaScript 강의를 듣고 글을 쓰고 있다.(강의를 꼭보길 바란다 너무 잘되어 있다.)

JavaScript functions

  • 각각 프로그램들은 고유한 기능들이 있고 그 프로그램 안에서도 각각의 기능들을 수행하는 function들이 존재함.
  • JavaScript도 java처럼 pure한 Object 언어가 아님 (프로토타입 베이스의 가짜 object 언어)
  • function 을 sub-program이라고 하기도 함!
  • input을 받아서 output으로 return 하는 것이 function임
  • 언어내 내장 함수 또는 API(Application Programming Interface)를 사용할때 함수이름을 보고 함수의 기능을 추측할수 있음
  • function에서는 input, output, function의 이름이 중요함

1. Function declaration (함수 선언)

  • 함수 선언 구조 : function functionName(param1, param1,) { body... return; }
  • 함수(Function)는 JavaScript에서 객체(Object)임
  • 한개의 함수에는 하나의 기능 만!
  • 함수명은 보통 verb 동사로 그와 반대로 변수명은 noun 명사로
  • Worng e.g ) createCardAndPoint -> 가능하면 분리해서 createCard , createPoint
function printHello() {
    console.log('Hello');
}
printHello();
// parameter 넣을 수 있음 (즉, 인자를 넣을 수 있음) 그리고 활용할 수 있음
function log(message) {
    console.log(message);
}

log('hello!!');

보너스. TypeScript

  • TypeScript 사이트 Platyground들어가서 TS를 맛볼수 있음
  • JS의 경우 interface(input, output의 datatype)가 정확히 명시안되어 있어서 프로그램 만들때 문제가 생김
  • TS의 경우 type을 요구하여 좀더 자세한 코드를 짤수 있고,
  • 협업과정이나, 작성한 것을 api로 제공시 TS를 쓰는게 더 명확하고 개발일을 더 쉽게 만들어줌
// js와 다르게 :을 통해 input과 output에 대한 datatype을 지정할 수 있음
function log(message: string) : number {
    console.log(message);
    return 0;
}

2. Parameters (매개변수)

  • premitive parameters(원래 매개변수): passed by value
  • object parameters(객체 매개변수): passed by reference
// obj는 단지 객체를 받아올 매개변수 명일 뿐임
function changeName(obj) {
    obj.name = 'coder';
}
// 전달된 obj의 네임을 coder로 바꾸는 함수
const raccoon = { name: 'raccoon' };
changeName(raccoon);
console.log(raccoon);
// object이기 때문에 값 변경이 가능하므로 변경된 사항을 볼수 있음

3. Default parameters (added in ES6)

  • parameter에 값이 안들어 올경우 기본 값 설정 가능
function showMessage(message, from = 'unknown') {
    // if (from === undefined) {
    //     from = 'unknown';
    // }
    console.log(`${message} by ${from}`);
}
showMessage('Hi!');

4. Rest parameters (added in ES6)

  • ...args 사용시 parameters를 배열(Array) 형태로 전달됨(python에서 list형으로 만들어 줌)
  • python의 for in 처럼 for of를 js사용가능
  • python의 pop 처럼 forEach를 python에서 사용가능
  • function은 object이기 때문에 아까 만든 printAll.하면 해당하는 속성을 볼 수 있음
function printAll(...args) {
    for (let i = 0; i < args.length; i++) {
        console.log(args[i]);
    }

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

    args.forEach((arg) => console.log(arg));
}
printAll('dream', 'coding', 'raccoon')

5. Local scope (지역 변수)

  • Local scope (지역 변수)는 코드 블럭 안에서만 사용 가능함
  • global scope (전역 변수)의 경우에는 코드 블럭 안, 밖 모두 사용 가능함
  • function 선언시 실행 코드안에 return 이 없으면 자동으로 return undefined; 가 들어 가있는 것과 같다. 그래서 return은 생략이 가능함
  • 함수(부모)안에 함수(자식)를 넣을 수 있음
    • 함수(부모)안에 함수(자식 가능 부모의 변수를 자식함수는 공유함(이를 클로저'closure' 라고 함),
    • 하지만, 반대로 자식변수를 부모 변수를 공유하지 않음
let globalMessage = 'global'; // global variable
function printMessage() {
    let message = 'hello';
    console.log(message); // local variable (super)
    console.log(globalMessage); // can use global variable in funciton
    function printAnother() {
        console.log(message);
        let childMessage = 'Hello'; // local variable (sub)
    }
    // console.log(childMessage) // error , sub variable 공유 불가
}
printMessage();
console.log(message) // error local variable 접근 불가

6. Return a value (값 반환)

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

7. Early return, early exit (나가는 것은 앞에다!)

  • 처음에 블록 안에서 많은 logic line을 작성하는 것은 가독성이 떨어짐
  • 필요한 조건 범위의 로직을 먼저 작성하지 말고
  • 예외가 되는 조건의 범위를 빨리 return을 통해 빠져 나오게 하는것을 먼저 작성하여 가독성을 올리는 것이 좋다.
  • 값이 undifined , -1 , 조건이 맞지 않은 경우 빨리 return 하게 할것(undifined 출력)
  • 즉, 느슨한 조건일 수록 앞으로, 제한적이고 코드가 많은 경우 뒤로
// Bad
function upgradeUser(user) {
    if (user.point > 10) {
        // long upgrade logic...
    }
}
// Good!!!!
function upgradeUser(user) {
    if (user.point <= 10) {
        return;
    }
    // logic upgrade logic... 
}

First-Class function

  • functions are treated like any other variable (변수 처럼 사용 가능)
  • can be assigned as a value to variable (변수와 마찬가지로 변수에 할당 가능함)
  • can be passed as an argument to other functions. (function의 parameter로 전달가능하고)
  • can be returned by another function (return 값으로도 사용가능함)

1. Function expression (함수 표현식)

  • a function declaration can be called earlier than it is defined. (hoisted)
    • 함수 선언시 제일 위로 올라감 hoisted (즉, 함수 선언만 되면 호출은 어디든지 상관 없음)
console.log(multiple(3, 5)) // no error 
function multiple (x, y) {
    return x * y;
}
  • a function expression is created when the execution reaches it. (실행 하면서 함수 만들수 있음)
  • 변수 만들면서 바로 함수 선언하면서 할당 가능
  • 다른 변수에 위를 할당 가능하고 이를 호출도 가능
const print = function() { // anonymous function <-> named function
    console.log('print');
}; // 이름 없이 함수 선언과 동시에 변수에 할당도 되고,  이름 있이 할당도 가능 
print();
const printAgain = print; // 다른 변수에 할당 가능
printAgain();
const sumAgain = sum; // sum함수를 sumAgain 변수에 할당하고 
console.log(sumAgain(1, 3)); // 호출 가능

2. Callback function using function expression (콜백 함수)

  • 기존의 함수를 불러와 parameter 사용하는 경우 그 함수를 Callback function이라고 함
  • 즉, parmeter로 기존의 함수를 불러와 조건에 따라 함수를 return
  • named function 의 경우 이름을 함수안에서 자신을 지칭할때 쓸수 도 있음.(python에서 self마냥)
    • named function is better debugging in debugger's stack traces
function randomQuiz(answer, Yes, No) {
    if (answer === 'love you') {
        Yes(); // paramer이기 때문에 그냥 함수처리만 되게 해도 되고, 굳이 넣을 함수와 이름이 같을 필욘 없다.
    } else {
        No();
    }
}
const printYes = function() { // anonymous function
    console.log('Yes!');
};
const printNo = function print() { // named function
    console.log('No!');
    // 자신 함수선언 안에서 스스로를 호출할때 사용하기도 함
    // print(); // 근데 무한 루트라서 call stack 이 꽉차서 error 발생함
};
randomQuiz('Wrong', printYes, printNo)
randomQuiz('love you', printYes, printNo)

3. Arrow function (화살 함수 표현식)

  • 선언 형식을 Arrow form으로 편하게 할 수 있음
  • 항상 이름이 없는 함수를 간결하게 만들어줌
// 1. base ->
const simplePrint = function () {
    console.log('simplePrint!');
};
// 1. arrow form
const simplePrint = () => console.log('simplePrint!');

// 2. arrow form ->
const add = (a, b) => a + b; 
// 2. base
const add = function (a, b) {
    return a + b;
};
  • code line 많은 경우 Arrow function
const simpleMultiply = (a, b) => {
    // do something more
    return a * b
}; // 단, 블럭 사용시 항상 return을 통해 값을 불러오게 해야함

5. IIFE: Immediately Invoked Function Expression (즉시 호출 함수 표현식)

  • 원래는 함수 선언후 호출 해야함
// base
function hello () {
    console.log('IIFE')
}
hello();

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

Quiz (계산기 함수 만들기)

  • 함수명 calculate, parameters command , a, b
  • 받을 command : add, substract, divide, multiply, remainder
  • 구상 : 제일먼저 command 구분하여 return 할지 연산하고 나중에 각 커맨드에 해당하는 코드 실행
  • 반대로 생각해 보려고 or and를 많이 생각해봄, or and 연산 실행 순서고려해서 만듬
const calculate = (command, a, b) => {
    if (command == 'add' || 'substract' || 'divide' || 'multiply' || 'remainder') {
        if (command == 'add') {
            return a + b;
        } else if (command == 'substract') {
            return a - b;
        } else if (command == 'divide') {
            return a / b;
        } else if (command == 'multiply') {
            return a * b;
        } else if (command == 'remainder') {
            return a % b;
        }; 
    } else { 
        console.log('Wrong cmd or check the parameters!')
    };
}; 

console.log(calculate('add', 5, 3))
// string으로 안하고 바로 그냥 치고 싶으면 command 부분을 callback  함수로 모두 만들어서 하면 됨