outwater 2021. 1. 13. 03:34

Start Think:
어제 새벽 4시까지 블로그 정리 및 공부를 하고 잤더니 일과시간에 조금 피곤하다는 느낌을 받았다.
속도를 올려서 빠르게 마무리 해보아야 겠다!.!

 

 

🎄오늘 한 일


✔️ 1.  Modern Javascript에서 사용하는 화살표함수, this, call & apply , bind 개념학습

  • 최신 자바스크립트에서 사용하는 화살표함수와 this의 개념을 익히고, 함수의 메소드인 call&apply, bind에 대해서 공부하였다. 공부하면서 100% 이해된다기보다는 60~80%이해하고, 그냥 이렇게 정의한거구나 하는 정도로 학습하였다. 
    this와 call, apply, bind에서 혼란스러웠으나 오후의 koans에서 실제 코드를 접하면서 조금 더 명확하게 이해하였다.

✔️ 2. Modern Javascript Koans 페어코딩
    koans는 함수와 메소드들의 작동원리를 실제 코드와 함께 이해하는데 큰 도움을 주는 것 같다. 마치 군대에서 구분동작을 익힌 후 한번에 동작을 진행하듯이 잘개잘개 쪼개어 해당 함수,메소드를 이해하는 재미가 쏠쏠하다.
그렇지만 this 와 bind 등이 아직은 조금 헷갈린다. 헷갈린다면 잘모른다는 것이고, 잘모르면 익숙해질때까지 반복해야 한다는 코드스테이츠 존경하는 강사님의 어록이 떠올랐다 ㅎ.;

 

🎄기억할 것


화살표함수

  • 함수표현식에서 function 키워드를 화살표로 축약하고, 본문(body)에 return문만 있는 경우, return을 생략하여 함수를 표현하는 것
  • 주의할점
    1. return을 생략하고 중괄호를 사용하면 안됨 
       const add = (x, y) => { x + y } (X) 
    2. 함수 내의 표현식이 2줄 이상일 경우, 보통 return을 생략하지 않음
    3. call, apply, bind 를 사용할 수 없다!
    4. 화살표 함수의 실행은 this를 결정짓지 않는다.
    5.  

//매개변수 지정 방법
	( ) => { ... }  // 매개변수가 없을 경우
	 x  => { ... }  // 매개변수가 한 개일 때 ( ) 생략가능
  (x, y)=> { ... }  // 매개변수가 여러개 일 때, ( ) 생략불가!

 

  • 클로저 함수는 연속된 여러 개의 화살표 함수로 표시할 수 있어 유용하게 사용됨

//함수 표현식
const adder = function(x) {
  return function(y) {
    return x + y
  }
}
adder(5)(7)

//화살표함수 
const adder = x => y => x + y

 

this 키워드

  • this 정의

    : 함수 실행시 호출방법에 의해 결정되는 특별한 객체

    : 함수 실행시 마다 this가 결정되므로, 실행되는 맥락(context)에 따라 this가 다르게 결정된다.

  • 함수 실행 다섯가지 방법

    1. 글로벌: 전역에서 this를 참조할 때
      : 사용하지 않음
    2. function 호출   foo( ) 
      : 사용하지 않음
    3. Method 호출  obj.foo( )
      : this는 부모객체(온점 왼쪽에 있는 객체)가 바인딩 된다.
    4. New 키워드를 이용한 생성자에서 호출 new Foo( )
      : 새롭게 생성된 인스턴스 객체가 바인딩된다.
    5. .call 또는 .apply 호출  foo.call( ) foo.apply( )
      :첫번째 인자로 전달된 객체에 바인딩되어 this값을 특정할 때 사용
  • 유의 사항

  1. 글로벌과 function 에서는 this를 사용하지 않도록 함
    : 경우에 따라 다양하게 this가 바뀌기 때문에 혼란스러움
  • Method 호출 예시

    Singleton 패턴이란?
     (추가조사 해볼 것) : 단 하나의 객체만 만들 수 있다. 따라서 여러개의 카운터를 만들어주려면 클로저모듈패턴이나 클래스로 만들어서 생성자 호출과 같이 사용한다.

let counter1 = {
  value: 0,
  increase: function() {
    this.value++ // 메소드 호출을 할 경우, this는 counter1을 가리킵니다
  },
  decrease: function() {
    this.value--
  },
  getValue: function() {
    return this.value
  }
}

counter1.increase()
counter1.increase()
counter1.increase()
counter1.decrease()
counter1.getValue() // 2
  • 생성자 호출 예시
    • 객체.메소드( ) 와 같이 객체 내에 메소드를 호출하는 방법(couter1.increase())은 비슷하지만, 해당 객체가 new 키워드를 이용하여 만들어졌다는 점이 다르다. 이 때 만들어진 객체를 우리는 인스턴스라고 부른다. 즉 인스턴트.메소드( ) 의 형태가 된다.
class Counter {
	constructor() {
		this.value = 0; 
}
	increase(){
		this.value++
	}
	decrease(){
		this.value--
	}
	getValue(){
		return this.value
}
}
let counter1 = new Counter( ) // 생성자 호출
counter1.increase() // counter1은 인스턴트가 되고 this가 바인딩된다.
counter.getValue() // 1

 

call, apply 메소드

  • .call 과 .apply 는 함수의 메소드이며, 명시적으로 첫번째 인자를 this 값으로 지정하고 싶을 때 사용한다.

  • 예제 (유사배열?? .? 추가조사필요)

let allDivs = document.querySelectorAll('div'); // NodeList라는 유사 배열입니다.
// allDivs를 this로 지정합니다.
[].map.call(allDivs, function(el) {
  return el.className
})

// allDivs는 유사 배열이므로 map 메소드가 존재하지 않습니다. 
// 그러나, Array prototype으로부터 map 메소드를 빌려와 this를 넘겨 map을 실행할 수 있습니다.et allDivs = document.querySelectorAll('div'); // NodeList라는 유사 배열입니다. // allDivs를 this로 지정합니다. [].map.call(allDivs, function(el) { return el.className }) // allDivs는 유사 배열이므로 map 메소드가 존재하지 않습니다. // 그러나, Array prototype으로부터 map 메소드를 빌려와 this를 넘겨 map을 실행할 수 있습니다.
  • 객체 지향 프로그래밍에서의 예제 (아직 call 과 apply의 차이가 잘 이해되지는 않는다.)

    function Product(name, price) {
      this.name = name
      this.price = price
    }

    function Food(name, price) {
      Product.call(this, name, price)
      // 인자가 많으면 Product.apply(this, arguments) 가 더 유용합니다.
      
      this.category = 'food'
    }

    let cheese = new Food('feta', 5000) // cheess는 Food이면서 Product입니다.
   

bind 메소드

  • .bind .call 과 유사하게 this와 인자들을 바인딩하나, 당장 실행하는 것이 아닌 바인딩된 함수를 리턴한다.

  • fn.bind( this값, 인자1, 인자2, ... ) fn.bind(null, 인자1) 할 경우 this객체는 null이 되고 바로 인자1을 리턴한다.

  • 비동기함수(setTimeout)에서는 항상 window객체가 this로 바인딩되기 때문에 this.printArea.bind(this) 로 원하는 this를 바인딩한다.

  • 이벤트핸들러에서의 사용

    • 이벤트 핸들러에서 이벤트 객체 대신에 다른 값을 전달하고자 할 때 유용
let target = document.querySelector('#target')
let users = ['김코딩', '박해커', '최초보']

users.forEach(function(user) {
  let btn = document.createElement('button')
  btn.textContent = user
  btn.onclick = handleClick.bind(user) // 이렇게 바꿔볼 수 있습니다.
  target.appendChild(btn)
});
  
  
function handleClick() {
  console.log(this) //bind된 user의 값들이 출력된다.
}

 



마무리 Think: 

 그래도 오늘은 3시30분에 모든 학습이 완료되었다. 30분씩 더 빠르게 하다보면 적정시간인 새벽2시 퇴근이 가능해질 것이다. 하하하핳