티스토리 뷰

스터디/하브루타 스터디

4. 함수

곤이씨 2021. 4. 18. 16:08

내 질문에 대한 정리

Q1. 함수의 매개변수는 최대 몇개까지 두는 것이 이상적일까요? 만약 그 이상의 매개변수가 필요한 경우에는 어떤 식으로 해결하시는 편인가요?

매개변수가 많은 함수라면 이 함수가 하나의 동작만을 하고 있는 것인지 확인할 것 같다. 쪼갤 수 있다면 쪼갠다. 객체로 묶는 것도 좋다. 하지만 매개변수가 많지 않고 매개변수의 성격이 다르다면 객체로 묶는 것이 무조건 좋다고 할 수 없을 것 같다. 최근에는 코드 에디터가 함수 매개변수에 대한 힌트를 제공하기 때문에 꼭 객체로 묶을 필요는 없을 것 같다.

Q2. 리액트에서 함수형 컴포넌트를 선언할 때, 함수 선언문과 함수 표현식으로 작성할 수 있는데 차이가 있을까요?

  • 자바스크립트 함수 선언문과 함수 표현식의 차이만 존재하는 듯 하다. 리액트 공식문서에서도 두 가지의 방법으로 함수형 컴포넌트를 사용할 수 있다고 나와있다.

Using the State Hook - React

Q3. 함수와 클래스의 차이는 무엇이 있을까요? 그리고 함수와 메서드는 어떤 차이가 있을까요? 함수와 클래스를 사용하는 상황에 대해서 이야기를 나눠보면 좋을 것 같아요 :)

일반 함수와 클래스의 차이

  • 클래스는 호이스팅이 되지 않는다.
  • 클래스를 new 연산자 없이 호출하면 에러가 발생한다. 하지만 생성자 함수를 new 연산자 없이 호출하면 일반 함수로서 호출된다.
  • 클래스는 상속을 지원하는 extends와 super 키워드를 제공한다. 하지만 생성자 함수는 제공하지 않는다.
  • 클래스는 호이스팅이 발생하지 않는 것처럼 동작한다. 하지만 함수 선언문으로 정의된 생성자 함수는 함수 호이스팅이, 함수 표현식으로 정의된 생성자 함수는 변수 호이스팅이 발생한다.
  • 클래스 내의 모든 코드에는 암묵적으로 strict mode가 지정되어 실행되며 strict mode를 해제할 수 없다. 하지만 생성자 함수는 암묵적으로 strict mode가 지정되지 않는다.
  • 클래스의 contrustor, 프로토타입 메서드, 정적 메서드는 모두 프로퍼티 어트리뷰트 [[Enumerable]]의 값이 false다. 다시 말해, 열거되지 않는다.

함수와 메서드의 차이

  • 함수는 독립적으로 정의되어 이름만으로도 호출이 가능하다. 반면 메서드는 이름만으로는 호출되지 않는다.
  • 메서드는 클래스 내에서 정의되므로 해당 클래스에 종속된다.
  • 함수가 메서드보다 더 포괄적인 의미를 가진다.
  • 자바스크립트에서 메서드(method)는 객체의 속성인 함수이다. (출처: MDN)
  • ES6 사양에서 메서드는 메서드 축약 표현으로 정의된 함수만을 의미한다.
  • ES6 사양에서 정의한 메서드는 인스턴스를 생성할 수 없는 non-constructor다. 따라서 ES6 메서드는 생성자 함수로서 호출할 수 없다.
  • ES6 메서드는 자신을 바인딩한 객체를 가리키는 내부 슬롯 [[HomeObject]]를 갖는다. super 참조는 내부 슬롯 [[HomeObject]]를 사용하여 수퍼 클래스의 메서드를 참조하므로 내부 슬롯 [[HomeObject]]를 갖는 ES6 메서드는 super 키워드를 사용할 수 있다.

브랜 질문에 대한 정리

Q1. 실행 컨텍스트와 this가 결정되는 시점은 언제일까요? this는 왜 고정되어 있지 않고 호출 환경에 따라 달라져서 괴롭힐까요?

this란?

  • this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수다. this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
  • this는 자바스크립트 엔진에 의해 암묵적으로 생성되며, 코드 어디서든 참조할 수 있다. 함수를 호출하면 arguments 객체와 this가 암묵적으로 함수 내부에 전달된다. 함수 내부에서 arugments 객체를 지역변수처럼 사용할 수 있는 것처럼 this도 지역 변수처럼 사용할 수 있다.
  • 단, this가 가리키는 값, 즉 this 바인딩은 함수 호출 방식에 의해 동적으로 결정된다.

실행 컨텍스트

  • 자바스크립트 엔진은 먼저 전역 코드를 평가하여 전역 실행 컨텍스트를 생성한다. 그리고 함수가 호출되면 함수 코드를 평가하여 함수 실행 컨텍스트를 생성한다.
  • 생성된 실행 컨텍스트는 스택 자료구조로 관리된다. 이를 실행 컨텍스트 스택이라고 한다.
  • this가 결정되는 시점은 함수 실행 컨텍스트가 실행되고 함수 환경 레코드의 [[ThisValue]] 내부 슬롯에 this가 bind 될 때이다. this는 함수 호출 방식에 따라 결정된다.

Q2. 유사배열인 NodeList에서 배열의 메서드인 map을 사용하려면 어떻게 해야할까요? 배열로 변환하지 않고 map을 사용할 수 있는 방법이 있을까요?

  • NodeList의 prototype에 Array.prototype.map을 추가한다. (하지만 이러한 방법은 나중에 자바스크립트의 스펙이 바뀌면서 사이드 이펙트가 발생할 수 있으므로 비추천)
// 1. prototype 추가
const $numbers = document.querySelectorAll('.number');
console.log((NodeList.prototype.map = Array.prototype.map));
console.log($numbers.map(number => console.log(number)));

// 2. call 사용
Array.prototype.map.call($$('.number'), (number) => console.log(number));

Q3. 일반 함수와 화살표 함수는 어떤 차이가 있을까요?

1. this value

  • 일반 함수: 함수가 호출되는 시점에 동적으로 this가 결정됨
  • 화살표 함수: 화살표 함수는 함수 자체의 this 바인딩을 갖지 않는다. 화살표 함수 내부에서 this를 참조하면 상위 스코프의 this를 그대로 참조한다.

2. Constructors

  • 일반 함수: 생성자가 존재함
  • 화살표 함수: 생성자가 존재하지 않음

3. arguments Objects

  • 일반 함수: arguments Objects가 존재함
  • 화살표 함수: arguments Objects가 존재하지 않음. rest parameter를 인자로 대신할 수 있음.

4. Implicit return

  • 일반 함수: 의도한 리턴값이 있는 경우에는 명시적으로 리턴을 해줘야 한다. 리턴값을 입력하지 않으면 undefined가 리턴된다.
  • 화살표 함수: 일반 함수와 동일하지만 화살표 뒤에 중괄호를 사용하지 않고 표현식을 하나만 사용하면 암묵적으로 표현식의 결과값이 리턴된다.

5. Method

  • 일반 함수: 메서드 내부의 중첩 함수 또는 콜백 함수의 this가 불일치 하는 문제를 해결하기 위해 bind를 사용해야한다.
  • 화살표 함수: 스코프 체인을 통해 상위 스코프의 this를 참조하기 때문에 bind를 사용하지 않아도 된다.
  • 5 Differences Between Arrow and Regular Functions

+) 기타 인사이트

콜백 함수

  • 함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수

고차 함수

  • 변수를 통해 함수의 외부에서 콜백 함수를 전달받은 함수

 

 

일급 객체의 성질

  • 변수나 데이터에 저장
  • 함수의 인자로 전달 가능
  • 함수를 반환할 수 있음

'스터디 > 하브루타 스터디' 카테고리의 다른 글

6. This  (3) 2021.05.02
5. 변수와 데이터  (0) 2021.04.25
3. 비동기  (1) 2021.04.12
2. CSS selector  (0) 2021.04.04
1. 이벤트  (0) 2021.04.04