Written by
hoyeonUm
on
on
JavaScript Transcompile 을 진행해보자
예전 진행한 프로젝트에서 function 을 arrow function 으로 변환하는 도중 다음과 같은코드가 있었다.
let someThingObject = {
something : 'test' ,
getSomthing : function () {
return this.somthing;
}
}
someThingObject.getSomthing(); //test
해당코드를 다음과 같이 변환하고있는데 일반 function 에서는 잘되던 this 값이 arrow function 으로 이동되면서는 전달되지 않는 문제가 생겼다. arrow function 은 this 를 that 이나 bind 함수 없이 쓸수있도록 도와준다고 알고있었는데 적용이 안되어서 테스트를 진행해 보았다.
let someThingObject = {
something : 'test' ,
getSomthing : () => {
return this.somthing;
}
}
someThingObject.getSomthing(); //undefined
node 랑 npm 은 설치 되어있다고 가정하고 진행한다.
setUp
npm install babel-cli -g
/usr/bin/babel-doctor -> /usr/lib/node_modules/babel-cli/bin/babel-doctor.js
/usr/bin/babel -> /usr/lib/node_modules/babel-cli/bin/babel.js
/usr/bin/babel-node -> /usr/lib/node_modules/babel-cli/bin/babel-node.js
/usr/bin/babel-external-helpers -> /usr/lib/node_modules/babel-cli/bin/babel-external-helpers.js
cd /home
mkdir ./babeltest
cd ./babeltes
//babel preset setup
npm install --save-dev babel-preset-es2015t
//babelrc
vim ./.babelrc
{
"presets":["es2015"]
}
기초세팅종료.
test.js
vim ./test.js
let testObj = {
testVal : '1234',
callArrow : () => {
console.log(this.testVal)
},
callFunction : function () {
console.log(this.testVal);
},
callFunctionInArrow : function() {
setTimeout(() => {
console.log(this.testVal);
});
},
callFunctionInFunction : function() {
setTimeout(function () {
console.log(this.testVal);
});
},
callArrowInArrow : () => {
setTimeout(() => {
console.log(this.testVal);
});
},
callArrowInFunction : () => {
setTimeout(function() {
console.log(this.testVal);
});
},
}
testObj.callArrow(); //undefined
testObj.callFunction(); //1234
testObj.callFunctionInArrow(); //1234
testObj.callFunctionInFunction(); //undefined
testObj.callArrowInArrow(); //undefined
testObj.callArrowInFunction(); //undefined
babel compile
babel ./test.js -o ./test_compile.js
vim ./test_compile.js
'use strict';
var testObj = {
testVal: '1234',
callArrow: function callArrow() {
console.log(undefined.testVal);
},
callFunction: function callFunction() {
console.log(this.testVal);
},
callFunctionInArrow: function callFunctionInArrow() {
var _this = this;
setTimeout(function () {
console.log(_this.testVal);
});
},
callFunctionInFunction: function callFunctionInFunction() {
setTimeout(function () {
console.log(this.testVal);
});
},
callArrowInArrow: function callArrowInArrow() {
setTimeout(function () {
console.log(undefined.testVal);
});
},
callArrowInFunction: function callArrowInFunction() {
setTimeout(function () {
console.log(this.testVal);
});
}
};
testObj.callArrow(); //undefined
testObj.callFunction(); //1234
testObj.callFunctionInArrow(); //1234
testObj.callFunctionInFunction(); //undefined
testObj.callArrowInArrow(); //undefined
testObj.callArrowInFunction(); //undefined
위와 같이 애초에 this 값이 undefined 로 변환되서 저장되는것을 확인할수있다.
화살표 함수에서 this 를 찾을수 없는 이유는
화살표 함수는 자기 자신의 this 를 가지고있지않는다.(bind 와 같은 행위를 할수없음) 따라서
화살표 함수 내에서 this 에 대한 호출이 일어나면 this에 대한 바인딩을 찾기위해 화살표 함수의 범위를 찾기 시작한다.
일반 함수 (function a () {}) 와 global scope 만이 this 를 소유할수 있기때문에 화살표 함수는 object 안에서의 this 를 찾을수 없다. 따라서 최상위 (global scope) 의 this 를 참조하게 된다.