<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>heo-mk.log</title>
        <link>https://velog.io/</link>
        <description>괴발개발 개발자 지망생에서 금손이 개발자가 되어 남들에게 기여하는 사람이 되기 위해서 개발을 배우고 있습니다.</description>
        <lastBuildDate>Thu, 17 Jun 2021 15:21:28 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>heo-mk.log</title>
            <url>https://images.velog.io/images/heo-mk/profile/fdd63ec4-7390-4c86-904d-2d8807a4bccc/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. heo-mk.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/heo-mk" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[자바스크립트 스터디 : 코어자바스크립트 3장 this]]></title>
            <link>https://velog.io/@heo-mk/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%8A%A4%ED%84%B0%EB%94%94-%EC%BD%94%EC%96%B4%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-3%EC%9E%A5-this</link>
            <guid>https://velog.io/@heo-mk/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%8A%A4%ED%84%B0%EB%94%94-%EC%BD%94%EC%96%B4%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-3%EC%9E%A5-this</guid>
            <pubDate>Thu, 17 Jun 2021 15:21:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>코어자바스크립트(정재남 지음)의 3-1절에서 다룬 this 내용을 리뷰한 페이지입니다.   </p>
</blockquote>
<p><strong>철이 없었죠, 파이썬만 배우면 다 되는줄 알고 자바스크립트도 모르면서 패기 넘치게 리액트를 배웠다는 자체가.</strong> 그러다 리액트의 class형 컴포넌트에서 갑툭튀한 this가 뭔지 몰라 넋을 놔버렸죠. 함수형 컴포넌트로 전향하니 this가 안 나와서 잊어 버리고 있었네요. 이제 잠시 숨을 돌리는 이때, this를 제대로 알고 넘어가야겠어요.</p>
<blockquote>
<p>자바스크립트에서 가장 혼란스러운 개념 this
다른 객체지향 언어에서 this는 클래스로 생성된 인스턴스 객체
<strong>그러나 자바스크립트에서 this는 상황에 따라 가리키는 대상이 다르다.</strong>
자바스크립트에서 this는 함수와 객체를 실질적으로 구분하는 거의 유일한 기능</p>
</blockquote>
<h2 id="1-1-전역공간에서-this">1-1. 전역공간에서 this</h2>
<blockquote>
<p>전역공간에서 this === 전역객체</p>
</blockquote>
<p>전역공간에서 this는 전역객체를 가리키고 전역객체는 window이므로, 전역공간에서는 this === window이다. 그리고 자바스크립트의 모든 변수는 실은 특정객체(여기서는 전역객체)의 프로퍼티이므로, 다음과 같은 관계가 성립한다.</p>
<pre><code class="language-javascript">var a = 1;
console.log(a, window.a, this.a); // 1 1 1</code></pre>
<p>그리고 전역에서는 var로 선언하는 것과 window의 프로퍼티로 직접 할당하는 것이 같다</p>
<pre><code class="language-javascript">var a = 1;
window.b = 2;
console.log(a, window.a, this.a); // 1 1 1
console.log(b, window.b, this.b); // 2 2 2</code></pre>
<h2 id="1-2-메서드로-호출할-때-this">1-2. 메서드로 호출할 때 this</h2>
<p>전역공간에서 함수자체로 호출 할 때, 객체의 메서드로 호출할때 this는 서로 다른 것을 가리킨다.</p>
<pre><code class="language-javascript">var func = function (x) {
    console.log(this, x);
};
func(1); // window {...} 1

var obj = {
    method: func,
};
obj.method(2); // {method: f} 2</code></pre>
<p><strong>함수자체를 호출하면 this는 전역객체인 window를 가리키지만, 객체의 메서드로 호출하면 this는 객체(위의 예에선  obj)를 가리킨다.</strong> 다시말해 익명함수 func는 그대로여도,<strong>텍스트</strong> 변수로 호출한 경우와 객체의 프로퍼티로 호출한 경우 this가 가리키는 대상이 달라진다.</p>
<p>this에는 호출한 대상의 정보가 담긴다. 함수를 메서드로서 호출하는 경우, this는 호출주체인 함수명 바로 앞의 객체를 가리키게 된다.</p>
<pre><code class="language-javascript">var obj = {
    methodA: function () {
        console.log(this);
    }
    inner: {
        methodB: function () {
            console.log(this);
        }
    }
}

obj.methodA();        // { method: f, inner: { ... } }  ( === obj)
obj.inner.methodB();  // { method: f }  ( === obj.inner)</code></pre>
<h2 id="1-3-함수로-호출시-함수-내부에서-this">1-3. 함수로 호출시 함수 내부에서 this</h2>
<h3 id="함수-내부에서-this">함수 내부에서 this</h3>
<p><strong>함수를 함수로서 호출할 때는 this가 지정되지 않는다.</strong> this는 호출한 주체의 정보를 가리키는데, 자바스크립트에서는 함수를 함수로 호출하는 경우에는 호출주체가 없다(객체지향언어라면 호출주체는 객체가 된다). 이런 경우에는 함수의 this는 전역객체를 가리키는데, 이를 자바스크립트이 설계오류라고 한다.</p>
<h3 id="메서드의-내부함수에서-this">메서드의 내부함수에서 this</h3>
<p>바로 앞에서 언급한 설계오류로 인해서 this가 무얼 가리키는지 혼란스러울때가 많다. <strong>하지만 함수를 함수로 호출할 때 this가 가리키는 것과 메서드로 호출할 때 this가 가리키는 것은 다르다는 것을 알고 구분하면 된다.</strong></p>
<pre><code class="language-javascript">var obj1 = {
  outer: function  () {
    console.log(this);    // this -&gt; obj1
    var innerFunc = function () { 
      console.log(this);  // innerFunc()로 호출이면 this -&gt; window, obj2.innerMethod()로 호출하면 this -&gt; obj2
    }
    innerFunc();

    var obj2 = {
      innerMethod: innerFunc,
    };
    obj2.innerMethod();
  }
};
obj1.outer();</code></pre>
<p><img src="https://images.velog.io/images/heo-mk/post/76df1505-d56f-49b3-98ff-868dd0d96494/image.png" alt="">
해설</p>
<ol>
<li>세번째줄에 나오는 this는 obj1의 메서드로서 호출 되었으므로 obj1를 가리킨다.</li>
<li>innerFunc()는 함수로 호출 되었으므로 다섯번째 줄의 this는 전역객체인 window를 가리킨다.</li>
<li>obj2.innerFunc()는 obj2의 메서드로서 호출 되었으므로 다섯번째줄의 this는 obj2를 가리킨다.</li>
</ol>
<p>이렇듯 함수로 호출할 때, 메서드로 호출할 때 this는 서로 다른 것을 가리킨다는 것을 알면 해석 할 수 있게 된다.</p>
<h3 id="메서드의-내부함수에서-this-우회하기">메서드의 내부함수에서 this 우회하기</h3>
<p>그렇지만 이렇게 하는것이 헷갈리거나 전역객체를 바인딩하지 않고 호출 당시 주변환경의 this를 그대로 받게 하고 싶다면 다음과 같이 하면 된다.</p>
<pre><code class="language-javascript">var obj = {
  outer: function  () {
    console.log(this);    // this -&gt; obj
    var innerFunc1 = function () { 
      console.log(this);  // this -&gt; window
    }
    innerFunc1();

    var self = this; // outer 환경의 this를 할당

    var innerFunc2 = function () {
      console.log(self);  // this -&gt; obj
    }
    innerFunc2();
  }
};
obj.outer();</code></pre>
<p><img src="https://images.velog.io/images/heo-mk/post/9d5b463f-1c63-4140-a4ab-b44ae665801a/image.png" alt=""></p>
<p>outer 안에서 var self = this로 outer 환경의 this를 할당해 주면 this를 현재 컨텍스트의 this를 바라보게 하는 효과가 생기므로, innerFunc2안의 this가 obj를 가리키게 된다.</p>
<h3 id="this를-바인딩하지-않은-함수-feat-화살표함수">this를 바인딩하지 않은 함수 (feat. 화살표함수)</h3>
<p>ES6부터 추가된 화살표 함수는 this를 바인딩하지 않으므로 상위 스코프의 this를 활용하게 된다. 쉽<strong>게 말해서 화살표 함수를 쓰면 this가 전역객체를 가리키지 않게 할 수 있다.</strong> 다음의 예시를 보자.</p>
<pre><code class="language-javascript">var obj = {
  outer: function() {
    console.log(this);
    var innerFunc = () =&gt; {
      console.log(this);
    };
    innerFunc();
  }
};
obj.outer();</code></pre>
<p><img src="https://images.velog.io/images/heo-mk/post/d7ec691f-ba94-4c5a-b33d-aa85c6a804a9/ddfd.JPG" alt=""></p>
<h3 id="콜백함수-내부에서-this">콜백함수 내부에서 this</h3>
<p>콜백함수의 경우에도 내부의 this는 경우에 따라 가리키는 대상이 다르다. <strong>콜백함수가 호출 될 때 this가 가리킬 대상을 지정하지 않으면 전역객체(window)를 가리키고, 메서드로서 호출이 되면 메서드의 점(.) 앞의 대상을 this로 가리키게 된다.</strong>
예시를 보자</p>
<pre><code class="language-javascript">setTimeout(function () {
  console.log(this);
}, 300); // this를 가리키는 대상을 지정하지 않았으므로 this는 전역객체인 window객체를 가리키게 된다.   

[1,2,3,4,5].forEach(function (x) {
  console.log(this, x);
}); // this를 가리키는 대상을 지정하지 않았으므로 this는 전역객체인 window객체를 가리키게 된다

document.body.innerHTML += &#39;&lt;button id=&quot;a&quot;&gt;클릭&lt;/button&gt;&#39;;
document.body.querySelector(&#39;#a&#39;)
  .addEventListener(&#39;click&#39;, function(e) {
    console.log(this, e)
  });   // addEventListener 자신이 가리키는 this를 콜백함수가 가리키도록 한다</code></pre>
<h3 id="생성자-함수-내부에서-this">생성자 함수 내부에서 this</h3>
<p><strong>자바스크립트에서 생성자 함수는 공통된 특징을 지니는 객체(인스턴스)를 생성하는데 사용하는  함수다. 자바스크립트는 함수에 생성자의 역할을 부여하는 것이다.</strong> 프로젝트를 해본 사람이라면 한번쯤은 써봤을 new 명령어와 함께 생성자 함수를 호출하면 해당 함수가 생성자로서 동작하게 된다. 다음과 같은 예시가 있다.</p>
<pre><code class="language-javascript">const formData = new FormData();  // ForData라는 생성자 함수는 formData라는 인스턴스를  생성한다. 인스턴스 formData는 키:값의 형태로 데이터를 저장할 수 있는 객체다.
formData.append(&quot;title&quot;, post.title);
formData.append(&quot;content&quot;, post.content);
...</code></pre>
<p>함수가 생성자함수로서 호출된 경우, <strong>내부의 this는 새로 만들어질 인스턴스를 가리키게 된다.</strong> 그러므로 파이썬에서 클래스를 정의할 때 쓰는 self와 this가 유사하다고 보면 되겠다. 구체적인 인스턴스가 만들어지는 과정은 다음과 같다. 생성자함수의 prototype을 참조하는 _ _ _ proto _ _ _ 라는 프로퍼티가 있는 인스턴스를 만들고 공통속성, 개성을 해당 인스턴스 즉 this에 부여하면 된다.
코드로 예를 들어보자.</p>
<pre><code class="language-javascript">var Cat = function (name, age) {
  this.bark = &#39;야옹&#39;;
  this.name = name;
  this.age = age;
};

var choco = new Cat(&#39;초코&#39;, 7);
var nabi = new Cat(&#39;나비&#39;, 5);
console.log(choco, nabi);</code></pre>
<p><img src="https://images.velog.io/images/heo-mk/post/8d69c331-6f74-4a5a-97c2-1937a688d978/image.png" alt="">
Cat이란 변수에 할당된 함수 내부에서는 this의 프로퍼티에 인자러 입력된 값을 대입해준다. 이후 new 명령어와 함께 생성자함수 Cat를 호출하면 인자로 입력된 값들이 this가 가리키는 인스턴스들의 프로퍼티로 저장이 된다. 다시말해, var choco = new Cat(&#39;초코&#39;, 7)에서 this는 choco 인스턴스를 가리키고, 인자로 입력된 값들이 choco 인스턴스의 프로퍼티로 저장이 되는 것이다. </p>
]]></description>
        </item>
    </channel>
</rss>