Javascript_함수 생성 및 호이스팅 & this 바인딩

Minji Jeong·2021년 8월 12일
1

Javascript

목록 보기
3/6
post-thumbnail

1. 함수 생성

함수 선언문 방식

함수 선언문 방식은 리터럴 표기법과 같이 선언하는 방법이다.

리터럴 표기법: 변수를 선언함과 동시에 그 값을 지정해주는 표기법

let height = 140;
let person = {name: "MJ", hobby: "music"}

위의 예시를 보면 리터럴 표기법으로 표현하게 되면 그 변수명이 꼭 정의되어야 한다. 함수 선언문 방식도 마찬가지로, 반드시 함수명이 정의되어 있어야 한다.

// C언어에서 함수를 선언하는 방법
int add(int x, int y) {
    int value = x + y;
    return value;
}
// JS에서 함수를 선언하는 방법
function add(x, y) {
    return x + y;
}

위의 예시를 보면 알 수 있듯, Js에서 함수를 선언하는 방식은 C/C++과는 차이가 있는 것을 볼 수 있다. Js에서는 function이라는 키워드를 명시적으로 사용하고, 매개변수와 리턴값에 변수타입을 따로 기재하지는 않는다. 훨씬 간단해진 느낌이다 😎

함수 표현식 방식

Js에서는 함수도 하나의 값으로 취급이 된다.
따라서 함수도 숫자나 문자열처럼 변수에 할당하는 것이 가능하다.
위에서 설명한 방법처럼 함수 리터럴로 함수를 만들고, 이렇게 생성한 함수를 변수에 할당하는 것을 함수 표현식이라고 한다.

let add = function(x, y) {
   return x + y;
}

위의 예시를 보면 함수명이 없다! 이런 경우를 익명함수라고 한다.
여기서 주의할 점은,
add는 생성한 함수를 참조하는 변수이지, 함수의 이름이 아니라는 것이다.
따라서 "add라는 함수"라고 부르는 것 보다는 "add함수 변수"라고 부르는 편이 좋을 것 같다 😁

2. 함수 호이스팅(Function Hoisting)

Js에서 함수를 생성하는 방법은 다양하다. 코드는 달라도, 모두 같은 기능을 하는 함수가 된다. 하지만 표현 방식에 따라서 동작하는 방법에는 조금씩 차이가 있는데, 그 중 하나가 '함수 호이스팅'이다.

add(5, 6);	// 11

// 함수 선언문 방식으로 정의
function add(a, b) {
   return a + b;
}

add(2, 3);	// 5

위의 예시를 보자.
함수 선언문 방식으로 함수를 선언했다.
맨 윗 줄 add(5, 6)은 함수가 먼저 정의되지 않았는데도 아래에 정의된
add() 함수를 호출하여 정상적으로 작동하는 것이 가능하다.

함수 선언문 형태로 정의한 함수는, 자신이 정의된 곳에 상관없이
코드의 맨 처음부터 유효범위가 시작된다는 것을 알 수 있다.
🚩 이게 바로 함수 호이스팅!

이렇게 함수 호이스팅은 함수를 사용하기 전에 반드시 선언해야 한다는 규칙에 어긋나므로, 코드의 구조가 뒤죽박죽되는 문제가 발생한다.

add(5, 6);	// uncaught type error

// 함수 표현식 방식으로 정의
let add = function(a, b) {
   return a + b;
}

add(2, 3);	// 5

이렇게 함수 표현식 방식으로 정의하면, 함수 호이스팅으로 인한 문제가 발생하지 않는다. 함수 호이스팅이 발생하는 원인은 자바스크립트의 변수 생성과 초기화 작업이 분리돼서 진행되기 때문이다. 자세한 내용은 실행 컨텍스트에 대해서 공부한 후, 따로 글을 쓸 예정이다 📖

3. this 바인딩

자바스크립트에서 함수를 호출할 때, 매개변수로 전달되는 인자값과 함께
arguments 객체와 this 인자가 암묵적으로 전달된다.
this는 함수 호출 방식에 따라 다른 객체를 참조하기 때문에 공부하고 넘어갈 필요가 있다✍

객체의 메서드를 호출할 때

객체의 property가 함수인 경우, 그 함수를 메서드라고 부른다. 메서드를 호출할 때, 메서드 내부에서 사용된 this는 해당 메서드를 호출한 객체로 바인딩된다.


코드를 보면 objectA에서 property로 추가한 sayName() 함수를 objectB에도 똑같이 만든 것을 볼 수 있다. 하지만, objectB.sayName()은 A가 아닌 B값을 출력하였다.

objectA.sayName()에서 this.name = objectA.name이고,
objectB.sayName()에서 this.name = objectB.name이 된 것이다.
❗ sayName() 메서드의 this가 자신을 호출한 객체에 바인딩 되었다는 증거

함수를 호출할 때

자바스크립트에서는 함수를 호출하면,
함수 내부에서 사용된 this가 전역 객체에 바인딩된다.

js를 브라우저에서 실행하는 경우 -> 전역객체는 window
js를 런타임 환경에서 실행하는 경우 -> 전역객체는 global

브라우저 환경에서 코드를 테스트 해보기 위해 Chrome 개발자모드 콘솔창에 코드를 작성해 보았다.

test라는 전역변수를 선언했다. js 전역변수는 전역객체 window의 프로퍼티로 접근 가능하기 때문에, window.test로 결과값을 찍어보았다.

자바스크립트에서 함수를 호출할 때 this는 전역 객체인 window에 바인딩된다. 따라서 this.test = window.test가 되고, This is test를 출력하게 되는 것이다.

profile
쿼카를 사랑하는 프론트엔드 개발자입니다 :)

0개의 댓글