개발노트/Note

[TIL] JavaScript Function (2022-08-10 내용 이전)

Dahoon06 2022. 9. 8. 14:03
728x90
반응형

이번에 새로 두 분이 입사하셨다.

 

한분이 제이쿼리를 학습하시면서 remove()를 사용하는데 선택한 값이 지워지지 않는다고 질문을 주셨다.

(사내 서베이 솔루션이 제이쿼리로 짜여있어 이 솔루션 한에서는 제이쿼리를 활용하고 있기 때문에 어느정도 제이쿼리를 다룰 줄 알아야한다.)

 

코드는 이러했다.

$(document).ready(() => {
    $('#menu li').click(() => { this.remove(); })
});

로그를 찍어보니 여기서 this 가 window 객체를 가르키고 있었다.

그래서 내가 알려준 코드는 아래와 같다.

$(document).ready(() => {
    $('#menu li').on('click',(e) => {
        const target = e.target
        target.remove();
    });
});

그러다가 arrow function 을 그냥 function으로 사용하니까 this가 원하는 대로 작동한다고 말해주셨다.

 

아.. this가 사용한 함수에 따라 다르지 근데 어떨때 다르게 동작하더라...???

 

this를 사용할 때 함수에 따라서 다르다고는 알고 있었지만 정확하게는 알지 못했기에 설명을 해드리는데 어려움이 있었다.

 

왜.. 나도 정확하게 모르니까...

 

그래서 화살표 함수를 사용할 때의 this는 window 객체를 가져오고 일반 함수로 사용하게 되면 이벤트가 발생된 지점을 가져온다 라고만 설명 해드리고 부랴부랴 검색하기 시작했다.

 

입사한지 1년이 다 돼가는데 이런 내용조차 제대로 대답을 못 해 주었다는게 너무 부끄러워 이번 기회에 자바스크립트 기초에 대해 공부 해보려고 한다.

 

함수 선언


함수 선언에는 2가지 방법이 있다.

// 함수 표현식
const functionExpression = function() {};
// 함수 선언식
function functionDeclaration() {};

1. 함수 표현식: function Expression

2. 함수 선언식: function Declaration

 

차이점은 호이스팅(Hoisting) 에 있다.

 

💡 호이스팅(Hoisting) 이란?

함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 요효 범위의 최상단에 선언하는 것을 말한다.

자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수 값들을 모두 모아서 유효 범위의 최상단에 선언한다.
(즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 위로 끌어올림.)

실제로 코드가 끌어올려지는 것이 아니고, 자바스크립트 Parser 내부적으로 끌어올려서 처리한다.

실제 메모리에 대해서는 변화가 없다.

 

호이스팅은 var 변수 선언함수 선언문에서만 발생되며,

let / const 변수 선언함수 표현식 에서는 호이스팅이 발생되지 않는다.

functionExpression();  // 에러 발생.
functionDeclaration(); // 정상적으로 실행됨.

// 선언 방식 1
const functionExpression = function() {};
// 선언 방식 2
function functionDeclaration() {};

함수 선언식이 호이스팅의 영향을 받기 때문에 에러가 발생된다.

첫번째 선언 방식으로 생성된 함수의 경우에는 변수에 값이 할당되기 전이므로 에러가 발생한다.

 

 

Arrow Function


arrow();
// Arrow function 은 오직 익명 함수
const arrow = () => {};

화살표 함수의 경우에는 익명 함수로써 오직 표현식만 사용할 수 있다.

 

마찬가지로 함수가 선언되기 전에 호출을 하게 되면 에러가 발생하게 된다. (같은 호이스팅 적용)

 

 

this


es5 에서의 this

1. 함수 실행 시 전역(window) 객체를 가리킨다.
2. 메소드 실행 시 메소드를 소유하고 있는 객체를 가리킨다.
3. 생성자를 실행 시 새롭게 만들어진 객체를 가리킨다.

 

 

es6 에서의 this 는 Lexical this 즉, 자신의 둘러싼 환경의 this 를 그대로 계승

function es6Function() {
    console.log('일반 함수 호출 :', this.foo); // 13
    return {
        foo: 25,
        bar: () => console.log('화살표 함수 호풀:', this.foo) // 13
    };
}
es6Function.call({ foo: 13 }).bar();

es5 에서 메소드 호출 시, this 는 메소드를 소유하고 있는 객체를 가리킨다.

 

따라서 this.foo 는 13 을 가리키는데 화살표 함수(arrow function) 에서는 Lexical this 를 가진다.

 

그렇기 때문에 call 메소드 를 통한 간접실행이 일어날 때에는 this 문맥을 그대로 가져와 25가 아닌 13이 호출되는 것을 알 수 있다.

화살표 함수의 this 는 상위 환경의 this 를 계승하므로 전역 객체를 가리키기 때문이다.

 

 

💡 Arrow Function 을 사용할 때 주의할 점

1. this 나 super에 대한 바인딩이 없고, methods로 사용될 수 없다.
2. new.target 키워드가 없다.
3. 일반적인 스코프를 지정할 때 사용하는 call, apply, bind methods를 이용할 수 없다.
4. 생성자를 사용할 수 없다.
5. yield를 화살표 함수 내부에서 사용할 수 없다.

화살표 함수 내에서는 생성자 함수 자체를 사용하지 못한다.

(화살표 함수에는 prototype 프로퍼티가 없기 때문)

 

 

 


728x90
반응형