🐯
경민민 IT 핸드북
  • Orientation
    • 전달사항
    • 복습방법
    • 수료한 선배의 한마디
    • 간단 자기소개
    • 스터디
  • 백엔드
    • Java
      • 1장 프로그래밍 기초
      • 2장 자바 메모리구조
        • 1. Stack
        • 2. Heap
      • 6장 객체
      • 8장 상속
      • 9장 다형성
      • 10장 추상클래스와 인터페이스
      • 13장 Generic
      • 14장 Thread
      • 15장 Network
      • 16장 Lamda
        • 1. 내부 클래스 (Inner Class)
          • DTO , VO, Builder Pattern
        • 2. 람다 표현식 (Lambda Expression)
        • 3. 스트림 API (Stream API)
          • Optional
      • 17장 Enum
  • 프론트
    • Node.js
    • Java Script
      • ES6+
        • Node.js로 자바스크립트 실행
        • let , const , var
        • Destructuring문법
          • Rest(...) 문법
        • Arrow Function
        • 모듈
        • ETC
    • Type Script
      • 개요
      • TS설치 및 환경설정
      • 타입스크립트 기본
        • 기본 자료형들과 타입추론
        • Object, Array , Tuple
        • Any, Unknown, Union Type
        • Function Type
          • Type Assertion && Narrowing
          • Never type
        • Type Aliases와 Interface
        • 리터럴 타입
        • 함수 추가 문법
        • Class문법
        • 객체 타입 추가 문법
        • 실습문제 1차
        • 실습문제 2차
        • 실습문제 3차
    • React
      • 개요
      • SPA 와 MPA
        • SEO(작성예정)
      • 리액트 프로젝트 생성(18.3.1.ver)
        • HTML + react 샘플
        • CRA 와 Vite 비교
      • 리액트 개념들
        • Component
          • 클래스 컴포넌트(작성예정)
          • 함수형 컴포넌트(작성예정)
        • JSX
        • React Virtual Dom
          • Reconciliation
        • hook
          • useState
        • 리액트 데이터 전달
          • FLUX
      • 백엔드 서버 연동
        • 비동기요청
        • 웹소켓
        • Promise(작성예정)
      • 실습문제 1
      • 실습문제 2
      • 실습문제3
      • 실습문제4
  • 프레임워크
    • Spring
      • Spring 개발환경 구축
        • 프로젝트 환경설정
        • 프로젝트 생성
          • MVC Project 생성이슈
        • Maven 설정
        • web.xml 설정
        • Spring Bean Configuration.xml 설정
      • Spring Legacy Project
        • Spring 요청 및 응답 흐름
        • Spring 주요 Annotation
          • 의존성 주입방식의 차이점
          • @ModelAttribute와 유효성검사
          • 비동기처리
          • 스프링 예외처리
        • Logging
        • Pagination
        • Spring File 업로드 및 다운로드
        • Spring WebSocket
        • Spring AOP
      • Spring 라이브러리들(작성예정)
        • Lombok
        • Maven
        • MyBatis
      • Spring 구성 모듈(작성예정)
      • 스프링 과제
    • Spring Boot
      • Spring Boot 개발환경 구축
      • 스프링 부트 프로젝트 생성방법들
        • 프로젝트에서 사용하는 의존성들
      • 스프링 프로젝트 구조
        • SpringBootApplication
      • application.properties
      • Cross Origin
        • CORS
      • WebSocket
        • Stomp(작성중)
      • 로그인(작성중)
      • Spring Security(작성중)
      • 실습문제 Select
      • 실습문제 Update
      • 실습문제 Delete
  • 형상관리(Git)
    • GitHub설정
    • SourceTree를 활용한 깃허브 연동
      • 소스트리 설치
      • Clone
      • Branch
        • Branch Protection rules
          • Branch Protection Rules 상세규칙
        • Rebase 와 Squash (작성예정)
      • Team Project 설정
        • 팀장 프로젝트 셋팅
          • Collaborator
          • .gitignore 설정
        • 팀원 프로젝트 셋팅
        • 공통 프로젝트 진행
  • 프로젝트
    • 진행순서
      • 요구사항 분석 단계
        • 유용한 사이트
      • 프로그램 설계 단계
        • 유용한 사이트
      • 프로그램 구현단계
        • SourceTree를 활용한 Team Project설정
      • 테스트 단계
  • 배포
    • AWS-EC2 배포 연습
    • DevOps
      • IT시스템의 변화와 DevOps
      • DevOps 라이프사이클
    • 젠킨스
      • 도커
        • 도커 설치 방법
        • 도커 기본 명령어들
      • 젠킨스 설치
      • 젠킨스 프로젝트 생성
      • 젠킨스 소스코드 통합 - Github
      • 젠킨스 빌드 설정 - Maven
      • 배포 서버 구축하기
      • 파이프라인 구축
      • AWS 서버 생성
        • AWS 인스턴스 생성
        • AWS - Zenkins 연동
        • AWS - 배포서버 연동
        • AWS - Jenkins CI/CD파이프라인 구축
  • 유용한 사이트 모음
  • SQL
    • SQLD
      • 데이터 모델링의 이해 - 스키마
      • 데이터 모델링의 이해 - ERD
      • 데이터 모델링의 이해 - 정규화
      • 데이터 모델링의 이해 - NULL
      • SQL 기본 및 활용 - WINDOW FUNCTION
    • Oracle
      • 1장 개요
      • 2장 SQL
  • LLM 서비스
    • 1장 LLM에 대한 이해
    • 2장 프롬프트 엔지니어링
      • 프롬프트와 프롬프트 엔지니어링
      • GPT PlayGround
      • 프롬프트 작문 유형
      • 기본 프롬프트 엔지니어링 태크닉
      • 고급 프롬프트 엔지니어링 태크닉
        • ReAct Prompting
        • Active-Prompt
        • Reflexion
        • Graph Prompt
      • OpenAI API설정
      • OpenAI를 활용한 프롬프트 엔지니어링 실습
        • 실습 프롬프트
    • 3장 Lang Chain 프레임워크
      • LangSmith 프레임워크
        • LangSmith를 활용한 LangChain 모니터링 설정
      • LangChain 실습 1 - Prompt
        • 실습 코드
      • LangChain 실습 2 - LLM 캐시와 메모리
    • 4장 RAG
      • Document Loader - 문서 로더
      • Text Splitter - 텍스트 분할
      • Embedding - 임베딩
      • Vector Store - 벡터 저장소
      • Retriever - 검색기
      • ReRanker - 재평가자
      • RAG
Powered by GitBook
On this page
  • 화살표 함수 선언방법
  • this바인딩
  • 일반 함수의 this
  • 화살표 함수의 this
  • 사용처
  • 콜백함수
  • 일반함수의 정적 this바인딩
  1. 프론트
  2. Java Script
  3. ES6+

Arrow Function

화살표 함수 선언방법

화살표함수는 es6에서 추가된 기능으로 선언적 함수를 좀더 간결할 방식으로 정의할 수 있도록 해주는 문법입니다. 화살표 함수 이전 함수의 선언 방식은 다음과 같습니다.

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

위 함수를 화살표 함수 방식으로 변경하면 다음과 같습니다.

//1
const declareFn = (a, b) => {return a*b;}

//2 {}내부의 코드가 return문 뿐이라면 {return} 생략 가능.
const declareFn = (a,b) => a*b; 

//3. 매개변수가 1개뿐이라면 매개변수의 괄호도 생략 가능.
const declareFn = a => a;

화살표 함수는 함수를 값으로써 표현한 것이기 때문에 위처럼 변수에 값을 대입해 주셔야 합니다. 이때 변수의 선택지는 let , const, var 3가지가 있지만 const를 사용하는 것이 안전합니다. let이나 var로 함수값을 저장하게 되면 담긴 값이 바뀔 수가 있는데 const로 대입하게 되면 함수의 불변성을 유지시켜주기 때문입니다.

this바인딩

화살표 함수는 선언적 함수를 간결하게 표현한 문법임과 동시에 독특한 방식의 this binding 규칙이 존재합니다. this바인딩에 대해서 제대로 이해하지 못한다면 화살표 함수는 차라리 사용하지 않는게 좋을 수 있습니다.

일반 함수의 this

this는 함수에서 사용가능한 키워드로 해당 함수를 호출한 객체가 바인딩 됩니다. 아래 코드예시를 살펴보겠습니다.

function callableFn(){
    console.log(this);
}
callableFn(); // ?

위 함수를 브라우저상에서 실행해본다면 window객체가, node.js상에서 호출해본다면 global객체가 this에 바인딩 될것입니다. callableFn이라는 함수를 호출하는 주체가 없기 때문에 각 플랫폼의 최상위 객체가 자동으로 바인딩 된 것이죠.

그럼 위 함수를 호출하는 주체를 추가해 보도록 하겠습니다.

const obj1 = {
    name : '객체1',
    callableFn : callableFn
}
const obj2 = {
    name : '객체2',
    callableFn : callableFn
}
obj1.callableFn(); //?
obj2.callableFn(); //?

위 코드에서 call속성의 속성값으로 동일한 callableFn을 저장시켜두고 있습니다. 즉 동일한 함수인 것이죠. 하지만 동일한 함수를 서로 다른 객체에서 호출할 때는 호출하는 주체가 바뀌게 되므로 this에는 해당 메서드를 호출한 주체가 바인딩 됩니다. obj1이 호출하면 obj1이 obj2가 호출하면 obj2가 this에 바인딩 됩니다.

화살표 함수의 this

화살표 함수에는 this라는 값이 존재하지 않습니다. 자바스크립트는 현재 스코프에 내가 찾고자 하는 값이 없는 경우 상위스코프로 올라가면서 값을 찾아 나갑니다. 따라서 화살표 함수의 this는 함수가 처음 선언된 영역을 기반으로 상위 스코프의 this값이 바인딩 됩니다.

그래도 무슨말인지 모르겠죠. 확인해보겠습니다.

const arrowFn = () => {
    console.log(this.name);
}
arrowFn(); //1번

const obj3 = {
    name : '객체3', 
    arrowFn
}
obj3.arrowFn(); // 2번

위 두 코드에서 this에는 모두 전역객체가 바인딩 됩니다. 1번 코드는 이해가 갈것이나 2번 코드는 이해가 안가죠? 명확하게 arrowFn함수를 실행하는 주체가 있는데도 불구하고 obj3 객체가 바인딩 되지 않습니다.

왜냐면 arrowFn이 선언된 영역에서 this의 상위 스코프는 global이기 때문입니다. 화살표 함수는 이렇게 호출되는 주체에 따라 this값이 변경되지 않고 함수가 처음 정의된 환경에 따라갑니다. 즉 this값이 고정된다는 것입니다.

자세히 살펴보겠습니다.

const obj4 = {
    name : '객체4',
    arrowFn : function(){
        const getName = () => {
            return this.name
        } 
        const getName2 = function() {
            return this.name
        } 
        console.log(getName()); // ?
        console.log(getName2()); // ?
    }
}
obj4.arrowFn();

getName함수를 먼저 봅시다. getName함수는 obj4객체의 arrowFn 메서드 내부에서 선언되었습니다. 즉 getName함수의 외부는 obj객체라고 할 수 있겠군요. 화살표 함수의 this는 항상 상위 스코프(함수밖)의 this값에 바인딩 되므로 getName함수를 호출했을때 this.name에는 '객체4'값이 반환될것입니다.

다음으로 getName2함수를 확인해 보겠습니다. getName2함수는 익명함수입니다. 익명함수는 화살표 함수와 다르게 this값이 동적으로 결정됩니다. 즉 함수를 호출하는 객체가 누구냐에 따라 달라진다고 할 수있죠. 위 코드에서 getName2를 호출하는 객체가 없으므로 최상위 객체가 바인딩 되겠네요.

사용처

화살표 함수를 배웠으니 이제 모든 함수는 화살표 함수로 만들어서 사용해야겠네요. 가독성 좋고 뭔가 this의 문제를 해결한것 같으니까요. 그쵸? 아닙니다.

화살표 함수가 기존 일반함수를 완전히 대체할 수는 없습니다. 각 함수생성방법이 가지는 특징에 대해 잘 이해하고 상황별로 올바른 함수를 작성하시는게 중요하죠. 각 함수의 특징에 대해서는 배워봤으니 this가 사용되지 않는 단순 함수에서 코드를 간결하게 줄이고 싶을 때나 this를 현재 함수가 아닌 상위 스코프의 this로 바인딩 시켜야 하는 경우에는 화살표 함수를. 그 밖에 동적으로 바뀌는 this값(생성자함수, 객체의 메서드)을 가져야 하는 함수에서는 일반함수 방식으로 코드를 짜주셔야합니다.

헷갈리면 사실 무조건 일반함수 방식으로 만드는 방법도 있습니다. 일반함수방식으로 생성된 함수에 this값을 특정 객체로 고정시켜버리는 방법도 있거든요. 다만 가독성이 나쁘고 사용방법도 복잡하기 때문에 일반적으로 화살표 함수 사용하는걸 선호합니다. 그 이유에 대해 알아보도록하죠.

콜백함수

콜백함수에 대해서는 다들 아실겁니다. 매개변수로 전달된 후 다른 함수에 의해 호출되는 함수를 콜백함수라고 부르죠. 아래 코드를 살펴보겠습니다.

const obj5 = {
    name  : '객체5',
    fn : function (callback){
        callback();
    },
    call : function(){ 
        this.fn(()=>{ // 콜백함수
            console.log(this.name); // ?
        })
    }
}
obj5.call();

위 코드예시를 보면 call메서드 내부에서 fn함수의 매개변수로 작성하는 값이 함수표현식으로 작성된 콜백함수 입니다. 콜백함수는 내가 콜백함수를 전달한 다른 메서드의 내부에서 호출됩니다. fn 메서드의 내부를 보시면 매개변수로 callback함수를 전달하였고 바로 호출하고 있습니다. 이때 주목할만한 부분은 함수를 호출하는 주체가 없다는 것입니다. 이런경우 this에는 최상위객체가 바인딩 됨을 배웠습니다. 하지만 화살표 함수를 통해 값을 전달 했으므로 this에는 항상 정적으로obj5객체가 바인딩됩니다.

일반함수의 정적 this바인딩

함수를 호출하는 방법에 대해서는 다들 알고 계실겁니다. 함수 호출 연산자(function call operator)를 사용하는거죠. 함수호출 연산자는 ()를 의미합니다.

const obj7 = {
    name : '객체7',
    callableFn : function(){
        console.log(this.name)
    }
}

위 obj7의 함수를 호출하는 방법은 3가지입니다.

첫번째는 함수 호출 연산자를 이용하는 것이죠.

obj7.callableFn();

두번째는 Function의 call함수를 이용하는 것입니다. call함수는 this로 바인딩 시킬 객체를 함수의 첫번째 매개변수로 직접 전달 한 후 함수를 호출(call)하는 역할을 합니다.

obj7.callableFn.call(obj1);

위와 같이 call함수의 매개인자로 obj1객체를 넘기게 되면 실행시 obj1이 this가 됩니다.

세번째는 Function의 apply함수를 이용하는 것입니다. appy함수는 call과 동일하게 this로 바인딩 시킬 객체를 함수의 첫번째 매개변수로 직접 전달한 후 함수를 호출하는 역할을 합니다. call과의 차이점은 두번째 매개변수로 받는 인자가 ...을 사용하느냐 배열을 사용하느냐 입니다. 두번째 매개변수는 사용하지 않으므로 넘어가도록 하겠습니다.

obj7.callableFn.apply(obj1);

함수를 호출하지는 않은 상태로this만 미리 정적으로 바인딩 시켜두는 방법도 있습니다. 바로 Function의 bind 메서드를 이용하는 것입니다. bind메서드는 call과 apply에서 함수를 호출하는 기능만 쏙 빼고 this를 바인딩 시키는 기능만 추가된 함수입니다.

obj7.callableFn.bind(obj3)();

apply , call의 차이점은 아래 문서를 확인하세요.

PreviousRest(...) 문법Next모듈

Last updated 10 months ago

Function.prototype.call() - JavaScript | MDNMDN Web Docs
Logo