본문 바로가기

JS

JS #6-자바스크립트 기초 개념6 (함수표현식, 화살표함수)

함수

 

getComputedStyle(node)[prop] : html 태그의 값을 가져오는 것 
node 는 요소노드(클래스), prop은 프로퍼티를 가르킨다.
ㄴ node에 $0을 입력하면 선택된 엘리먼트의 값을 가져온다. 
function getStyle(node, prop) {
    getComputedStyle(node)[prop]; //html의 태그의 값을 가져온다.node가 요소노드  prop이 프로퍼티
}

const first = document.querySelector('.first');
const size = getStyle(first, 'fontSize');
console.log(size);

 

 

querySelector(요소 노드);
해당하는 id나 class의 값을 가져온다. 
        node = document.querySelector(node);
        console.log(node);

 

출력결과

 

 

node.style.prop = 'value'
html의 프로퍼티를 정의해준다. 

 

 

점 표기법, 대괄호 표기법 (변수) 
function setStyle(node , prop, value) {
    if(typeof node === 'string') node = document.querySelector(node);


    node.style[prop] = value;

}

함수의 인자로 받은 변수들을 사용할 때

점으로 사용하거나 대괄호로 사용할 수 있다. 

 

 

Validatiion
에러 던지기 
throw new Error = '~~~'

function setStyle(node , prop, value) {
    if(typeof node === 'string') node = document.querySelector(node);


    if(typeof prop !== 'string') {
        throw new Error('setStyle 함수의 두 번째 인수는 문자 타입이어야 합니다.');
    }
    if(!value) throw new Error('setStyle 함수의 세 번째 인수는 필수 입력값 입니다.');

    node.style[prop] = value;
}

함수의 인자가 잘못 입력되었을 상황을 고려하여 애러 처리를 해준다. 

 

 

삼항식으로 작성하기
function css(node, prop, value) {

    if(!value) {
        return getStyle(node, prop);
    }
    else {
        setStyle(node, prop, value);
    }

    return (!value) ? getStyle(node, prop) : setStyle(node, prop, value);
}

삼항식을 사용하여 위의 if~else문으로 작성했던 문장들을 단 한 문장으로 줄였다. 

value가 없을 때를 조건으로 삼항식으로 작성하였다. 

 

현업에서 이 방법이 굉장히 활발히 쓰이므로 반드시 공부할 것

 

 

콜백 함수 (call back) ★★★ 중요
함수를 내부에서 사용하기! 

 

함수가 yes 안에 담기고, no 안에 담긴다. 

함수는 자체가 복사가 된다 (참조에 의한 복사x) 

콜백함수 예제 2

  function movePage(url,success,fail){

    if(url){
      success()
    }else{
      fail()
    }
   
  }
 
 
  movePage(
    function (){
      console.log('3초 뒤 해당 url로 넘어갑니다.');
    },
    function (){
      console.error('잘못된 url 정보를 입력하셨습니다.');
    }
  )
 

 

movePage함수를 호출하면서 url과 함수 그 자체를 넘겨준다. 

movePage에서는 해당 매개변수들을 함수 이름의 형태로 전달받고 처리한다. 

 

매개변수가 함수 안에서 전달이되는 상태 

 

 

-> 화살표 함수와 삼항식을 사용해보기

  function movePage(url,success,fail){
   
    url.includes('www') ? success(url) : fail()
  }
 
  movePage(
    function (url){
      console.log(`3초 뒤 해당 url인 ${url}로 넘어갑니다.`);
     
      setTimeout(() => {
        // window.location.href = url
      }, 3000);
    },
    function (){
      console.error('잘못된 url 정보를 입력하셨습니다.');
    }
  )

 

함수안에서 인수들에 접근할 때 ! arguments
  // 함수 선언 → 일반 함수 (표현)식
  let calculateTotal = function(a,b,c,d,e,f,g) {

    //함수안에서만 접근 가능한 인수들의 집합 객체
    console.log(arguments);
    return a+b+c+d+e+f+g;
  }

  const result = calculateTotal(10,20,30,40,50,60,70,80);
  console.log(result);

 

 

for...of 사용하여 위의 예제 풀기

Symbol.iterator를 내장하고 있다면 반복 가능한 요소이다.

for of 는 반복 가능한 요소일 때 사용 가능하므로 다시 for문을 정의하면...

  let calculateTotal = function(a,b,c,d,e,f,g) {
    let result = 0;

    for(let i of arguments) {
        result += i;
    }
    console.log(result);
    return result;
  }

  const result = calculateTotal(10,20,30,40,50,60,70,80);
  console.log(result);
 

for of는 직접 요소들을 불러오므로 arguments[i]가 아닌 i를 더해준다. 

 

 

forEach를 사용하여 반복문 돌리기
//arguments의 부모를 배열로 바꿔치기 한다면?
    arguments.__proto__ = Array.prototype;

    arguments.forEach(function(item, index){ //forEach 는 콜백 함수
        total+=item;
        return total;
    })
    return total;

1. arguments가 배열이 아니라서 프로토타입(부모) 를 배열로 만들어줬다. 

2. forEach는 item과 index도 찾아주기 때문에 forEach함수를 정의하여 total 에 item들을 모두 더해주고 리턴해준다. 

 

 

Array.from() 을 통해 유사배열 -> 배열로 만들기
    const arr = Array.from(arguments);
    console.log(arr);

 

예전 레거시 방법으로 배열 만드는 법

    const arr = Array.prototype.slice.call(arguments);

slice는 배열을 인덱스로 잘라서 사용하는 메서드인데, 아무 것도 전달하지 않으면 그 배열 자체를 반환한다. 

 

전개구문으로 배열 만드는 법 (가장 많이 사용)

    const arr = [...arguments];

 

 

arr.reduce(acc, cur) -> 구문을 줄여쓸 수 있어서 reduce
acc : 누적값
cur :  현재값
    const arr = [...arguments];

    arr.reduce(function(acc, cur){
        return acc + cur;
    }, 0) // ,0은 초기값이다.
  };

acc의 초기 값은 0으로 시작, cur에 저장된 current값을 가져와서 acc에 더하고

acc에 누적이된다. 

 

 

*reduce는 값을 내뱉어 줘야 한다,. (forEach와 다른 점!)

forEach => 값을 반환하지 않음 반복의 로직만 처리

reduce => 값을 반환함 모든걸 다 (배열, 객체, 문자, 숫자)

map => 배열을 반환함 : 새로운 배열로 반환해줌!

filter => 배열을 반환함

 

 

이피패턴 - 함수를 선언과 동시에 작동시키기 
//IIFE; 이피패턴
const MASTER = (function(){
    let uuid = 'asdasdasfas';

    return {
        geKey(){
            return uuid;
        }
        setKey() {
            uuid = value;
        }
    }
})();

 -> MASTER이라는 함수를 선언함과 동시에 끝에 붙은 ()를 통해 바로 실행시킬 수 있다. 

인자도 넘겨줄 수 있다. 

 

이런 것을 incapsulation 캡.슐.화 라고 한다. 

 

 

css 함수 안에 get,set,css 세개의 함수가 들어가있지만, 

전역에 노출된 것은 return을 수행한 css 하나뿐!

 

따라서 다른 변수들은 전역에서 접근이 불가능해서, 보호된다. 

캡슐화라고 할 수 있다!

 

 

--> export import 구문때문에 살짝 레거시가 된 이피패턴이다. 

 

 


 

 

화살표함수

 

args => 인자로 받으면 바로 배열로 받아짐!

앞서 배웠던 arguments보다 더 효율적이다 ㅎㅎ

 

Arrow 함수 

1. 중괄호를 없애고 한줄로 작성하면 return 값 생략이 가능하다.

 

 

2. Arrow 함수는 arguments를 가지지 못한다.

 

    let calcAllMoney = (...args)=> args.reduce((acc,cur)=> acc + cur,0);

    console.log( calcAllMoney(10,30,40,50) );

return 값을 생략하고 함수를 실행시킴

 

3. this를 가지지 않는다. 내 상의 영역에서 찾는다. 

 

이 코드의 경우, user라는 객체의 화살표함수로 정의된 totalGrades가 있는데, 

이 내부에서 this를 호출하면 상의 영역인 window에서 this를 찾게 된다.== 화살표 함수는 this를 가지지 않는다. 

일반 함수였다면 this는 나를 호출한 대상 객체를 가르키며, 출력한다. 

 

<정리> 

일반함수 this : 나를 호출한 대상을 this로 찾음

화살표함수 this : 가지고 있지 않음, 내 상위 영역에서 찾음

 

 

 

sayHi는 '누군가에 의해' 호출이 된 형태가 아니라,  (누군가에 의해 호출된 형태 : ~~~.sayHi())

자기자신이 그냥 호출된 형태이다 보니 this를 출력하면 window가 나온다. 

 

 

sayHi 함수가 화살표 함수라면, this를 가지지 않으니 상위 컨텍스트의 totalGrades로 간다.  (함수한개는 컨텍스트를 갖음)

이 때 totalGrades의 this가 객체로 존재하므로, 이를 가져다 쓰게 되어 sayHi도 동일한 this 를 가르키게 된다!!!

 

 

<정리>

객체의 메서드를 정의할때 concise method 사용,

메서드 안에서 함수를 정의할 때에는 화살표 함수를 사용해야 한다!!!

 


자바스크립트의 함수는 양면의 얼굴을 가지고 있다. (일반함수 / 생성자 함수)

 

  function button() {
  }
  const a = button() //결과 값이 담기게 된다.

이게 보통함수인데, 우리는 이렇게도 함수를 정의할 수 있다. 

  function button() {
  }
  const a = button() //결과 값이 담기게 된다.
 
  const b = new button();

b는 생성자함수로 '객체' 를 리턴한다. 

별도의 return 구문을 입력하지 않아도 자동으로 객체를 리턴하는 것이다. 

 

==>생성자함수를 구분짓기 위해서 !  함수의 첫 알파벳은 무조건 대문자로 해준다. 

+arrow function으로 정의한 함수는 절대 생성자를 생성할 수 없다!!! (constructor를 내장하고 있지 않기 떄문 = 함수 자체가 비교적 가볍다. )