step_1: from function to arrow function

Seunghyunkim1·2020년 6월 30일
0

프론트엔드

목록 보기
1/8

프로그램을 기능을 수행하는 함수 있음

절차적인 언어 함수가 중요한기능을함 자스처럼

클래스가 추가되어있으니까 객체지향아닌가?

추가된 클래스는 자바처럼 퓨어함 클래스가 아니고 프로토타입을 베이스로한 가짜 객체지향이라고 할수 있다. 이부분은 클래스랑 객체를 좀더 공부해야함

인풋, 아웃풋, 명명 매우매우 중요
api( application programming interface)를 쓸때
함수의 이름을 보고, 역할 예측, 파라미터 예상 가능

Function

프로그램의 기초적인 빌딩 블록
재사용, 반복적 사용가능, subprogram이다.
함수는 어떠한 일을 수행하거나, 값을 계산한다.

1. function 정의

function name(param1, param2) {body... return; }
one function === one thing //함수하나 하는일하나
naming: doSomething, command, verb //함수는 동작하는이름, 변수는 명사로
e.g. createCardAndPoint -> createCard, createPoint //하는일 나눠주기
function is object in JS
function log(message) {
console.log(message);
}
log('hello')
log(123)   //타입이없어서 스트링인지 넘버인지 애매하다

Typescript 맛보기

function log(message: string): number {
console.log(message);
return 0;
}

2. Parameter

  • premitive parameter: 메모리에 value 저장, 전달
  • object parameter: 메모리에 레퍼런스 저장, 전달
function changeName(obj) {  //전달된 onj이름 coder로 변경
  obj.name = 'coder';
}
const elie = { name: 'ellie'}; //엘레라는 obj을 만들어서 할당하면 메모리에 obj가 만들어진 레퍼런스가 들어감, 이 레퍼런스는 obj어딘가를 메모리에서 가르키고 있음.
changeName(ellie);
console.log(ellie);

3. Default parameters (es6)

function showMessage(message, from) {
  console.log(`${message} by ${from}`);
}
showMessage('Hi!');  //message는 출력이 되지만, from은 undefined된다


//from이 undefined될경우를 위해, 아래와 같이작성 (es5)
function showMessage(message, from) {
  if (from === undefined) {
    from = 'unknown';
  }
  console.log(`${message} by ${from}`);
}
showMessage('Hi!'); 

//현재 아래와같이 작성 가능
function showMessage(message, from = 'unknown') {
  console.log(`${message} by ${from}`);
}
showMessage('Hi!'); 

4. Rest parameters (ES6)

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', 'ellie'); //인자를 3개로 전달 -> 배열로 전달

5. Local scope

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

let globalMessage = 'global' //global var
function printMessage() {
  let message = 'hello'; //local var
  console.log(message); //블락안에서 호출가능
  console.log(globalMessage); //블락안에서 호출가능
  
   //함수 부모와 자식 => 클로져
  function printAnother() { 
    console.log(message);   //자식은 부모함수의 변수를 전다락능
    let childMessage = 'hello';
  }
  console.log(childMessage) //이건불가능
}
printMessage();

6. Return a value

모든함수에는 return undefined (생략가능) 이거나 return값 계산

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

7. Early return, early exit

//bad
function upgradeUser(user) {
  if (user.point > 10) {  //한블록 안에서 if, else를 번갈아서 길게쓰면 가독성이떨어짐 
    //long logic..
  }
}

//good
function upgradeUser(user) {
  if(user.point <= 10) { //조건이 맞지 않을때, 값이 undefined, -1 일 경우, 빨리 return해서 함수를 종료하고, 조건이 맞을때만 필요한 함수, 로직을 실행하는게 더 좋다 
    return;
  }
  //long logic..
}

First-class function

함수는 다른 변수와 마찬가지로 변수처럼 할당이 되고
다른함수에 파라미터로 전달이 되고
리턴값으로도 리턴이 된다.

1. Function expression

function expression은 할당된 다음부터 호출이 가능

//함수를 선언함과 동시에 print변수에 할당
print(); //위에서 호출하면 error -> 가능하게 hoisting 
// hoisting: 함수가 선언되기전에 호출되도 호출이가능하다
// js엔진이 선언된것을 제일 위로 올려주기 때문이다. 

const print = function () {  //anonymous function
console.log('print');        //필요한부분만 함수에 작성해서 변수에 할당가능
}							//함수 명명 가능 
print(); //프린트 호출
const printAgain = print; //다시 할당
printAgain(); //호출
const sumAgain = sum; 
console.log(sumAgain(1,3));

2. Callback function using function expression

//콜백함수 의미 => 상황에 맞게 전달하고 싶은 함수를 전달
//여기서 인자 3개로 들어온 함수 3개를 전달해야함
function randomQuiz(answer, printYes, printNo) {
  if (answer === 'love you') {
    printYes(); 
  } else {
    printNo();
  }
} 

const printYes = function () {   //anonymous function
  console.log('yes!');
};

//named function
//better debugging in debegger's stack traces(trace에 함수이름이 나오기위해)
//recursions => 함수안에서 자신을 또 호출한다?(재귀)
//피보나치 수열, 반복되는 평균값을 계산해서 적용
// call stack
const printNo = function print() {  
  console.log('no!');
  print();  //무한호출 => 함수안에서 자기자신을 다시호출 
}
randomQuiz('wrong', printYes, printNo);
randomQuiz('love you', printYes, printNo);

Arrow function

always anonymous

const simplePrint = function () {
  console.log('simplePrint!');
};

//애로우는 이런식으로 작성 가능
const simplePrint = () => console.log('simplePrint!');

const add = function (a, b) {
  return a + b ;
};
const add = (a, b) => a + b;

const simpleMultiply = (a, b) => {
  //do something more
  return a * b;
};

IIFE ( Immediately Invoked Function Expression)


//함수 선언과 동시에 호출
(function hello() {
  console.log('IIFE');
})(); 

Arrow function에는 없는것 3가지

  • 함수이름
  • this
  • arguments

1. 함수이름 없다

const myFun = function () {

}
//함수는 실행될때 자신의 scope안에 this가 존재한다
//하지만 arrow function에는 자기의 this가 존재하지 않는다. 
const myFun2 = () => {  
  
}
//this가 없기때문에 bind, apply, call을 이용해서 주입 불가능

var myObj = {
  count: 3,
  setCounter: function(){
    console.log(this.count);
  }
}
myObj.setCounter(); //3

2. this 없다.

const btn = document.getElementById('btn')

var myObj = {
  count: 3,
  setCounter: function(){
    console.log(this.count);
    btn.addEventListenr('click', (function(){
      console.log(this); //<button>찍힘
    }).bind(this)) //여기서 bind로 묶어주면 setCounter의 this에 접근가능
  }
}
myObj.setCounter(); 

Arrow function (this가 없는)

애로펑션을 쓰게되면 scope상에 this가 존재하지 않으므로 this를 연결해주는 bind가 필요가 없어진다.

const btn = document.getElementById('btn')

var myObj = {
  count: 3,
  setCounter: function(){
    console.log(this.count);
    btn.addEventListenr('click', () => {
      console.log(this) //선언된 scope상에 바로 setCounter의 this로 접근가능
      console.log(this.count++) //콘솔 -> 1씩증가
    })
  }
}
myObj.setCounter();
const myClass = function() {
  //여기서 this가 하나의 객체로서 역할
}

const myClass = () => {
//arrow function 일때는 this가 없으므로 error
//constructor로서 사용 불가능 
  //그렇다면 당연히 prototype 도 존재하지 않는다?? (추가요망)
}
new myClass(); //생성자로서 인스턴스를 만들수 있다. 

3. argument가 없다?

const myFun = function(){
console.log(arguments); //scope에서 자동으로 배열처럼 접근할수있다.
}
myFun(1,2,3,4)


 const myFun2 = () => {
   console.log(arguments); //arrow func에서는 argument가 들어가지 않는다. this처럼 존재하지 않는다. 
 }
 myFun2(1,2,3,4)
 
//자기의 scope에 argument가 없기때문에, arrow function이 정의된 outter함수의 scope를 참조하게 된다.
function outter(){
 const myFun2 = () => {
   console.log(arguments);
 }
 myFun2();
}
outter(1,2,3,4)

rest parameters를 사용한다

배열처럼이 아닌 배열이 생성된다.

const myFun2 = (...args) => {
  console.log(args);
}
myFun2(1,2,3,4) 

0개의 댓글