코딩생활의 소소한 뒤통수
js에서 일반적인 this에 대한 내용을 알기 쉽게 MDN문서가 설명하고 있다.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
이 문서의 call & apply 섹션에 가면 Note부분에 primitive가 this인 경우의 설명이 있다.
Note that with call and apply, if the value passed as this is not an object, an attempt will be made to convert it to an object using the internal ToObject operation.
머 간단히 정리하자면 this로 넘어갈 대상이 오브젝트가 아니라면 내부적으로 ToObject가 발동하여 객체화한게 넘어간다는 얘기다. ToObject는 js엔진 내측 구현이다. 기본값을 래핑객체로 만드는 일을 한다(사실 굉장히 많은 곳에서 ToObject를 사용하고 있어 쇼크였다. 나머지도 전부 검토해봐야함..)
MDN이 아니라 실제 스펙문서에서는 세부 절차등에 ToObject를 호출한다는 것을 명시하고 있다.
http://www.ecma-international.org/ecma-262/6.0/#sec-ordinarycallbindthis
해서 다음과 같은 일이 일어난다는 것이다.
(function(){
console.log(this);
}).call(1);
//[object Number]
즉 this에 primitive인 1을 보내면 ToObject의 작동으로 말미암아 new Number(1) 이 전달된다는 것이다. 이건 바인드에도 당연히 그대로 적용된다.
(function(){
console.log(this);
}).bind(1)();
//[object Number]
또한 배열객체의 iterator계 메소드도 마찬가지다.
[1,2].map(function(v){
console.log(this);
return v;
}, 1);
//[object Number]
//[object Number]
P.S 이러한 강제 객체화는 Object.assign, Object.setProperty 등 인자에 객체를 강제하는 대부분의 코어객체 메소드에 적용되어있다(는걸 문서로 알 수 있다 ^^)
> 다음글
> 이전글