17일차 - 2022.03.17

안병욱·2022년 3월 17일
0

오늘 공부한 내용 요약

( 모던 JavaScript 튜토리얼 학습 )

1. 함수 바인딩

객체메서드를 전달할 때 this정보가 사라지는 경우가 있음
객체 내부가 아닌 외부에 전달되어 호출되는 경우에도 this가 사라짐

let user = {
  firstName: "John",
  sayHi() {
    alert(`Hello, ${this.firstName}!`);
  }
};

setTimeout(user.sayHi, 1000); // Hello, undefined!

마지막 줄은 let f = user.sayHi; setTimeout(f, 1000); 와 같은결과로 sayHi가 sayHi()가 아니기에 user 컨택스를 잃어버리기 때문임.



  • 메서드를 전달할때 컨텍스트도 제대로 유지하려면

방법 1) 래퍼
기존 함수를 한번 감싸주는 래퍼함수를 이용

let user = {
  firstName: "John",
  sayHi() {
    alert(`Hello, ${this.firstName}!`);
  }
};

setTimeout(function() {
  user.sayHi(); // Hello, John!
}, 1000);

밑부분은 setTimeout(() => user.sayHi(), 1000); 와 같음

그러나 위의 방법의 경우 1초가 지나기 전에 user가 변경되면 변경된 객체의 메서드를 호출하게 됨.


방법 2) bind
모든 함수는 this를 수정하게 해주는 내장 메서드 bind를 제공

기본 문법

let boundFunc = func.bind(context);

예시

let user = {
  firstName: "John",
  sayHi() {
    alert(`Hello, ${this.firstName}!`);
  }
};

let sayHi = user.sayHi.bind(user); // (*)

sayHi(); // Hello, John!

setTimeout(sayHi, 1000); // Hello, John!

user = {
  sayHi() { alert("또 다른 사용자!"); }
};

1초 이내에 user 값이 변경되도 sayHi는 기존값을 사용
이제 객체 없이도 객체 메서드를 호출할 수 있게 됨


  • 부분 적용

this 뿐만 아니라 인수도 바인딩 가능

기본 문법

let bound = func.bind(context, [arg1], [arg2], ...);

곱셈 함수로 예시

function mul(a, b) {
  return a * b;
}

let double = mul.bind(null, 2);

alert( double(3) ); // = mul(2, 3) = 6
alert( double(4) ); // = mul(2, 4) = 8

위에선 this를 사용하지 않았는데 컨텍스트를 남겨야 해서 null사용
첫 인수를 2로 고정하고 이후 인수를 전달(이걸 부분 적용이라 함)

부분적용은 가독성 좋은 이름을 가진 독립함수를 만들 수 있고 인수 하나를 고정해 매번 전달 안해도 되게 해줌



2. 화살표 함수 다시 살펴보기

자바스크립트에서는 함수를 만들고 어딘가에 전달하는것이 자연스러움
전달하는 함수의 컨텍스를 잃을수도 있는데 이걸 해결해주는것이 화살표함수.


  • 화살표 함수에는 this가 없다

본문에서 this에 접근하면 외부 렉시컬 환경에서 값을 가져오게 됨

let group = {
  title: "1모둠",
  students: ["보라", "호진", "지민"],

  showList() {
    this.students.forEach(
      student => alert(this.title + ': ' + student)
    );
  }
};

group.showList();

여기서 this.title은 group.title과 같다.

위의 함수에서 화살표 함수가 아닌 일반함수를 사용했다면
함수의 this가 undefined 여서 오류가 발생했을 것

showList() {
    this.students.forEach(function(student) {
      // TypeError: Cannot read property 'title' of undefined
      alert(this.title + ': ' + student)
    });

하지만 화살표함수는 this 자체가 없기에 이런 오류는 발생하지 않는다


  • 화살표 함수는 this가 없기에 생성자 함수 사용 불가
    즉 new와 함께 실행할 수 없음

  • 화살표함수는 모든인수에 접근할수 있게 해주는 유사배열객체인 argument도 없음


( Core JavaScript 기본서 )

undefined 와 null

자바스크립트에는 '없음'을 나타내는 undefined와 null이 있다.


  1. undefined

사용자가 지정할 수도 있지만 값이 존재하지 않을때 자동으로 부여되는 경우도 있다. 이 경우는 3가지로 볼 수 있는데 각각

  • 값을 대입하지 않은 변수에 접근시
  • 객체 내부에 존재하지 않는 프로퍼티에 접근시
  • Return 문이 없거나 호출되지 않은 함수의 실행결과

예시로 알아보면

let a;
console.log(a);     // undefined   첫번째 경우 


let a = {b:1};
console.log(a.c);   // undefined   두번째 경우 


let a = function() {};
let b = a();        //  undefined   세번째 경우 

그밖에

let a = [];
a.length = 2;
console.log(a);     //   [empty × 3] 

값이 지정되지 않은 인덱스는 아직은 존재하지 않는 프로퍼티이다.

사용자가 undefined을 부여한 경우는 하나의 값으로 동작하기에 고유의 키값이 존재하지만 (실존하는 데이터)
비어있는 요소에 접근할 때는 키값 자체가 존재하지 않음


  1. null

이런 혼란을 피하기 위해 직접 undefined를 할당하는 경우는 많지 않게 하면됨
비어있음을 나태내려면 이러한 용도를 목적으로 만들어진 null값을 사용하면 됨.

null 값을 사용시 자료형이 object임에 주의.

공부 출처

자바스크립트.info
코어 자바스크립트 -정재남 지음 -


위의 내용은 공부중 본인이 이해한 내용으로 몇몇 틀린 내용이 있을 수 있습니다.
회독중 발견시 수정하겠습니다

profile
working hard

0개의 댓글