this
, spread operator, 비구조화 할당, arrow function오늘은 ES6의 여러가지 신규 문법을 알아보면서, 가장 많이 혼동하는 부분인 this
에 대해서 정리하려고 했다.
정리하려는 도중에 지난번에 페어를 하셨던분이 궁금한 내용을 여쭤보셔서 구부분에 갖혀서 한참을 고생했다.
대략적인 내용을 정리하면 이렇다.
해당 현상은 test library (mocha)를 사용하면서 생긴 일이다.
it('여기서 무언가 우린 테스트를 합니다.', () => {
module.exports.test = '이건 테스트 입니다.'
// 뭔가 심도 있는 테스트 내용
// ...
// ...
const obj = {
test: '이건 가짜입니다.',
getTest: () => {
return this.test
}
expect(obj.getTest()).be.eql('뭐가 들어가야 할까요') //
})
여기서 실제 테스트 결과인 '뭐가 들어가야 할까요'
에 적합한 내용이 무엇일까.
쉽게 우리는 '이건 테스트 입니다.'
라는 결과가 들어가야 한다는 걸 알 수 있다.
하지만, 왜 module.exports
가 this
에 나타나게 되는 걸까?
찾아본결과는 다음과 같았다.
module.exports
는 글로벌에서의 this
와 같다.arrow function
은 this
가 존재하지 않는다. (실행 context가 없다.)중간에 테스트를 위해서 다음과 같이 실험을 해보았는데, 또 다른 결과가 나왔다.
it('여기서 무언가 우린 테스트를 합니다.', () => {
// 아까 테스트 내용 그대로
console.log('in this: ', this) // {test: '이건 테스트 입니다.'}
})
console.log('out this: ', this) // {}
?????
분명 찾아본 결과로는 module.exports
가 실행 되었으니, this
안에는 test
라고 하는 키밸류 페어가 있어야 하는데 it
의 콜백에서는 존재하고 밖에서는 찾을 수 없게 되어있다.
it('여기서 무언가 우린 테스트를 합니다.', () => {
// 아까 테스트 내용 그대로
console.log('in this: ', this) // {test: '이건 테스트 입니다.'}
})
module.exports.test = '이건 밖에서 한 테스트 입니다.'
console.log('out this: ', this) // {test: '이건 밖에서 한 테스트 입니다.'}
마지막 실험의 결과를 보면, 실제로 module.exports
는 글로벌의 this
를 조작하는것이 맞다.
하지만, it
이라고 하는 mocha
의 테스트 함수가 무언가 해당 환경을 조작하고 원래의 상태로 돌려놓는 것으로 예측된다.
실제로 글로벌에 선언된 변수를 it
안에서 변경하게 되면 it
이 종료되었을 때 초기화된 값으로 돌아가게 된다.
let a = '변하기 전'
console.log('first a:', a) // 'first a: 변하기 전'
it('어쩌구 저쩌구 테스트 1번', () => {
a = '변한 뒤 '
console.log('second a:', a) // 'second a: 변한 뒤'
})
console.log('last a:', a) // 'last a: 변하기 전'
요즘 너무 바쁩니다. 그냥 궁금한거 정리하다가는 날새겠어요. 어떡하면 효율적으로 공부할지 조금 생각해봐야 합니다.
난 토이 프로젝트가 하고 싶다는 말이에요.