본문 바로가기

배운 것/js

[js] arrow function 의 this

function 키워드로 생성한 일반 함수와 화살표 함수의 가장 큰 차이점은 this이다.

 

 

1. 일반 함수의 this : 이벤트 리스너 예제

const button = document.querySelector("button");

button.addEventListener("click", function(){
	console.log(this) // button 콘솔에 찍힘
});

 

- 일반 함수의 경우 바인딩할 객체를 기준으로 this가 존재했다.

 

 

2. 화살표 함수의 this : 이벤트 리스너 예제

const button = document.querySelector("button");

button.addEventListener("click", () => {
	console.log(this) // window가 찍힘
});

 

- 화살표 함수의 this는 전역 객체인 window를 가르킨다.

 

즉, 화살표 함수는 this 바인딩을 하지 않는다.

 

 

3-1. 또 다른 예제 : 일반 함수의 this

const obj = {
  a () {
    console.log(this);
    const b = function () {
    	console.log(this);
  	}
  	b();
  }
}

obj.a(); 

// 콘솔창 결과값은
// {a:f}
// window{...}

 

- 위의 경우 첫번째 콘솔의 this는 obj를 의미하고 두번째 콘솔의 this는 window 전역객체를 바인딩한다.

 

3-2. 또 다른 예제 : 화살표 함수의 this

const obj = {
  a () {
    console.log(this);
    const b = () => {
    	console.log(this);
    }
  	b();
  }
}

obj.a(); 

// 콘솔창 결과값은
// {a:f}
// {a:f}

 

- 그런데 const b 를 arrow 함수로 바꾸면 첫번째 콘솔과 같은 this를 의미한다.

 

왜냐, arrow 함수는 this 바인딩을 하지 않기 때문에 외부 스코프인 a() 에서 this를 찾기 때문이다.

 

 

+ 번외

3-1에서 함수 b의 this를 a함수와 같은 걸 바라보고 싶을 때 방법들은 아래와 같다.

* call로 this 호출하기
const obj = {
	a () {
    	console.log(this);
        const b = function () {
        	console.log(this);
        }
        b.call(this);
    }
}

obj.a(); 

// 콘솔창 결과값은
// {a:f}
// {a:f}


* 특정 변수에 this를 담아서 사용하기
const obj = {
	a () {
    	var self = this;
    	console.log(this);
        const b = function () {
        	console.log(self);
        }
        b();
    }
}

obj.a(); 

// 콘솔창 결과값은
// {a:f}
// {a:f}

 

 

4. 화살표 함수는 함수 스코프를 갖는다

const a = function () {
	var x = 10;
}
a();

console.log(x)

// x is not defined

- var 는 함수 스코프에 갇히기 때문에 a 함수 실행 결과는 x 값을 찾지 못한다.

 

 

const a = () => {
	var x = 10;
}
a();

console.log(x)

// x is not defined

- 화살표 함수 역시 같은 결과를 내는데 이 말은 곧, 화살표 함수는 기존 함수와 똑같이 함수 스코프를 갖는다.

 

 

 

5. 화살표 함수는 메소드로서의 기능보다는 함수로서의 기능을 한다

const b = {
	name : '하하',
    bb () {
    	return this.name;
    }
}

b.bb();

// 콘솔 결과 "하하"

- 객체에서 메소드로 사용하려면 위와 같은 축약형으로 사용해야 한다.

 

const b = {
	name : '하하',
    bb () {
    	return this.name;
    },
    a : x => {
    	return this.name
    }
}

b.bb();
// 콘솔 결과 "하하"

b.a();
// 콘솔 결과 ""

- 객체의 메소드는 b 라는 객체(나)를 바라보기 위해서 사용하는 건데 화살표 함수는 this 바인딩을 하지 않기 때문에 위와 같은 코드 방식은 올바르지 않다.

 

3-2 예제와 같이

const b = {
	name : '하하',
    bb () {
    	const b = x => {
        	return this.name;
        }
        console.log(b())
    },
}

b.bb();
// 콘솔 결과 "하하"

- 화살표 함수는 메소드 안에서 같은 this를 갖고 사용할 때, 즉 내부 함수로서 사용한다. b.bb()를 실행하면 그 안에 있는 내부 함수인 b가 실행이 될 거고 내부 함수 b의 this는 bb 함수가 보고 있는 this를 보기 때문에 원하는 콘솔 결과가 나온다.