[TIL]201201

슬지로운 개발생활·2020년 12월 1일
0

TIL

목록 보기
46/73
post-thumbnail

1. 코드스테이츠

화살표 함수

  • 함수 표현식을 축약한 형태
  • call, apply, bind 사용 X
  • 화살표 함수 실행은 this를 결정하지 않는다.
    • 중괄호 사용: 함수 내(function body) 표현식이 2줄이상이면, return문과 중괄호를 같이 명시적으로 쓸 것!
    const calculateKoreanAge = bYear => {
      let thisYr = new Date().getFullYear();
      let age = thisYr - bYear + 1
      return `당신의 한국 나이는 ${age}입니다`;
    }
    
    calculateKoreanAge(2000) // "당신의 한국 나이는 21입니다"
    • 소괄호(parentheses)사용
    const add = (x, y) => x + y
    const multiply = (x, y) => (x * y) // O, 정상작동
    const substract = (x, y) => {x - y} // X, undefined
    • 클로저에 강력하다!!!
    const adder = function(x) {
      return function(y) {
        return x + y
      }
    }
    // ↓
    const adder = x => y => x + y

구조 분해 할당

  • python에서 보던 구조 분해 할당
  • 배열이나 객체의 속성을 해체 후 그 값을 개별 변수에 담을 수 있게 하는 JS 표현식이다.
    //기본 형태
    // 배열
    var a, b;
    [a, b] = [10, 20];
    console.log(a); // 10
    console.log(b); // 20
    
    //변수 값 교환
    var a = 1;
    var b = 3;
    [a, b] = [b, a];
    console.log(a); // 3
    console.log(b); // 1
    
    //객체
    ({ a, b } = { a: 10, b: 20 });
    console.log(a); // 10
    console.log(b); // 20

    참조 : mdn


this

함수 호출 방법

// 1. Global : 정확히 함수실행이 아니라 전역에서 this를 참조할 때
console.log(this)

// 2. Function 호출
foo()

// 3. Method 호출 : 메소드는 객체가 가지고 있는 동작을 말한다.
obj.foo()

// 4. new키워드를 이용한 생성자 호출
new foo()

// 5. .call()또는 .apply() 호출
foo.call()
foo.apply()

함수 실행에 따른 this 바인딩 패턴

패턴바인딩 되는 객체설명
Method 호출부모 객체 (실행 시점에 온점 왼쪽에 있는 객체)하나의 객체에 값과 연관된 메소드를 묶어서 사용할 때 주로 사용함
new 키워드를 이용한 생성자 호출새롭게 생성된 인스턴스 객체객체 지향 프로그래밍에서 주로 사용함
.call 또는 .apply 호출첫번째 인자로 전달된 객체this 값을 특정할 때 사용하며, 특히 apply의 경우 배열의 엘리먼트를 풀어서 인자로 넘기고자 할 때 유용함

하기에 나오는 Global형태나 function호출 방법은 this 사용할 이유 없음.
패턴바인딩되는 객체 (브라우저)바인딩되는 객체 (node.js)
Globalwindow (strict mode에서는 undefined)module.exports
Function 호출window (strict mode에서는 undefined)global

this 인자를 바인딩해야하는 대표적인 경우 2

1. 이벤트 핸들러

  • bind는 이벤트 핸들러에서 이벤트 객체 대신 다른 값을 전달하고자 할 때 유용
    <div id="target"></div>
    • 기본형태
    let target = document.querySelector('#target')
    let aligns = ['left', 'center', 'right']
    
    aligns.forEach(function(align) {
      let btn = document.createElement('button')
      btn.textContent = align
      btn.onclick = handleClick
      target.appendChild(btn)
    });
    
    function handleClick() {
      console.log(this)
    }
    
    // left 버튼을 클릭하면 <button>left</button> 콘솔에 표시
    // center 버튼을 클릭하면 <button>center</button> 콘솔에 표시
    // right 버튼을 클릭하면 <button>right</button> 콘솔에 표시

    • 바인드를 이용해 이름이 콘솔에 표시되는 방법
    let target = document.querySelector('#target')
    let aligns = ['left', 'center', 'right']
    
    aligns.forEach(function(align) {
      let btn = document.createElement('button')
      btn.textContent = align
      btn.onclick = handleClick.bind(align) // this 값: align
      target.appendChild(btn)
    });
    
    function handleClick() {
      alert(this);
    }
    // left 버튼을 클릭하면 alert창에 'left' 표시
    // center 버튼을 클릭하면 alert창에 'center' 표시
    // right 버튼을 클릭하면 alert창에 'right' 표시

    • bind를 이용하지만 this는 이용하지 않는 방법(콘솔 표시)
    let target = document.querySelector('#target')
    let aligns = ['left', 'center', 'right']
    
    aligns.forEach(function(align) {
      let btn = document.createElement('button')
      btn.textContent = align
      btn.onclick = handleClick.bind(null, align)
      target.appendChild(btn)
    });
    
    function handleClick(align) {
      alert(align);
    }

    • 익명 함수를 이용해 이름이 콘솔에 표시되는 방법
    let target = document.querySelector('#target')
    let aligns = ['left', 'center', 'right']
    
    aligns.forEach(function(align) {
      let btn = document.createElement('button')
      btn.textContent = align
      btn.onclick = function() { handleClick(user) };
      target.appendChild(btn)
    });
    
    function handleClick(align) {
      alert(align);
    }

2. setTimeout

  • setTimeout은 시간 지연을 일으킨 후 함수를 비동기적으로 실행하게 하는 함수이다.
  • 명시적으로 항상 window 객체를 this 바인딩하는 특징이 있다.
    • 예제
    class Rectangle {
      constructor(width, height) {
        this.width = width
        this.height = height
      }
     
      getArea() {
        return this.width * this.height
      }
    
      printArea() {
        console.log('사각형의 넓이는 ' + this.getArea() + ' 입니다')
      }
     
      printSync() {
        // 즉시 사각형의 넓이를 콘솔에 표시합니다
        this.printArea()
      }
    
      printAsync() {
        // 1초 후 사각형의 넓이를 콘솔에 표시합니다
        setTimeout(this.printArea, 1000)
      }
    }
    
    let box = new Rectangle(40, 20)
    box.printSync() // '사각형의 넓이는 800 입니다'
    box.printAsync() // 에러 발생!
    Uncaught TypeError: this.getArea is not a function
        at printArea (<anonymous>:12:36)

    • bind를 이용하여 printAsync메소드 수정
    printAsync() {
      // 1초 후 사각형의 넓이를 콘솔에 표시합니다
      setTimeout(this.printArea.bind(this), 1000)
    }

    • 익명 함수를 이용하여 printAsync메소드 수정
      - 권장하지 않는다. 깔끔한 방법은 아니다.
    printAsync() {
      // 1초 후 사각형의 넓이를 콘솔에 표시합니다
      setTimeout(this.printArea.bind(this), 1000)
    }

    • 화살표 함수를 이용하여 printAsync메소드 수정
    printAsync() {
      // 1초 후 사각형의 넓이를 콘솔에 표시합니다
      setTimeout(() => {
        this.printArea()
      }, 1000)
    }


TODAY MOOD

문제는 다 풀었으나, 이해하지 못하는 문제들이 한가득...
특히 call, apply, bind!!
꼭 정말 PRE때 koans 처음 풀었을 때와 같은 너낌적 너낌.

0개의 댓글