<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>argos_js.log</title>
        <link>https://velog.io/</link>
        <description>ARGOS JavaScript 정복하기</description>
        <lastBuildDate>Sun, 24 Oct 2021 12:50:03 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>argos_js.log</title>
            <url>https://images.velog.io/images/argos_js/profile/3471b4aa-844b-493c-910e-b5a9e2d950ad/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. argos_js.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/argos_js" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Begachu]JavaScript에서의 객체지향 프로그래밍]]></title>
            <link>https://velog.io/@argos_js/BegachuJavaScript%EC%97%90%EC%84%9C%EC%9D%98-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</link>
            <guid>https://velog.io/@argos_js/BegachuJavaScript%EC%97%90%EC%84%9C%EC%9D%98-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</guid>
            <pubDate>Sun, 24 Oct 2021 12:50:03 GMT</pubDate>
            <description><![CDATA[<p>이번주에는 Javascript에서의 <strong>객체지향 프로그래밍</strong>에 대해 공부해보고자 합니다.</p>
<hr>
<h2 id="클래스-기반-vs-프로토타입-기반-언어">클래스 기반 vs 프로토타입 기반 언어</h2>
<p>객체지향 언어는 크게 <strong>클래스 기반 언어</strong>와 <strong>프로토타입 기반 언어</strong>가 존재합니다.</p>
<p><strong>클래스 기반 언어</strong>는 클래스를 이용해서 객체의 형태와 기능을 정의하고, 생성자를 통해 인스턴스를 만들어 사용합니다. 클래스 기반 언어의 예로는 Java, C++가 있습니다.
클래스 기반 언어는 모든 인스턴스가 클래스에 정의된 것과 같은 구조를 가지며, 이는 런타임에 바꿀 수 없습니다.
반면 <strong>프로토타입 기반 언어</strong>는 클래스 대신 <strong>프로토타입 객체</strong>를 이용하기 때문에 객체의 자료구조, 메서드 들을 동적으로 바꿀 수 있습니다.</p>
<p>클래스 기반 언어는 정확성, 안전성, 예측성 등의 관점에서 장점을 지니고, 프로토타입 기반 언어는 동적으로 객체의 구조와 동작 방식을 바꿀 수 있다는 장점을 지닙니다.</p>
<p>Javascript는 프로토타입 기반 언어로, 이번 시간에는 Javascript에서 프로토타입 객체를 이용한 객체지향 프로그래밍 방법에 대해 알아볼 것입니다.</p>
<hr>
<h2 id="클래스-생성자-메서드">클래스, 생성자, 메서드</h2>
<p>Class 키워드를 직접 제공하는 클래스 기반 언어와 달리, Javascript에서는 class와 같은 개념이 존재하지 않습니다. 하지만 우리는 Javascript의 함수를 이용하여 클래스와 함께 생성자, 메서드도 모두 구현할 수 있습니다.</p>
<pre><code class="language-javascript">function Person(arg){
    this.name = arg;

    this.getName = function() {
        return this.name;
    }
}

var me = new Person(“begachu”);
console.log(me.getName());    // 출력 : begachu

me.setName(“yugyoung”);
console.log(me.getName());    // 출력 : yugyoung</code></pre>
<p>위의 코드는 이전 시간에 공부했던 생성자 함수 방식으로 객체를 생성하여 사용한 경우입니다. 하지만 이 예제는 문제가 있을 수 있습니다. 위의 코드의 Person 생성자 함수를 이용해 여러 개의 객체를 만든다고 가정해봅시다.</p>
<pre><code class="language-javascript">var me = new Person(“me”);
var you = new Person(“you”);
var him = new Person(“him”);</code></pre>
<p>위의 코드로 만들어진 세 객체는 정상적으로 작동할 것입니다. 하지만 이 경우 각 객체는 setName()과 getName()이라는 동일한 일을 수행하는 함수들을 각각의 메모리에 올려놓고 사용하고 있습니다. 이는 자원낭비를 가져옵니다.</p>
<p>그렇다면 이러한 자원낭비를 막기 위해서는 어떻게 해야할까요?</p>
<pre><code class="language-javascript">function Person(arg) {
    this.name = arg;
}

Person.prototype.getName = function() {
    return this.name;
}

Person.prototype.setName = function(value) {
    this.name = value;
}

var me = new Person(“me”);
var you = new Person(“you”);
console.log(me.getName());
console.log(you.getName());</code></pre>
<p>위와 같이 공통적인 프로퍼티를 Person 함수 객체의 prototype 프로퍼티로 정의하면 됩니다. 
더 나아가 아래의 메서드를 정의해 사용할 수도 있습니다.</p>
<pre><code class="language-javascript">Function.prototype.method = function(name, func) {
    if (!this.prototype[name])
        this.prototype[name] = func;
    }
}</code></pre>
<blockquote>
<p>더글라스 크락포드는 함수를 생성자로 사용해 프로그래밍하는 것을 추천하지 않습니다. 이는 생성자 함수가 new를 이용한 호출 뿐만 아니라 직접 호출도 가능하기 때문입니다. 또한 호출 방법에 따라 this에 바인딩되는 객체가 달라진다는 점도 그 이유입니다. 따라서 크락포드는 일단은 생성자로 사용되는 함수의 첫 글자를 대문자로 표기할 것을 권고하고 있습니다.</p>
</blockquote>
<h2 id="상속">상속</h2>
<p>Javascript에서는 클래스를 기반으로 하는 전통적인 상속을 지원하지 않습니다. 대신 <strong>객체 프로토타입 체인</strong>을 통해 상속을 구현할 수 있습니다. 이 방식은 크게 두 가지로 나뉩니다.</p>
<ol>
<li>클래스 기반 상속 방식 모방</li>
<li>클래스 없이 객체의 프로토타입으로 상속 구현</li>
</ol>
<p>특히 2번째 방법은 <strong>프로토타입을 이용한 상속</strong>이라고 합니다. 이번 시간에는 두 방법 모두에 대해 알아보고자 합니다.</p>
<h3 id="프로토타입을-이용한-상속">프로토타입을 이용한 상속</h3>
<p>아래의 코드를 볼까요?</p>
<pre><code class="language-javascript">function create_object(o) {
  function F() {}
  F.prototype = o;
  return new F();
}</code></pre>
<p>코드에서 create_object() 함수는 인자로 들어온 객체를 부모로 하는 자식 객체를 생성해 이를 반환하고 있습니다. 이렇게 반환된 객체는 인자로 들어온 객체 o의 프로퍼티에 접근할 수 있으며, 또한 자신의 프로퍼티도 만들 수 있습니다.</p>
<p>이처럼 프로토타입의 특성을 활용해 상속을 구현하는 것이 프로토타입 기반의 상속입니다.</p>
<p>프로토타입 기반의 상속은 클래스에 해당하는 생성자 함수, 인스턴스를 따로 생성하지 않고 부모 객체를 프로토타입 체인으로 참조하여 상속을 구현한다는 특징이 있습니다.</p>
<h4 id="자식-객체에서의-overriding">자식 객체에서의 overriding</h4>
<p>앞에서는 자식 객체가 부모 객체의 함수를 그대로 상속받는 경우만 다루었습니다. 이번에는 자식 객체가 부모의 함수를 오버라이딩하는 방법에 대해서 알아보고자 합니다.
이를 위해서 이번에는 JQuery의 extend() 함수를 사용해보고자 합니다.
extend() 함수는 다음과 같이 구현되어 있습니다.</p>
<pre><code class="language-javascript">jQuery.extend = jQuery.fn.extend = function(obj, prop) {
  if (!prop) { prop = obj; obj = this; }
  for ( var i in prop ) obj[i] = prop[i];
  return obj;
};</code></pre>
<p>위의 코드를 간단히 분석하자면, 인자가 하나만 들어오는 경우는 현재 객체의 인자로 들어오는 객체의 프로퍼티를 복사하고, 두 개가 들어오는 경우 첫 번째 객체에 두 번째 객체의 프로퍼티를 복사한다는 것입니다.</p>
<p>하지만 이 경우 obj[i] = prop[i]는 얕은 복사이므로 두 번째 객체의 프로퍼티가 변경되면 첫 번째 객체의 프로퍼티도 같이 변경되게 됩니다.
따라서 extend 함수를 구현하는 경우 대상이 객체일 때 깊은 복사를 하는 것이 일반적입니다.</p>
<p>사용예시는 다음과 같습니다.</p>
<pre><code class="language-javascript">var person = {
  name = &quot;test&quot;,
  getName : function() {
    return this.name;
  },
  setName : function(arg) {
    this.name = arg;
  }
};

function create_object(o) {
  function F() {};
  F.prototype = o;
  return new F();
}

function extend(obj,prop) {
  if(!prop) { prop = obj; obj = this; }
  for ( var i in prop ) obj[i] = prop[i];
  return obj;
}

var student = create_object(person);
var added = {
  setAge : function(age) {
    this.age = age;
  },
  getAge : function() {
    return this.age;
  }
};

extend(student, added);

student.setAge(23);
console.log(student.getAge());</code></pre>
<h3 id="클래스-기반의-상속">클래스 기반의 상속</h3>
<p>클래스 기반의 상속도 사실은 프로토타입을 이용한 상속과 유사하게 함수의 프로토타입을 적절히 이용하여 상속을 구현합니다.
하지만 객체 리터럴로 생성된 객체의 상속이었던 프로토타입 이용한 상속과 달리, 클래스 기반의 상속에서는 클래스 역할을 하는 함수로 상속을 구현합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[purplepig4657] 자바스크립트의 클로저]]></title>
            <link>https://velog.io/@argos_js/purplepig4657-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98-%ED%81%B4%EB%A1%9C%EC%A0%80</link>
            <guid>https://velog.io/@argos_js/purplepig4657-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98-%ED%81%B4%EB%A1%9C%EC%A0%80</guid>
            <pubDate>Sun, 24 Oct 2021 11:16:11 GMT</pubDate>
            <description><![CDATA[<h3 id="클로저의-개념">클로저의 개념</h3>
<p>클로저는 &#39;함수&#39;이다. 어떤 함수가 외부 함수의 지역변수에 접근한다면 그 함수는 &#39;클로저&#39;라 한다. 다음 예제를 보자.</p>
<pre><code class="language-javascript">function a() {
    var x = 0;
    var b = function() {
        console.log(x);
    }
    return b;
}

var c = a();
c(); // 0</code></pre>
<p>다음 예제에서 함수 a에서 함수 b가 리턴된다. 여기서 b는 외부 함수의 변수 x를 참조한다. 이렇게 a함수 바깥에서 x가 참조될 수 있었고, 이것을 가능하게 하는 개념이 바로 클로저다. 또한 클로저로 참조되는 외부 변수 x를 자유 변수(free variable)이라 한다.</p>
<p>여기서 &quot;a 함수의 실행 컨텍스트는 종료되었을 텐데 어떻게 변수 x를 참조할 수 있을까?&quot;라는 의문이 들 수 있다. 하지만 이 의문은 &#39;스코프 체인&#39; 개념을 알고있다면, 쉽게 해결될 수 있다. a의 실행 컨텍스트가 종료되더라도 a의 변수 객체는 b의 스코프 체인으로 참조되고 있기 때문에 가능한 것이다. 클로저는 이렇게 스코프 체인의 뒷쪽 객체를 참조하는 특성상 성능 저하의 원인이 된다.</p>
<h3 id="클로저의-활용">클로저의 활용</h3>
<h4 id="특정-함수에-사용자-정의-객체의-메서드-연결">특정 함수에 사용자 정의 객체의 메서드 연결</h4>
<p>어떠한 함수는 인자를 하나만 받는다고 해보자. 그럼 사용자가 함수를 정의를 해도 한 개의 인자를 받는 함수를 정의할 수 밖에 없다. 하지만 여기서 더 많은 인자를 넘기고 싶다면 어떻게 해야 할까? 여기서 클로저가 사용될 수 있다. 다음 예시를 보자.</p>
<pre><code class="language-javascript">function HelloFunc() {
    this.greeting = &quot;hello&quot;;
}

HelloFunc.prototype.call = function(func) {
    func ? func(this.greeting) : this.func(this.greeting);
}

function saySomething(obj, methodName, name) {
    return (function(greeting) {
        return obj[methodName](greeting, name);
    });
}

function newObj(obj, name) {
    obj.func = saySomething(this, &quot;who&quot;, name);
    return obj;
}

newObj.prototype.who = function(greeting, name) {
    console.log(greeting + &quot; &quot; + name);
}

var objHello = new HelloFunc();
var obj = new newObj(objHello, &quot;a&quot;);
obj.call(); // hello a</code></pre>
<p>이 예제에서 HelloFunc의 prototype의 call 함수는 인자에 greeting만을 받아 함수를 실행한다. 따라서 우린 두 개 이상의 인자를 넘기는 것이 불가능하다. 하지만 클로저를 사용한다면 이것이 가능해 질 수 있다.</p>
<p>이 예제의 saySomething 함수는 함수를 반환하는데 이 반환되는 함수가 클로저이다. 이 클로저는 인자로 greeting을 받고, obj[&quot;who&quot;] 함수를 호출한다. 이 과정에서 saySomething의 name변수가 참조되므로 클로저라 할 수 있다. 이러한 과정을 거쳐 obj.call 함수를 호출하면 사실상 newObj.prototype.who 함수가 호출되는 것과 같으므로 인자를 두 개 이상 넣는 것과 같은 효과를 얻을 수 있다.</p>
<h4 id="함수의-캡슐화">함수의 캡슐화</h4>
<p>다음 두 예제를 비교해보자.</p>
<pre><code class="language-javascript">var array = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;];

function a() {
    return array;
}

var b = a();
console.log(b); // [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]</code></pre>
<pre><code class="language-javascript">var obj = (function() {
    var array = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;];

    var a = function() {
        return array;
    }

    return a;
})();

var b = obj();
console.log(b); // [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]</code></pre>
<p>첫 번째 예시와 두 번째 예시의 출력은 같다. 하지만 두 코드의 차이는 무엇일까?</p>
<p>첫 번째 예시의 문제점은 변수 array가 전역 변수라는 것이다. 이는 많은 문제를 발생시킬 수 있다.</p>
<blockquote>
</blockquote>
<ul>
<li>다른 함수에서 쉽게 접근하여 값을 변경 가능.</li>
<li>같은 이름의 변수와 충돌 가능성.</li>
</ul>
<p>이러한 문제점은 다른 코드와 통합할 때, 혹은 라이브러리 코드를 만들 때 많이 발생한다.</p>
<p>따라서, 변수를 함수 아래로 넣어 외부에 노출되지 않도록 하고, 클로저를 사용하여 자유 변수에 접근하도록 하는 두 번째 예시가 우려하는 문제를 일으킬 가능성이 낮아지는 것이다. 이를 함수의 캡슐화라 한다.</p>
<h3 id="클로저를-활용할-때-주의사항">클로저를 활용할 때 주의사항</h3>
<h4 id="클로저의-여러-번-호출로-값이-항상-변할-수-있음을-상기">클로저의 여러 번 호출로 값이 항상 변할 수 있음을 상기</h4>
<pre><code class="language-javascript">function a() {
    var b = 0;
    return (function c() {
        b += 1;
        console.log(b);
    });
}

var d = a();
d(); // 1
d(); // 2</code></pre>
<p>이 예시처럼, a 함수의 자유 변수 b 값은 클로저 d에 의해 계속 변경될 수 있다. 이렇듯 자유 변수의 값은 계속 변화할 수 있다는 것을 유의해야 한다.</p>
<h4 id="루프-안에서-클로저를-사용시-유의">루프 안에서 클로저를 사용시 유의</h4>
<pre><code class="language-javascript">function a(num) {
    for(var i = 0; i &lt; num; i++) {
        setTimeout(function() {
            console.log(i);
        }, i * 1000);
    }
}
a(3);
// 3
// 3
// 3</code></pre>
<p>이 예제는 0, 1, 2가 1초 간격으로 출력되는 것을 기대하고 작성하였다. 하지만, 출력은 3만 1초 간격으로 출력되었다.</p>
<p>위 예제에서는 클로저 함수가 자유 변수 i를 참조하고 있다. 일단 setTimeout의 두 번째 인자의 i는 각각 0, 1, 2가 들어갔을 것이다. 하지만 실제로 setTimeout함수에서 호출되는 클로저는 그렇지 않다. 왜냐하면, 클로저를 실행할 때는 이미 i가 0, 1, 2을 지나 3이 된 상태일 것이기 때문이다. 따라서 기대한 것과는 다르게 3만 세 번 출력되었다.</p>
<pre><code class="language-javascript">function a(num) {
    for(var i = 0; i &lt; num; i++) {
        (function(num) {
            setTimeout(function() {
                console.log(num);
            }, num * 1000);
        })(i);
    }
}
a(3);
// 0
// 1
// 2</code></pre>
<p>다음 예제는 위의 문제를 해결한 것이다. i를 익명 함수의 인자로 넘겨주었고, 그 익명 함수에 안에서 setTimeout함수가 실행된다. 이렇게 한다면 기대한 결과가 출력되게 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ire4564]실행 컨텍스트와 클로저]]></title>
            <link>https://velog.io/@argos_js/ire4564%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EC%99%80-%ED%81%B4%EB%A1%9C%EC%A0%80</link>
            <guid>https://velog.io/@argos_js/ire4564%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EC%99%80-%ED%81%B4%EB%A1%9C%EC%A0%80</guid>
            <pubDate>Sun, 17 Oct 2021 12:58:37 GMT</pubDate>
            <description><![CDATA[<p>오늘은 JavaScript의 기본이 되는 실행 컨텍스트와 스코프, 클로저에  대해서 배워보자. 이를 이해하지 못하면 자바스크립트 코드를 매우 이해하기 어렵고, 활용하기 불편할 것이기 때문에 꼭 필수 개념이다.</p>
<h2 id="💡-실행-컨텍스트-개념">💡 실행 컨텍스트 개념</h2>
<p>기존에 다른 언어를 배웠다면 <strong>콜 스택(Call Stack)을 들어보았을 것이다. 콜 스택은 함수의 호출 정보 등으로 함수 내 지역 변수 혹은 인자 값 등이 차곡차곡 쌓여있는 스택을 의미한다</strong>. <br/>
C언어로 예를 들어보자면, 함수가 호출 될 때마다 해당 함수의 정보가 기존의 호출 정보 위에 스택 형식으로 하나씩 쌓인다.  자바스크립트 역시 동일하다.</p>
<blockquote>
<p>실행 컨택스트는 앞에서 설명한 콜 스택에 들어가는 <strong>실행 정보 하나</strong>와 비슷하다. </p>
</blockquote>
<ul>
<li>ECMAScript에서는 실행 컨텍스트를 &quot;실행 가능한 코드를 형상화하고 구분하는 추상적인 개념&quot;으로 기술한다.</li>
<li>콜 스택과 연관하여 정의하면 <strong>&quot;실행 가능한 자바스크립트 코드 블록이 실행되는 환경&quot;</strong>이다.</li>
</ul>
<p><strong>+) ECMAScript란?</strong>
ECMA-262 기술 규격에 따라 정의하고 있는 <strong>표준화</strong>된 스크립트 프로그래밍 언어를 말한다. 자바스크립트를 표준화하기 위해 만들어졌다. </p>
<br/>

<p>ECMAScript에서는 실행 컨텍스트의 생성을 다음처럼 설명한다.</p>
<blockquote>
<p>현재 실행되는 컨텍스트에서 이 컨텍스트와 관련 없는 실행 코드가 실행되면, <strong>새로운 컨텍스트가 생성되어 스택에 들어가고</strong> <strong>제어권이 그 컨텍스트로 이동한다.</strong></p>
</blockquote>
<p>예시를 보면, 이런 경우이다.</p>
<pre><code>Console.log(&quot;This is global context&quot;);

function ExContext1() {
    console.log(&quot;This is ExContext1&quot;);
};

function ExContext2() {
    console.log(&quot;This is ExContext2&quot;);
};

ExContext2();</code></pre><p>이 경우, 출력은 아래와 같다. 그리고 컨텍스트의 추상적인 개념을 그림으로 표현해 보면 이와 같이 표현할 수 있다.</p>
<pre><code>This is global context
This is ExContext1
This is ExContext2</code></pre><p><img src="https://images.velog.io/images/argos_js/post/46a34a67-3f03-482a-8ec3-4985b67c825f/image.png" alt=""></p>
<ol>
<li><strong>전역 컨텍스트</strong>가 가장 먼저 실행된다. (전역 컨텍스트는, 단지 가장 먼저 실행되는 컨텍스트일 뿐이다.)</li>
<li>이 과정에서 새로운 함수 호출이 발생한다.</li>
<li>새로운 컨텍스트가 만들어지고 실행된다.</li>
<li>종료 되면 반환된다.</li>
</ol>
<p>이 과정이 반복된 후, 전역 실행 컨텍스트의 실행이 완료되면 모든 실행이 끝나게 된다.
<br/></p>
<h2 id="💡-실행-컨텍스트-생성-과정">💡 실행 컨텍스트 생성 과정</h2>
<p>실행 컨텍스트의 생성 과정은 아래와 같다.</p>
<h3 id="1-활성-객체-생성">1. 활성 객체 생성</h3>
<p>실행 컨텍스트가 생성되면, 자바스크립트 엔진은 해당 컨텍스트에서 실행에 필요한 <strong>여러가지 정보를 담을 객체를 생성</strong>하는데, 이를 활성객체라고 한다.</p>
<p>이 객체에 사용하게 될 매개변수나, 사용자가 정의한 변수 및 객체를 저장하고 새로 만들어진 컨텍스트로 접근 가능하게 되어있다.</p>
<h3 id="2-arguments-객체-생성">2. arguments 객체 생성</h3>
<p>이 단계에서는 arguments 객체를 생성하는데, 앞서 만들어진 활성 객체는 argument 프로퍼티로 이 argument 객체를 참조한다. 예를 들어, execute 함수의 param1, param2가 들어왔을 경우의 활성 객체 상태를 표현하면 아래와 같다.
<img src="https://images.velog.io/images/argos_js/post/9409d9f9-6a51-4926-9e5b-80ed9fa4f099/image.png" alt=""></p>
<h3 id="3-스코프-정보-생성">3. 스코프 정보 생성</h3>
<p>이 단계에서는 현재 컨텍스트의 유효 범위를 나타내는 스코프 정보를 생성한다. 이 스코프 정보는 현재 실행 중인 실행 컨텍스트 안에서 연결 리스트와 유사한 형식으로 만들어진다. 이 리스트로 현재 컨텍스트의 변수 뿐만 아니라, 상위 실행 컨텍스트의 변수도 접근이 가능하다.</p>
<p>이 리스트를 <strong>스코프 체인</strong>이라고 하는데, <strong>[[scope]] 프로퍼티</strong>로 참조된다.</p>
<h3 id="4-변수-생성">4. 변수 생성</h3>
<p>다음으로 현재 실행 컨텍스트 내부에서 사용되는 지역 변수의 생성이 이뤄진다. 참고로, <strong>활성 객체</strong>와 <strong>변수 객체</strong>는 같은 것을 뜻하는 말이니 혼동하지 말자.</p>
<p>변수 안에서 호출된 함수 인자는 각각의 프로퍼티가 만들어지고 그 값이 할당된다. 만약 값이 넘겨지지 않았다면 <strong>undefined가 할당</strong>된다.</p>
<blockquote>
<p>여기서 주의할 점은, 이 과정에서는 변수나 내부 함수를 단지 메모리에 생성하고, _<strong>초기화는 각 변수나 함수에 해당하는 표현식이 실행되기 전까지는 이뤄지지 않는다는 점</strong>_을 알고 넘어가자.
표현식의 실행은 객체 생성이 다 이뤄진 후에 시작된다.</p>
</blockquote>
<h3 id="4-this-바인딩">4. this 바인딩</h3>
<p>마지막 단계에 this 키워드를 사용하는 값이 할당된다. 이 값에 어떤 객체가 들어갈지는 전에 &lt;함수 호출과 this&gt;에서 살펴보았으니 참고하도록 하자. </p>
<p>여기서 참고하는 <strong>this 객체가 없으면 전역 객체</strong>를 참조한다.</p>
<h3 id="5-코드-실행">5. 코드 실행</h3>
<p>이렇게 하나의 실행 컨텍스트가 생성되고, 변수 객체가 만들어지고 나면 코드에 있는 여러가지 <strong>표현식의 실행이 이뤄지게 된다. 이렇게 실행 될 떄 변수의 초기화와 연산, 또 다른 함수 실행 등</strong>이 이루어진다.</p>
<blockquote>
<p>전역 실행 컨텍스트 &amp; 일반 실행 컨텍스트</p>
</blockquote>
<ul>
<li>전역 실행 컨텍스트는 <strong>변수를 초기화하고 이것의 내부 함수는 일반적인 탑 레벨의 함수로 선언</strong>된다.</li>
<li>전역 실행 컨텍스트는 변수 객체가 곧 전역 객체이다. 따라서 전역적으로 선언된 함수와 전역 객체의 프로퍼티가 된다.</li>
</ul>
<h2 id="💡-스코프-체인">💡 스코프 체인</h2>
<p>실행 컨텍스트의 생성 과정에 이어, 생성 과정 안에서 설명한 스코프 체인이 어떻게 만들어지는지 살펴보자. 자바스크립트 코트를 이해하려면 스코프 체인의 이해는 필수적이다. </p>
<p>자바스크립트도 다른 언어와 마찬가지로 스코프, 즉 유효 범위가 있다. 이 <strong>유효 범위</strong> 안에서 함수가 존재한다.
<br/>
(업데이트 중....ㅠㅠ) </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Begachu]함수 호출과 this / 프로토타입 체이닝에 대해 알아보자]]></title>
            <link>https://velog.io/@argos_js/Begachu%ED%95%A8%EC%88%98-%ED%98%B8%EC%B6%9C%EA%B3%BC-this-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-%EC%B2%B4%EC%9D%B4%EB%8B%9D%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@argos_js/Begachu%ED%95%A8%EC%88%98-%ED%98%B8%EC%B6%9C%EA%B3%BC-this-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-%EC%B2%B4%EC%9D%B4%EB%8B%9D%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Thu, 14 Oct 2021 14:59:05 GMT</pubDate>
            <description><![CDATA[<p>오늘은 Javascript에서의 함수 호출과 this에 대해 공부해보고자 합니다. 또한 프로토타입 체이닝에 대해서도 간단히 알아봅시다.</p>
<hr>
<h2 id="💡함수-호출">💡함수 호출</h2>
<p>함수의 기본적인 기능은 당연하게도 함수를 호출하여 코드를 실행하는 것입니다. 저번 시간에서도 다루었듯이 Javascript는 문법 체크가 자유로운 언어이죠. 그렇다면 Javascript에서 함수 호출은 어떤 특징이 있을까요?</p>
<p>아래의 코드가 있다고 해봅시다.</p>
<pre><code class="language-javascript">function func(arg1, arg2) {
  console.log(arg1, arg2);
}

func();            // 출력 : undefined undefined
func(1);        // 출력 : 1 undefined
func(1, 2);        // 출력 : 1 2
func(1, 2, 3);    // 출력 : 1 2</code></pre>
<p>func 함수는 인자로 arg1, arg2로 두 인자를 받고 있습니다. 만약 엄격한 문법 체크를 하는 언어라면 func 함수 호출 시 인자 2개를 주지 않으면 오류가 발생할것입니다. 하지만 Javascript에서는 그렇지 않습니다.</p>
<p>예시에서 볼 수 있듯이 함수의 인자의 양을 선언했던 인자 수 보다 적게 주거나, 더 많이 준다고해도 Javascript에서는 출력이 이루어지고 있습니다.</p>
<p>이처럼 <strong>Javascript의 함수는 호출 시 인자를 어떻게 주더라도 오류가 발생하지 않습니다.</strong></p>
<p>그렇다면 만약 들어오는 인자 수에 따라서 함수의 동작을 제어해야한다면 어떻게 해야 할까요?</p>
<hr>
<h2 id="💡arguments-객체">💡arguments 객체</h2>
<p>Javascript 함수는 호출 시 암묵적으로 arguments 객체도 함수 내부로 전달됩니다. <strong>arguments 객체</strong>는 함수에 전달된 모든 인자에 대해 배열과 같은 형태로 저장되어 있습니다. 우리는 이를 통해 전달받은 인자 수와 모든 인자들에 대해 처리를 수행할 수 있습니다.</p>
<p>사용 예시는 다음과 같습니다.</p>
<pre><code class="language-javascript">function sum(a, b){
  var result = 0;

  // 배열처럼 length 프로퍼티 존재
  for(var i=0; i&lt;arguments.length; i++){
    result += arguments[i];        // 배열처럼 접근할 수 있다.
  }
  return result
}

console.log(sum(1, 2, 3));        // 출력 : 6
console.log(sum(1, 2, 3, 4, 5));    // 출력 : 15</code></pre>
<p>하지만 arguments 객체 사용에서 주의할 것이 있습니다. arguments 객체는 실제 배열이 아닌 <strong>유사 배열 객체</strong>입니다. 따라서 배열 객체에 사용하는 pop(), shift() 등의 함수는 사용할 수 없습니다. 하지만 이러한 메소드를 사용해야한다면 어떻게 해야할까요? 이는 조금 이후에 방법을 알아보고자 합니다.</p>
<hr>
<h2 id="💡this-바인딩">💡this 바인딩</h2>
<p>함수 호출 시 arguments 객체와 함께 암묵적으로 전달되는 객체가 하나 더 있습니다. 그것은 바로 <strong>this 인자</strong>입니다.</p>
<p>this 인자는 <strong>함수를 호출한 객체로 바인딩</strong>됩니다. 이해를 돕기위해 아래의 코드를 봅시다.</p>
<pre><code class="language-javascript">var myObject = {
  name: &#39;foo&#39;,
  sayName: function () {
    console.log(this.name);
  }
};

var otherObject = {
  name: &#39;bar&#39;
};
otherObject.sayName = myObject.sayName;


var name = &#39;hi&#39;;
var sayName = myObject.sayName;

myObject.sayName();            // 출력 : foo
otherObject.sayName();            // 출력 : bar
sayName();                // 출력 : hi</code></pre>
<p>otherObject.sayName과 객체 sayName은 모두 myObject의 sayName 함수와 동일합니다. 그럼에도 불구하고 세 함수를 모두 실행해보면 다른 결과가 나오는 것을 확인할 수 있습니다. 이는 세 함수 모두 바인딩된 this 인자가 다르기 때문입니다. 그럼 각각의 함수에 바인딩된 this는 무엇일까요?</p>
<p>코드를 보면서 눈치 채셨겠지만, 각각의 sayName() <strong>함수 앞에 호출된 객체</strong>가 this로 바인딩되었습니다. 앞에 객체가 없는 sayName()의 경우 전역 객체로 바인딩되었기 때문에 hi가 출력되는 것을 확인할 수 있습니다.</p>
<blockquote>
<p>브라우저 환경에서 전역객체는 window입니다.</p>
</blockquote>
<hr>
<p>이밖에도 <strong>함수 내부 코드에서 사용된 this는 전역 객체에 바인딩된다</strong>는 특징이 있습니다. 아래의 예를 참고해서 알아봅시다.</p>
<pre><code class="language-javascript">var value = 100;

var myObject = {
  value: 1,
  func1: function() {
    this.value += 1;
    console.log(&#39;func1() called. this.value : &#39; + this.value);

    func2 = function() {
      this.value += 1;
      console.log(&#39;func2() called. this.value : &#39; + this.value);

      func3 = function() {
          this.value += 1;
          console.log(&#39;func2() called. this.value : &#39; + this.value);
      }
    func3();        // value ++
      }
  func2();            // value ++
  }
};

myObject.func1();</code></pre>
<p>이 코드를 작성한 사용자는 아래와 같은 형태로 코드가 돌아가기를 원했을 것입니다.
<img src="https://images.velog.io/images/argos_js/post/addb0e8d-7194-45a3-b3e6-83c2b23177fb/image.png" alt="">
하지만 실제 출력은 다음과 같이 이루어질 것입니다.</p>
<pre><code class="language-javascript">myObject.func1();
/*
func1() called. this.value : 2
func2() called. this.value : 101
func3() called. this.value : 102
*/</code></pre>
<p>이는 우리가 원했던 것과 달리, 아래와 같이 this가 바인딩되었기 때문입니다.
<img src="https://images.velog.io/images/argos_js/post/34b9c7a7-9711-45bf-ab9b-32dc155aeb86/image.png" alt="">
그러면 우리가 처음에 원하는대로 구현하려면 어떻게 해야할까요? 바로 func1 함수 내 다른 함수들이 접근할 수 있는 <strong>내부 변수에 this를 저장하여 사용</strong>하면 됩니다.</p>
<hr>
<h2 id="💡생성자-함수와-this-바인딩">💡생성자 함수와 this 바인딩</h2>
<p>javascript에서 우리는 생성자 함수를 통해서도 객체를 생성할 수 있습니다. 사용 방법은 다음과 같습니다.</p>
<pre><code class="language-javascript">var Person = function (name) {
  this.name = name;
}

var foo = new Person(&#39;foo&#39;);
console.log(foo.name); // 출력 : foo</code></pre>
<p>이러한 방식의 객체 생성의 장점은 생성자 함수를 통해 같은 형태의 객체를 여러 개 생성할 수 있다는 것입니다.</p>
<p>이러한 생성자 함수에서도 주의해야하는 점이 있습니다.
아래의 코드를 봅시다.</p>
<pre><code class="language-javascript">var Person = function (name) {
  this.name = name;
}

var foo = Person(&#39;foo&#39;);
console.log(foo); // 출력 : undefined

console.log(window.name);     // 출력 : foo</code></pre>
<p>위의 코드처럼 생성자 함수를 사용할 때 <strong>앞의 new 입력을 깜빡한다면, 생성자 함수 내 this가 전역객체로 바인딩</strong>되기 때문의 위와 같은 일이 발생하게 됩니다.
이러한 실수를 막기 위해 아래와 같은 방법을 사용하기도 합니다.</p>
<pre><code class="language-javascript">function A(arg){
  if(!this instanceof A))
      return new A(arg);
  this.value = arg ? arg : 0;
}

var a = new A(100);
var b = A(10);

console.log(a.value);        // 출력 : 100
console.log(b.value);        // 출력 : 10</code></pre>
<hr>
<h2 id="💡call과-apply-메서드를-이용한-명시적인-this-바인딩">💡call과 apply 메서드를 이용한 명시적인 this 바인딩</h2>
<p>위에서 배운 것처럼 함수 호출 발생 시 각각의 상황에 따라서 this가 정해진 객체에 자동적으로 바인딩됩니다. 하지만 우리는 메소드를 통해 <strong>명시적으로 this를 바인딩</strong>할 수도 있습니다. 이러한 역할을 할 수 있는 것이 <strong>call()</strong>과 <strong>apply()</strong> 메서드입니다.</p>
<p>기본적으로 apply와 call 메서드를 호출하는 주체는 <strong>함수</strong>입니다. 또한 apply 또한 this를 특정 객체에 바인딩할 뿐 결국 본질적인 기능은 <strong>함수 호출</strong>입니다. 따라서 결론적으로 기본적인 기능은 <strong>자신을 호출한 함수를 호출하는 것</strong>입니다.</p>
<p>두 함수는 기능이 같기 때문에 우선은 apply() 메서드 먼저 이해해보겠습니다.</p>
<pre><code class="language-javascript">function.apply(thisArg, argArray);</code></pre>
<p>첫 번째 인자인 thisArg는 this로 명시적으로 바인딩할 객체입니다. 그리고 두 번째 인자 argArray는 결론적으로 호출할 함수에 제공할 인자입니다. 아래의 예시를 통해 좀 더 자세히 이해해보겠습니다.</p>
<pre><code class="language-javascript">// 생성자 함수
function Person(name, age, gender) {
  this.name = name;
  this.age = age;
  this.gender = gender;
}

// foo 빈 객체 생성
var foo = {};

// apply() 메서드 호출
Person.apply(foo, [&#39;foo&#39;, 30, &#39;man&#39;]);
console.log(foo);         // 출력 : {name: &#39;foo&#39;, age: 30, gender: &#39;man&#39;}</code></pre>
<p>apply() 메서드를 사용한 것을 보면 이를 이용하여 생성자 함수 Person에서 호출하여 foo라는 객체에 프로퍼티를 할당하고 있는 것을 볼 수 있습니다.</p>
<blockquote>
<p>call()의 경우 아래와 같은 방식으로 똑같이 사용할 수 있습니다.</p>
</blockquote>
<pre><code class="language-javascript">Person.call(foo, &#39;foo&#39;, 30, &#39;man&#39;);</code></pre>
<hr>
<p>위에서 함수 호출 시 자동으로 전달되는 <strong>arguments 객체</strong>에 대해 다뤘었죠. arguments 객체는 배열과 비슷하지만 배열 객체는 아니기 때문에 표준 배열 메서드는 사용할 수 없다고 하였습니다. 하지만 call()이나 apply() 메서드를 이용하면 이러한 문제를 해결할 수 있습니다.</p>
<pre><code class="language-javascript">function myFunc() {
  // args는 arguments 객체 내 인자를 똑같이 가진 배열 객체!
  var args = Array.prototype.slice.apply(arguments);
}</code></pre>
<p>위와 같이 코드를 작성하면 Array.prototype.slice 함수의 this가 arguments로 바인딩되어 결과적으로는 arguments.slice()와 같은 형태로 함수를 사용할 수 있습니다.
여기서 slice()함수는 인자를 따로 넘겨주지 않은 배열 전체가 복사되기 때문에 arguments 객체 내 모든 인자를 가진 배열을 args가 받을 수 있게 됩니다.</p>
<hr>
<h2 id="💡함수-리턴">💡함수 리턴</h2>
<p>javascript의 함수는 항상 리턴값을 반환합니다. 이러한 반환은 아래의 규칙을 따릅니다.</p>
<blockquote>
<p><strong>1. 일반 함수나 메서드는 리턴값을 지정하지 않을 경우, undefined 값이 리턴된다.</strong>
<strong>2. 생성자 함수에서 리턴값을 지정하지 않을 경우 생성된 객체가 리턴된다.</strong></p>
</blockquote>
<p>2번 규칙의 경우는 이해를 돕고자 예시 코드를 보면 좋습니다.</p>
<pre><code class="language-javascript">// Person() 생성자 함수
function Person(name, age, gender) {
  this.name = name;
  this.age = age;
  this.gender = gender;

  // 명시적으로 다른 객체 반환
  return {name:&#39;bar&#39;, age:20, gender:&#39;woman&#39;};
}

var foo = new Person(&#39;foo&#39;, 30, &#39;man&#39;);
console.log(foo);         // 출력 : {name: &#39;bar&#39;, age: 20, gender: &#39;woman&#39;}</code></pre>
<hr>
<h2 id="💡프로토타입-체이닝">💡프로토타입 체이닝</h2>
<p>Javascript는 <strong>프로토타입 기반의 객체지향 프로그래밍</strong>을 지원합니다. 따라서 Javascript의 동작 과정을 이해하기 위해서는 프로토타입의 개념을 잘 알고 있을 필요가 있습니다.</p>
<p>Javascript에서는 따로 클래스 개념이 존재하지 않습니다. 대신 생성자 함수를 이용하여 객체를 생성할 수 있었죠. 이렇게 생성된 객체의 부모 객체가 바로 <strong>프로토타입</strong> 객체입니다. 프로토타입 객체 내 프로퍼티나 메서드는 자식 객체에서 호출하여 사용할 수 있습니다.</p>
<p>Javascript의 모든 객체는 자신의 부모인 프로토타입 객체를 가리키는 참조 링크 형태의 프로퍼티가 있습니다. 이는 <strong>[[Prototype]]</strong>으로, [[Prototype]]에 담겨진 링크는 <strong>암묵적 프로토타입 링크</strong>라고 부릅니다.</p>
<blockquote>
</blockquote>
<h3 id="prototype-프로퍼티-prototype">prototype 프로퍼티? [[Prototype]]?</h3>
<p>함수객체의 prototype 프로퍼티와 객체의 [[Prototype]]는 구분할 수 있어야 합니다.
<strong>prototype 프로퍼티</strong>는 함수가 생성자 함수로 사용될 때, 이후 <strong>생성된 객체의 프로토타입 객체</strong>를 가리키는 것입니다.
반면 <strong>[[Prototype]]</strong>는 해당 <strong>객체의 부모의 링크</strong>를 저장하고 있는 프로퍼티입니다.</p>
<hr>
<h2 id="💡프로토타입-체이닝-1">💡프로토타입 체이닝</h2>
<p>앞에서 말했듯, Javascript의 객체는 자신의 프로토타입 객체의 프로퍼티와 메서드를 자신의 것처럼 접근하는 것이 가능합니다. 이것이 가능하게끔 하는 것이 <strong>프로토타입 체이닝</strong>입니다.</p>
<p>객체는 생성 방식에 따라서 프로토타입 객체가 다를 수 있습니다. 예를 들어 <strong>리터럴 방식</strong>으로 생성된 객체는 프로토타입 객체가 <strong>Object()</strong>인 반면, <strong>생성자 함수 방식</strong>으로 생성된 객체는 프로토타입 객체는 <strong>constructor 프로퍼티만 지닌 객체</strong>입니다.
따라서 리터럴 방식으로 생성된 객체는 프로토타입 체이닝에 의해 Object()가 지닌 메서드인 hasOwnProperty()를 사용할 수 있지만, 생성자 함수 방식으로 생성된 객체는 이를 사용할 수 없습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[h01010] 프로토타입 체이닝(후반부) ]]></title>
            <link>https://velog.io/@argos_js/h01010-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-%EC%B2%B4%EC%9D%B4%EB%8B%9D%ED%9B%84%EB%B0%98%EB%B6%80</link>
            <guid>https://velog.io/@argos_js/h01010-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-%EC%B2%B4%EC%9D%B4%EB%8B%9D%ED%9B%84%EB%B0%98%EB%B6%80</guid>
            <pubDate>Wed, 13 Oct 2021 13:48:12 GMT</pubDate>
            <description><![CDATA[<h3 id="454-프로토타입-체이닝의-종점">4.5.4 프로토타입 체이닝의 종점</h3>
<p>자바스크립트에서 Object.prototype 객체는 <strong>프로토타입 체이닝의 종점</strong>이다.</p>
<p>앞에서 봤듯이 객체 리터럴 방식이나 생성자 함수를 이용한 방식이나 결국엔 Object.prototype에서 프로토타입 체이닝이 끝난다.
달리 해석하면, <strong>객체 리터럴 방식이나 생성자 함수 방식에 상관없이 모든 자바스크립트 객체는 프로토타입 체이닝으로 Object.prototype 객체가 가진 프로퍼티와 메서드에 접근 및 공유가 가능하다</strong>는 의미이다.</p>
<p>때문에 자바스크립트 표준 빌트인 객체인 Object.prototype에는 hasOwnProperty()나 isPrototypeOf() 등과 같이 <strong>모든 객체가 호출 가능한 표준 메서드</strong>들이 정의되어 있다.</p>
<h3 id="455-기본-데이터-타입-확장">4.5.5 기본 데이터 타입 확장</h3>
<p>Object.prototype에 정의된 메서드들은 자바스크립트의 모든 객체의 표준 메서드이다.</p>
<p>이와 같은 방식으로 자바스크립트의 숫자, 문자열, 배열 등에서 사용되는 표준 메서드들의 경우,
Number.prototype, String.prototype, Array.prototype 등에 정의되어있다.
물론 이러한 객체들 또한 Object.prototypedmf 자신의 프로토타입으로 가지고 있어서 <strong>프로토타입 체이닝</strong>으로 연결된다.</p>
<p>표준 빌트인 프로토타입 객체에도 <strong>사용자가 직접 정의한 메서드들을 추가할 수 있다.</strong></p>
<pre><code class="language-javascript">String.prototype.testMethod = function () {
    console.log(&quot;hihi&quot;);
};

var str = &quot;this is test&quot;;
str.testMethod();

console.dir(String.prototype);</code></pre>
<p><img src="https://images.velog.io/images/argos_js/post/4e63e24a-e10f-4ab9-874e-1fa690b9ebad/image.png" alt=""></p>
<p>위 그림에도 나와있듯이 <strong>String.prototype 또한 자신의 프로토타입이 있고, 그것이 바로 Object.prototype이라는 것</strong>이다.
따라서 문자열 또한 프로토타입 체이닝으로 hasOwnProperty() 같은 Object.prototype 메서드를 호출 할 수 있다.</p>
<h3 id="456-프로토타입도-자바스크립트-객체다">4.5.6 프로토타입도 자바스크립트 객체다</h3>
<p>함수가 생성될 때, 자신의 prototype 프로퍼티에 연결되는 프로토타입 객체는 <strong>디폴트로 constructor 프로퍼티만을 가진 객체</strong>다.
당연히 프로토타입 객체 역시 자바스크립트 객체이므로 일반 객체처럼 동적으로 프로퍼티를 추가/삭제하는 것이 가능하다.</p>
<pre><code class="language-javascript">function Person(name) {
    this.name = name;
}

var foo = new Person(&#39;foo&#39;);

//foo.sayHello();                // -----------1)

Person.prototype.sayHello = function(){        // ---------2)
    console.log(&#39;Hello&#39;);
}

foo.sayHello();                    // Hello --------3)</code></pre>
<p>1) 아직 sayHello() 메서드가 정의되어있지 않아 에러가 발생한다.
2) foo 객체의 프로토타입 객체인 Person.prototype 객체에 동적으로 sayHello() 메서드를 추가했다.
3) foo에는 sayHello() 메서드가 없지만, 프로토타입 체이닝으로 Person.prototype 객체에서 sayHello() 메서드를 검색한다.</p>
<h3 id="457-프로토타입-메서드와-this-바인딩">4.5.7 프로토타입 메서드와 this 바인딩</h3>
<p>프로토타입 객체는 메서드를 가질 수 있다(짧게는 <strong>프로토타입 메서드</strong>라고도 부른다).</p>
<p>만약 프로토타입 메서드 내부에서 this를 사용하면 어떻게 될까?
이는 this 바인딩 규칙을 따른다. 결국, 메서드 호출 패턴에서의 <strong>this는 그 메서드를 호출한 객체에 바인딩된다는 것</strong>을 기억하자.</p>
<pre><code class="language-javascript">function Person(name) {
    this.name = name;
}

Person.prototype.getName = function(){        -------1)
    return this.name;
}

var foo = new Person(&#39;foo&#39;);

console.log(foo.getName());                    // foo -----2)

Person.prototype.name = &#39;person&#39;;

console.log(Person.prototype.getName());    ----------3)</code></pre>
<p>1) getName() 메서드는 내부에 this를 포함하고 있다.
2) foo 객체에서 getName() 메서드를 호출하면, foo 객체에서 찾을 수 없으므로 프로토타입 체이닝이 발생한다. foo 객체의 프로토타입 객체인 Person.prototype에서 getName() 메서드가 있으므로, 이 메서드가 호출된다. 이때 getName() 메서드를 호출한 객체는 foo이므로, this는 foo 객체에 바인딩된다.
3) Person.prototype.getName() 메서드와 같이 프로토타입 체이닝이 아니라, 바로 객체에 접근해서 getName() 메서드를 호출하면, 이때는 getName() 메서드를 호출한 객체가 Person.prototype이므로 this도 여기에 바인딩 된다.</p>
<h3 id="458-디폴트-프로토타입은-다른-객체로-변경이-가능하다">4.5.8 디폴트 프로토타입은 다른 객체로 변경이 가능하다</h3>
<p>디폴트 프로토타입 객체는 함수가 생성될 때 같이 생성되며, 함수의 prototype 프로퍼티에 연결된다.
자바스크립트에서는 이렇게 함수를 생성할 때 해당 함수와 연결되는 <strong>디폴트 프로토타입 객체를 다른 일반 객체로 변경하는 것이 가능하다.</strong> 이러한 특징을 이용해서 객체지향의 상속을 구현한다.
(* 6장에서 더 나옴)</p>
<p>하지만, 생성자 함수의 프로토타입 객체가 변경되면, 변경된 시점 이후에 생성된 객체들은 변경된 프로토타입 객체로 [[Prototype]] 링크를 연결한다는 점을 기억해야 한다.
이에 반해 생성자 함수의 프로토타입이 변경되기 이전에 생성된 객체들은 기존 프로토타입 객체로의 [[Prototype]] 링크를 그대로 유지한다.</p>
<pre><code class="language-javascript">function Person(name) {                     
    this.name = name;
}

console.log(Person.prototype.constructor);    // Person(name) ----------1)

var foo = new Person(&#39;foo&#39;);
console.log(foo.country);                    // undefined -------------2)

Person.prototype = {                        -------------------------3)
    country: &#39;kor&#39;,
};

console.log(Person.prototype.constructor);    // Object() ---------------4)

var bar = new Person(&#39;bar&#39;);
console.log(bar.country);                    // kor ---------------5)</code></pre>
<p>1) Person() 함수를 생성할 때 디폴트로 같이 생성되는 Person.prototype 객체는 자신과 연결된 Person() 생성자 함수를 가리키는 constructor 프로퍼티만을 가진다. 때문에 Person.prototype.constructor는 Person() 생성자 함수를 가리킨다.
2) foo 객체를 생성하면 foo 객체는 Person.prototype 객체를 자신의 프로토타입으로 연결한다. 그러나 foo 객체는 country 프로퍼티가 없고 또한, 디폴트 프로토타입 객체 Person.prototype도 country 프로퍼티가 없으므로 프로토타입 체이닝이 일어나도 결국 undefined 값이 출력된다.
3) 프로토타입 객체를 country 프로퍼티를 가진 객체로 변경하였다. 
4) Person.prototype.constructor이 없기때문에 이 경우도 <strong>프로토타입 체이닝이 발생</strong>한다. 변경한 프로토타입 객체는 객체 리터럴 방식으로 생성했으므로 <strong>Object.prototype을 [[Prototype]]</strong> 링크로 연결한다. 따라서 Object.prototype 객체로 프로토타입 체이닝이 발생한다.
5) 이제 bar는 새로 변경된 프로토타입 객체를 [[Prototype]]로 연결한다.</p>
<h3 id="459-객체의-프로퍼티-읽기나-메서드를-실행할-때만-프로토타입-체이닝이-동작한다">4.5.9 객체의 프로퍼티 읽기나 메서드를 실행할 때만 프로토타입 체이닝이 동작한다</h3>
<p>객체의 특정 프로퍼티를 읽으려고 할 때, <strong>프로퍼티가 해당 객체에 없는 경우 프로토타입 체이닝이 발생</strong>한다. 반대로 객체에 있는 특정 프로퍼티에 값을 쓰려고 한다면 이때는 프로토타입 체이닝이 일어나지 않는다. (당연한 얘기!!)</p>
<p>자바스크립트는 <strong>객체에 없는 프로퍼티에 값을 쓰려고 할 경우 동적으로 객체에 프로퍼티를 추가하기 때문</strong>이다.</p>
<pre><code class="language-javascript">function Person(name) {                     
    this.name = name;
}

Person.prototype.country = &#39;Korea&#39;;

var foo = new Person(&#39;foo&#39;);
var bar = new Person(&#39;bar&#39;);
console.log(foo.country);            // Korea    
console.log(bar.country);            // Korea    -------1)

foo.country = &#39;USA&#39;;                // ----------------2)

console.log(foo.country);            // USA
console.log(bar.country);            // Korea    -------3)</code></pre>
<p>foo와 bar 객체는 둘 다 Person.prototype 객체를 프로토타입으로 가진다.</p>
<p>1) foo.country에 접근하려 했을 때 foo 객체는 name 프로퍼티밖에 없으므로 프로토타입 체이닝이 이뤄지면서 foo의 프로토타입 객체인 Person.prototype의 country 프로퍼티인 &#39;Korea&#39;가 출력된다.
2) 1과 반대로 &#39;USA&#39;를 저장하면, <strong>프로토타입 체이닝이 동작하지 않고 foo 객체에 country 프로퍼티값이 동적으로 생성</strong>된다.
3) bar 객체만 프로토타입 체이닝을 거쳐 &#39;Korea&#39;가 출력된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[purplepig4657]함수 객체와 함수의 다양한 형태]]></title>
            <link>https://velog.io/@argos_js/purplepig4657%ED%95%A8%EC%88%98-%EA%B0%9D%EC%B2%B4%EC%99%80-%ED%95%A8%EC%88%98%EC%9D%98-%EB%8B%A4%EC%96%91%ED%95%9C-%ED%98%95%ED%83%9C</link>
            <guid>https://velog.io/@argos_js/purplepig4657%ED%95%A8%EC%88%98-%EA%B0%9D%EC%B2%B4%EC%99%80-%ED%95%A8%EC%88%98%EC%9D%98-%EB%8B%A4%EC%96%91%ED%95%9C-%ED%98%95%ED%83%9C</guid>
            <pubDate>Wed, 13 Oct 2021 11:32:18 GMT</pubDate>
            <description><![CDATA[<h2 id="자바스크립트에서-함수는-객체다">자바스크립트에서 함수는 객체다</h2>
<p>자바스크립트에서 함수는 &#39;코드의 실행&#39;뿐만 아니라 함수 자체가 객체처럼 프로퍼티(property)를 가질 수 있다.</p>
<blockquote>
<ul>
<li>함수를 생성할 때, 함수 코드는 함수 객체의 [[Code]] 내부 프로퍼티에 저장된다.</li>
</ul>
</blockquote>
<ul>
<li>함수는 프로퍼티를 가질 수 있다.</li>
<li>함수는 일반 객체와는 달리 특정 기능의 코드를 수행할 수 있을 뿐만 아니라, 일반 객체처럼 프로퍼티를 가질 수 있는 특별한 객체이다.</li>
</ul>
<p>다음 예제를 통해 이를 살펴보자.</p>
<pre><code class="language-javascript">function a() {
    return 0;
}

a.b = 0;
a.c = 1;

a(); // 0
a.b; // 0
a.c; // 1</code></pre>
<p>이처럼 여기서 생성한 a라는 함수는 코드의 실행뿐 아니라 b와 c라는 프로퍼티도 또한 가질 수 있다.</p>
<h2 id="자바스크립트에서-함수는-값으로-취급된다">자바스크립트에서 함수는 값으로 취급된다</h2>
<p>자바스크립트에서 함수는 객체로 취급된다고 언급했다. 따라서 우린 함수를 값으로도 사용할 수 있다. 자바스크립트에서 함수는 다음과 같은 동작이 가능하다.</p>
<blockquote>
<ul>
<li>리터럴에 의해 생성</li>
</ul>
</blockquote>
<ul>
<li>변수 등에 할당 가능</li>
<li>함수의 인자로 전달가능</li>
<li>함수의 리턴값으로 리턴 가능</li>
</ul>
<p>이와 같은 특징을 가지고 있는 함수를 일급 객체(First Class)라고 하며, 자바스크립트에서 함수는 일급 객체이다.</p>
<p>다음 예시는 자바스크립트의 함수가 일급 객체라는 것을 보인다.</p>
<ul>
<li>함수를 변수의 값으로 할당이 가능하다.</li>
</ul>
<pre><code class="language-javascript">var a = function() {
    return 0;
}

a(); // 0</code></pre>
<ul>
<li>함수의 인자로 전달이 가능하다.</li>
</ul>
<pre><code class="language-javascript">function b() {
    return 0;
}

function a(func) {
    return func();
}

a(b); // 0</code></pre>
<ul>
<li>리턴값으로 활용이 가능하다.</li>
</ul>
<pre><code class="language-javascript">function a() {
    return function() {
        return 0;
    }
}

a()(); // 0</code></pre>
<h2 id="함수-객체의-기본-프로퍼티">함수 객체의 기본 프로퍼티</h2>
<p>함수는 알반 객체와 다르게, 함수 객체만의 표준 프로퍼티가 정의되어 있다.</p>
<p>ECMA 표준</p>
<blockquote>
<ul>
<li>length - 함수가 실행될 때 기대되는 인자의 개수를 나타낸다.</li>
</ul>
</blockquote>
<ul>
<li>prototype property - 함수가 생성자로 사용될 때, 이 함수로 생성된 객체의 부모 프로토타입 객체를 나타낸다.</li>
</ul>
<p>다음은 ECMA 표준 프로퍼티가 아니다.</p>
<blockquote>
<ul>
<li>name - 함수의 이름을 나타낸다.</li>
</ul>
</blockquote>
<ul>
<li>caller - 자신의 호출한 함수를 나타낸다.</li>
<li>arguments - 함수를 호출할 때 전달된 인자값을 나타낸다.</li>
<li>__proto__ ([[Prototype]] property != Prototype property) - 자신의 부모 프로토타입 객체를 나타낸다.</li>
</ul>
<p>다음 예시를 통해 기본 프로퍼티를 알아보자.</p>
<pre><code class="language-javascript">ƒ plus(x, y) {
    return x + y;
}</code></pre>
<p><img src="https://images.velog.io/images/argos_js/post/4c31abca-1f89-481e-a028-cec99aca8529/image.png" alt=""></p>
<p>여기서 함수 객체의 __proto__ 즉, 함수 객체의 부모 프로토타입이 무엇인지 궁금할 것이다. 함수 객체의 부모 역할을 하는 프로토타입 객체는 &#39;Function.prototype 객체&#39;라고 한다. 이는 아무 이름이 없는 함수이고, 따라서 name 프로퍼티는 아무 값을 가지지 않는다.</p>
<p><img src="https://images.velog.io/images/argos_js/post/0a03229c-ad25-4a4f-838c-d98ebd782fb9/image.png" alt=""></p>
<h4 id="prototype-property">Prototype property</h4>
<p>Prototype 프로퍼티는 함수가 생성될 때 만들어지며, constructor 프로퍼티 만을 가지고 있는 객체를 가리킨다. 이때 constructor 프로퍼티는 함수 객체를 가리킨다. 함수 객체에서 Prototype 프로퍼티가 이 프로토타입 객체를 가리키므로 이는 서로를 참조하게 되는 꼴이다.</p>
<h2 id="함수의-다양한-형태">함수의 다양한 형태</h2>
<h3 id="콜백-함수">콜백 함수</h3>
<p>자바스크립트 함수 표현식에서 함수 이름은 꼭 붙이지 않아도 되고, 이를 익명 함수라고 부른다.</p>
<pre><code class="language-javascript">var a = function() //익명 함수 {
    return 0;
}</code></pre>
<p>이러한 익명 함수의 대표적인 활용은 바로 &#39;콜백 함수&#39;다. 콜백 함수는 어떤 이벤트가 발생하면 시스템에서 호출되는 함수를 말한다. 또한, 특정 함수에 인자로 넘겨져서 호출되는 함수도 콜백 함수라 한다.</p>
<p>이 콜백 함수의 대표적인 활용 예시는 다음과 같다.</p>
<pre><code class="language-javascript">&lt;script&gt;
    window.onload = function() {
        console.log(&quot;load!&quot;);
    }
&lt;/script&gt;</code></pre>
<p>window.onload는 이벤트 핸들러이고, 이 이벤트 핸들러에 익명 함수를 연결했다. 웹 페이지가 로드되는 이벤트가 발생한다면 console.log를 실행하게 된다.</p>
<h3 id="즉시-실행-함수">즉시 실행 함수</h3>
<p>즉시 실행 함수는 함수를 정의함과 동시에 실행하는 함수이다. 다음 예시를 보자.</p>
<pre><code class="language-javascript">(function(str) {
    console.log(str);
})(&quot;Hello&quot;);</code></pre>
<p>이렇게 선언되자마자 실행되도록 만든 즉시 실행 함수는 다시 호출이 불가능하다. 따라서 최초 한 번만 실행하는 함수를 사용할 때 유용하다. 예를 들어, 라이브러리의 초기화(한 번만 실행) 코드를 즉시 실행 함수를 사용하여 구현한다면, 변수 명의 중복 문제를 해결할 수 있어 유용하다.</p>
<h3 id="내부-함수">내부 함수</h3>
<p>자바스크립트는 함수 코드 내부에 또다시 함수 정의가 가능하다. 이렇듯 함수 내부에 정의된 함수를 &#39;내부 함수(Inner function)&#39;이라고 한다. 다음 예시를 보자.</p>
<pre><code class="language-javascript">function a() {
    var i = 0;
    var j = 1;

    function b() {
        var i = 1;
        console.log(i); // 1
        console.log(j); // 1
    }

    b();
}

b(); // error</code></pre>
<p>내부 함수는 자바스크립트의 &#39;스코프 체이닝&#39;과 함께 특별한 기능을 한다. 여기서 b함수에서 i를 호출할 때 b함수 바깥에 있는 i가 아닌, b함수 안에 있는 i가 출력이 되었다. 또한 b함수는 j를 가지고 있지 않지만 j를 출력해주었다. 이는 b함수 밖의 j를 참조하여 출력하는 과정이 있다. 스코프 체이닝 덕분에 함수 밖에서 선언된 변수나 함수에 접근이 가능한 것이다.</p>
<p>맨 마지막 b함수를 b함수가 정의된 a함수 바깥에서 호출하는 코드가 있는데, 이는 오류를 발생시킨다. b함수의 스코프가 a함수 안이기 때문에 이런일이 발생하는 것이다. 하지만 외부에서 내부 함수에 접근할 수 있는 방법이 있다. 다음 예시를 보자.</p>
<pre><code class="language-javascript">function a() {
    var i = 0;
    var b = function() {
        return i;
    }

    return b;
}

var c = a();
c(); // 0</code></pre>
<p>자바스크립트에서의 함수는 일급 객체다. 따라서, 함수를 리턴값으로 사용할 수 있다. a함수는 내부 함수b의 &#39;참조값&#39;을 반환한다. 이를 변수 c에 저장하고 c를 호출한다면, b함수가 실행된다. 외부에서 내부 함수를 실행한 것이다. 또한 여기서 a함수 내부의 변수 i를 외부로 끄집어 낸 것을 알 수 있는데, 이렇게 부모 함수 스코프의 변수를 참조하는 b함수를 &#39;클로저&#39;라 부른다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[h01010] 프로토타입과 배열]]></title>
            <link>https://velog.io/@argos_js/h01010-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85%EA%B3%BC-%EB%B0%B0%EC%97%B4</link>
            <guid>https://velog.io/@argos_js/h01010-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85%EA%B3%BC-%EB%B0%B0%EC%97%B4</guid>
            <pubDate>Wed, 06 Oct 2021 12:02:20 GMT</pubDate>
            <description><![CDATA[<h2 id="34-프로토타입">3.4 프로토타입</h2>
<p><strong>모든 객체는 자신의 부모 역할을 하는 객체와 연결되어 있다.</strong>
이것은 마치 객체지향의 상속개념과 같이 부모 객체의 프로퍼티를 마치 자신의 것처럼 쓸 수 있는 것 같은 특징이 있다.
자바스크립트에서는 이러한 부모 객체를 <strong>프로토타입 객체(짧게는 프로토타입)</strong> 라고 부른다.</p>
<pre><code class="language-javascript">var foo = {
    name: &#39;foo&#39;,
    age: 30
};

console.log(foo.toString());    // [object Object]    -----1)
console.dir(foo);                // foo 객체 출력    -------2)</code></pre>
<p><img src="https://images.velog.io/images/argos_js/post/9037dc9d-3b27-4c39-98b1-39188ea8ff21/image.png" alt=""></p>
<p>1) 앞 예제는 단순히 객체 리터럴 방식으로 foo 객체를 생성하였고 toString() 메서드는 없다. 정상적으로 결과가 나온 이유는 바로 <strong>foo 객체의 프로토타입</strong>에 toString() 메서드가 이미 정의 되어있고, foo 객체가 상속처럼 toString() 메서드를 호출했기 때문이다.
2) 객체를 출력해보면, name과 age 프로퍼티 외에도 <strong><strong>proto</strong> 프로퍼티</strong>가 있다는 것을 확인할 수 있다. 이 프로퍼티는 foo객체의 부모인 <strong>프로토타입 객체</strong>를 가리킨다. 이 객체를 펼쳐보면 toString() 메소드가 정의되어있는 것을 알 수 있다.</p>
<p>ECMAScript 명세서에는 자바스크립트의 <strong>모든 객체는 자신의 프로토타입을 가리키는 [[Prototype]]라는 숨겨진 프로퍼티</strong>를 가진다고 설명하고 있다.
즉, 위에서 foo객체는 자신의 부모 객체를 <strong>prototype</strong>라는 내부 프로퍼티로 연결하고 있는 것이다.</p>
<p>모든 객체의 프로토타입은 자바스크립트의 룰에 따라 객체를 생성할 때 결정되며(프로토타입 체이닝에서 설명) 후에 임의의 다른 객체로 변경하능하다.
<strong>객체 리터럴 방식으로 생성된 객체의 경우 Object.prototype 객체(<strong>proto</strong>)가 프로토타입 객체가 된다는 것</strong>을 기억해야한다.</p>
<p><img src="https://images.velog.io/images/argos_js/post/b74db585-554c-41f4-a201-5dfd35099708/image.png" alt="">
출처 : <a href="https://boycoding.tistory.com/16">https://boycoding.tistory.com/16</a></p>
<p>__proto__에는 toString(), valueOf() 등과 같은 모든 객체에서 호출 가능한 자바스크립트 기본 내장 메서드가 포함되어있다.</p>
<h2 id="35-배열">3.5 배열</h2>
<p>배열은 자바스크립트 객체의 한 형태이다.
C나 자바와 같은 기능을 하지만, 크기를 지정하지 않아도 되고 어떤 위치의 어느 타입의 데이터를 저장하더라도 에러가 발생하지 않는다.</p>
<h3 id="351-배열-리터럴">3.5.1 배열 리터럴</h3>
<p><strong>배열 리터럴</strong>은 자바스크립트에서 새로운 배열을 생성하는 데 사용하는 표기법이다.</p>
<ul>
<li>객체 리터럴 : {}</li>
<li>배열 리터럴 : []</li>
</ul>
<pre><code class="language-javascript">var color = [&#39;orange&#39;, &#39;yellow&#39;, &#39;blue&#39;, &#39;green&#39;, &#39;red&#39;];

console.log(color[0]);    // orange
console.log(color[4]);    // red</code></pre>
<p>배열 리터럴에서는 <strong>각 요소의 값</strong>만 포함하며, 인덱스로 접근할 수 있다.</p>
<h3 id="352-배열의-요소-생성">3.5.2 배열의 요소 생성</h3>
<p>배열도 동적으로 배열 원소를 추가할 수 있다.
자바스크립트 배열의 경우는 값을 순차적으로 넣지 않아도 아무 인덱스 위치에나 값을 동적으로 추가할 수 있다.</p>
<pre><code class="language-javascript">var emptyArr = [];
console.log(emptyArr[0]);    // undefined

emptyArr[1] = 1;
emptyArr[4] = &#39;four&#39;;
emptyArr[5] = true;

console.log(emptyArr);        // [undefined, 1, undefined x 2, &#39;four&#39;, true]</code></pre>
<p>자바스크립트 객체에기 때문에 객체에서도 포함하지 않은 객체의 프로퍼티에 접근한 경우 undefined가 출력된 것과 같이 배열의 경우도 값이 없는 원소에 접근할 경우 undefined가 출력된다.</p>
<h3 id="353-배열의-length-프로퍼티">3.5.3 배열의 length 프로퍼티</h3>
<p>모든 배열은 <strong>length 프로퍼티</strong>가 있다.
배열의 원소 개수를 나타내지만, 실제로 배열에 존재하는 원소 개수와 일치하는 것은 아니다.</p>
<pre><code class="language-javascript">console.log(emptyArr.length);    // 6

emptyArr.length = 8;
console.log(emptyArr);        // [undefined, 1, undefined x 2, &#39;four&#39;, true, undefined x 2]</code></pre>
<p>length 프로퍼티는 <strong>배열 내에 가장 큰 인덱스에 1을 더한 값</strong>이며, 배열의 가장 큰 인덱스 값이 변하면, length도 자동으로 바뀐다.
하지만 실제 메모리는 <strong>length크기처럼 할당되지는 않는다.</strong></p>
<p>배열의 length 프로퍼티는 코드를 통해 명시적으로 값을 변경할 수도 있다.
값을 증가시키면 undefined가 추가되며, 감소시키면 값이 잘려 출력된다.</p>
<p>자바스크립트는 배열에서 사용 가능한 다양한 표준 메서드를 제공한다.
이러한 메서드들은 length 프로퍼티를 기반으로 동작한다.
예를 들어, push 함수는 length 인덱스에 요소를 추가한다.</p>
<h3 id="354-배열과-객체">3.5.4 배열과 객체</h3>
<p>자바스크립트에서 배열은 객체라고 하였다.
하지만 배열은 일반 객체와는 약간 차이가 있다.</p>
<pre><code class="language-javascript">var colorsArray = [&#39;orange&#39;, &#39;yellow&#39;, &#39;green&#39;];
console.log(colorsArray[1]);    // yellow

var colorsObj = {
    &#39;0&#39;: &#39;orange&#39;,
    &#39;1&#39;: &#39;yellow&#39;,
    &#39;2&#39;: &#39;green&#39;
};
console.log(colorsObj[1]);        // yellow        ----------1)

// typeof 연산자 비교
console.log(typeof colorsArray);    // object    ----------2)
console.log(typeof colorObj);        // object

// length 프로퍼티
console.log(colorsArray.length);    // 3
console.log(colorObj.length);        // undefined ----------3)

// 배열 표준 메서드    ----------4)
colorsArray.push(&#39;red&#39;);    // 됨
colorsObj.push(&#39;red&#39;);        // Uncaught TypeError: Object #&lt;Object&gt; has no method &#39;push&#39;</code></pre>
<p>1) 객체 프로퍼티를 접근할 때는 프로퍼티 속성을 <strong>문자열 형태</strong>로 적어야하지만, 자바스크립트 엔진이 []연산자 내에 숫자가 사용될 경우, 해당 숫자를 자동으로 문자열 형태로 바꿔주기 때문에 에러를 내지 않는다.
2) 배열도 object이다.
3) 객체엔 length 프로퍼티가 존재하지 않는다.
4) <strong>배열과 객체가 자신의 부모인 프로토타입 객체가 서로 다르기 때문에</strong> 객체는 push() 메서드가 없어 에러를 출력한다.</p>
<p>배열의 경우 <strong>Array.prototype객체</strong>가 부모 객체인 프로토타입이 된다.
Array.prototype 객체는 배열에서 사용하는 push(), pop() 등과 같은 표준 메서드를 포함하고 있다.
<strong>Array.prototype 객체의 프로토타입은 Object.prototype 객체이다.</strong></p>
<p><img src="https://images.velog.io/images/argos_js/post/cb13f85e-6ce9-4b61-ae40-ae9c13d3d969/image.png" alt="">
출처 : <a href="https://boycoding.tistory.com/16">https://boycoding.tistory.com/16</a></p>
<p><img src="https://images.velog.io/images/argos_js/post/5720a458-7859-40a9-a4cf-166eaf0b3099/image.png" alt="">
캡쳐에 있는 Array[0] 객체가 바로 Array.prototype 객체를 나타낸다.
그리고 Array.prototype 객체 역시 __proto__프로퍼티를 가지고 있는데, 이 값은 Object.prototype을 가리킨다.</p>
<h3 id="355-배열의-프로퍼티-동적-생성">3.5.5 배열의 프로퍼티 동적 생성</h3>
<p>배열도 자바스크립트 객체이므로, 인덱스가 숫자인 배열 원소 이외에도 &#39;name&#39;, &#39;age&#39;와 같은 프로퍼티들을 동적으로 추가할 수 있다.</p>
<pre><code class="language-javascript">var arr = [&#39;zero&#39;,&#39;one&#39;,&#39;two&#39;];
arr.color = &#39;blue&#39;;
arr.name = &#39;number_array&#39;;

console.log(arr.legnth);    // 3</code></pre>
<p><img src="https://images.velog.io/images/argos_js/post/36d28e43-6abd-48da-9dbb-421b1450dc16/image.png" alt="">
프로퍼티를 추가한다고 length값이 바뀌지는 않는다.
배열의 length 프로퍼티 배열 원소의 가장 큰 인덱스가 변했을 경우만 변경된다.</p>
<h3 id="356-배열의-프로퍼티-열거">3.5.6 배열의 프로퍼티 열거</h3>
<p>객체는 for in 문으로 프로퍼티를 열거할 수 있다.
배열도 객체이므로 for in 문을 사용하여 배열 내의 모든 프로퍼티를 열거할 수 있지만, 이렇게 되면 불필요한 프로퍼티가 출력될 수 있으므로 <strong>되도록 for 문을 사용하는 것</strong>이 좋다.</p>
<pre><code class="language-javascript">for (var prop in arr) {
    console.log(prop, arr[prop]);
}
for (var i=0; i&lt;arr.length; i++){
    console.log(i, arr[i]);
}</code></pre>
<p><img src="https://images.velog.io/images/argos_js/post/0489412d-a547-4d89-aa52-39faf85a90c1/image.png" alt=""></p>
<h3 id="357-배열-요소-삭제">3.5.7 배열 요소 삭제</h3>
<p>배열도 객체이므로, 배열 요소나 프로퍼티를 삭제하는 데 <strong>delete</strong> 연산자를 사용할 수 있다.</p>
<pre><code class="language-javascript">var arr = [&#39;zero&#39;,&#39;one&#39;,&#39;two&#39;];
delete arr[2];
console.log(arr);            // [&#39;zero&#39;,&#39;one&#39;,undefined]
console.log(arr.length);    // 3</code></pre>
<p>delete 연산자는 해당 요소의 값을 undefined로 설정할 뿐 원소 자체를 삭제하지는 않는다.</p>
<p>때문에 보통 배열에서 요소들을 완전히 삭제할 경우 <strong>splice () 배열 메서드</strong>를 사용한다.</p>
<blockquote>
<p>splice(startIndex, countOfWillingToDelete, item...);
countOfWillingToDelete : startIndex부터 삭제할 요소 수
item : 삭제할 위치에 추가할 요소</p>
</blockquote>
<pre><code class="language-javascript">var arr = [&#39;zero&#39;,&#39;one&#39;,&#39;two&#39;];
arr.splice(1,1);
console.log(arr);            // [&#39;zero&#39;,&#39;two&#39;]
console.log(arr.length);    // 2</code></pre>
<h3 id="358-array-생성자-함수">3.5.8 Array() 생성자 함수</h3>
<p>배열은 일반적으로 배열 리터럴로 생성하지만, 배열 리터럴도 결국 자바스크립트 기본 제공 Array () 생성자 함수로 배열을 생성하는 과정을 단순화시킨 것이다.</p>
<p>Array()로 생성하는 방법(new 연산자로 생성)은 간단히 알아두기만 하면 된다.</p>
<pre><code class="language-javascript">var foo = new Array(3);    // 길이를 넣음
console.log(foo);        //[undefined,undefined,undefined]

var bar = new Array(1,2,3);
console.log(bar);        //[1,2,3]</code></pre>
<p>foo 배열의 경우는 Array() 생성자 함수를 호출할 때 3이라는 숫자 인자 1개만 넘겼으므로, 길이가 3인 빈 배열을 생성하지만, 반면에 bar는 요소를 지정하여 배열을 생성한다.</p>
<h3 id="359-유사-배열-객체">3.5.9 유사 배열 객체</h3>
<p>배열의 length 프로퍼티는 배열의 동작에 있어서 중요한 프로퍼티이다.
일반 객체에 length라는 프로퍼티가 있으면, 이러한 객체를 <strong>유사 배열 객체(array-like objects)</strong> 라고 부른다.</p>
<p>이러한 유사 배열 객체의 가장 큰 특징은 객체지만, <strong>apply() 메서드를 사용하면</strong> 자바스크립트의 표준 배열 메서드(push 등)를 사용하는 게 가능하다.
(그냥 가능하다!정도만 숙지하자)</p>
<p>후에 call과 apply 메서드를 이용한 명시적인 this 바인딩에서 자세히 나올 예정이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ire4564] 기본 타입과 연산자 & 함수 정의]]></title>
            <link>https://velog.io/@argos_js/ire4564-%EA%B8%B0%EB%B3%B8-%ED%83%80%EC%9E%85%EA%B3%BC-%EC%97%B0%EC%82%B0%EC%9E%90-%ED%95%A8%EC%88%98-%EC%A0%95%EC%9D%98</link>
            <guid>https://velog.io/@argos_js/ire4564-%EA%B8%B0%EB%B3%B8-%ED%83%80%EC%9E%85%EA%B3%BC-%EC%97%B0%EC%82%B0%EC%9E%90-%ED%95%A8%EC%88%98-%EC%A0%95%EC%9D%98</guid>
            <pubDate>Wed, 06 Oct 2021 07:18:15 GMT</pubDate>
            <description><![CDATA[<h2 id="1-기본-타입과-표준-메서드">1. 기본 타입과 표준 메서드</h2>
<p>자바스크립트는 숫자, 문자열, 불린 값에 대해 각 타입별로 호출 가능한 표준 메서드를 정의하고 있다.
하지만 기본 타입의 경우에는 객체가 아닌데 어떻게 객체를 호출할 수 있을까. 기본 타입들에 대해서 객체 형태로 메서드를 호출할 경우, 메서드 처리 순간 각 타입별 표준 메서드를 호출하고 끝나면 다시 기본값으로 복귀한다.</p>
<h4 id="예시-1-toexponential--표준-숫자형-메서드-숫자를-지수-형태의-문자열-변환">예시 1) toExponential() : 표준 숫자형 메서드, 숫자를 지수 형태의 문자열 변환</h4>
<pre><code>var num = 0.5;
console.log(num.toExponential(1)) //output: 5.0e-1</code></pre><h4 id="예시-2-charat--문자열에서-인자로-받은-위치에-있는-문자-반환">예시 2) charAt() : 문자열에서 인자로 받은 위치에 있는 문자 반환</h4>
<pre><code>console.log(charAt(2)); //output: &#39;s&#39;</code></pre><blockquote>
<p><strong>POINT</strong> 기본 타입으로 정의된 것도, 정의된 표준 메서드들을 객체처럼 호출할 수 있다는 사실을 기억하자.</p>
</blockquote>
<br/>

<h2 id="2-연산자">2. 연산자</h2>
<p>자바스크립트 연산자 대부분은 다른 연산자들과 유사하기 때문에, 몇가지 주의할 연산자들에 대해서만 정리해보았다.</p>
<h4 id="1-typeof">[1] typeof</h4>
<p>피연산자의 타입을 문자열 형태로 리턴한다. 
이때 유의해야할 점은 <strong>null과 배열이 Object라는 점, 함수는 function이라는 점</strong>을 유의하자.</p>
<pre><code>var hello = &quot;안녕하세요&quot;;
console.log(typeof(hello)); //output: string</code></pre><h4 id="2-동등-연산자와-일치-연산자">[2] 동등 연산자(==)와 일치 연산자(===)</h4>
<p>값이 동일한지 확인하는데, 두 연산자를 모두 사용할 수 있다. <strong>두 가지의 차이는 ===는 타입까지 체크를 한다는 점이다. 반면 ==는 타입이 다를 경우 타입 변환을 거친 다음 비교</strong>를 한다. 가급적 === 연산자로 비교하는 것이 좋다.</p>
<pre><code>console.log(1 == &#39;1&#39;); //output: true
console.log(1 === &#39;1&#39;); //output: false</code></pre><h4 id="3--연산자">[3] !! 연산자</h4>
<p>!!의 역할은 피연산자를 blooean 값으로 변환하는 것이다.</p>
<pre><code>console.log(!!0) //false
console.log(!!true) //true
console.log(!!false) //false
console.log(!!undefined) //false</code></pre><br/>

<h2 id="3-함수-정의">3. 함수 정의</h2>
<p>자바스크립트에서 가장  중요한 개념 1순위는 당연히 <strong>함수이다</strong>. 자바스크립트에서 이러한 함수를 얼마나 제대로 이해하고 활용하느냐에 따라서 고급 자바스크립트 개발자로 거듭날 수 있다. </p>
<p>단순히 호출해서 결과값을 얻는 것에서 벗어나서 자바스크립트의 함수는** 모듈화 처리나, 클로저, 객체 생성** 등 자바스크립트의 근간이 되는 많은 기능을 제공하고 있다. 앞으로 살펴볼 개념은 다음과 같다.</p>
<blockquote>
<ul>
<li>함수 생성</li>
</ul>
</blockquote>
<ul>
<li>함수 객체</li>
<li>다양한 함수 형태</li>
<li>함수 호출과 this</li>
<li>프로토타입과 프로토타입 체이닝</li>
</ul>
<p>함수를 생성하는 방법은 3가지가 있다.</p>
<blockquote>
<p>** 1. 함수 선언문 (function statement)
2. 함수 표현식 (function expression)
3. Function() 생성자 함수**</p>
</blockquote>
<h4 id="1-함수-리터럴">[1] 함수 리터럴</h4>
<p>자바스크립트에서는 함수도 일반 객체처럼 값으로 취급된다. 때문에 함수 리터럴을 이용해 함수를 생성할 수 있다. 리터럴 방식의 예시는 아래와 같다. 참고하면 된다.</p>
<pre><code>function add (x,y) {
    return x + y;
}</code></pre><ol>
<li>함수 리터럴은 function 키워드로 시작한다.</li>
<li>함수명은 함수를 구분하는 식별자로 사용된다. 여기서 주목할 점은 함수 명은 선택 사항이다. 함수 명이 없는 함수를 익명 함수라고 한다.</li>
<li>매개변수 리스트는, 기존 다른 언어의 매개변수 형태와 거의 비슷하지만 타입을 기술하지 않는다는 차이가 있다.</li>
<li>함수 몸체는 함수가 실제 호출됐을 때 실행되는 코드 부분이다.</li>
</ol>
<br/>

<h4 id="2-함수-선언문-방식으로-함수-생성하기">[2] 함수 선언문 방식으로 함수 생성하기</h4>
<p>이 함수 선언문 방식은 앞에서 설명한 함수 리터럴 형태와 같다. 주의할 점은, <strong>이 경우 반드시 함수명이 정의되어 있어야 한다는 것이다.</strong></p>
<pre><code>function add (x,y) {
    return x + y;
}

console.log(add(3,4)); //output: 7</code></pre><br/>

<h4 id="3-함수-표현식-방식으로-함수-생성하기">[3] 함수 표현식 방식으로 함수 생성하기</h4>
<p>함수는 하나의 값처럼 취급되기 때문에, 따라서 함수도 숫자나 문자열처럼 변수에 할당하는 것이 가능하다.
<strong>이러한 방식으로 함수 리터럴로 하나의 함수를 만들고, 여기서 생성된 함수를 변수에 할당하여 함수를 생성하는 것을 &#39;함수 표현식&#39;이라고 말한다.</strong></p>
<pre><code>var add = function(x,y) {
    return x + y;
}

var plus = add;

console.log(add(3,4)); //output: 7
console.log(plus(3,4)); //output: 7</code></pre><p>add와 plus 함수 변수는 두 개의 인자를 더하는 동일한 익명 함수를 참조하는 결과가 나타난다. 이렇게 add안에 선언된 이름이 없는 함수를 &#39;<strong>익명함수</strong>&#39;라고 부른다. 반대로 함수 이름이 포함된 함수 표현식을 &#39;<strong>기명 함수 표현식</strong>&#39;이라고 한다. 그러나 이러한 기명 함수 표현식을 사용할 때는 주의할 점이 있다. </p>
<pre><code>var add = function sum(x,y) {
    return x + y;
}

console.log(add(3,4)); //output: 7
console.log(sum(3,4)); //error!! -&gt; Uncaught ReferenceError: sum is not defined</code></pre><p>sum이 정의되어 있지 않다는 에러가 발생한다. 그렇다면 함수 선언문으로 정의한 add() 함수는 어떻게 함수 이름으로 함수 외부에서 호출이 가능할까? 위의 함수는 자바스크립트 엔진에 의해 다음과 같은 표현식의 형태로 변경된다.</p>
<pre><code>var add = function add(x,y) {
    return x + y;
}
</code></pre><blockquote>
<p>POINT 함수 이름이 같게 변하므로, 함수 이름으로 함수가 호출되는 것처럼 보이지만 실제로는 add 함수 변수로 외부에서 호출이 가능하게 된 것이다.</p>
</blockquote>
<ul>
<li>주의할 점
일반적으로 자바스크립트 코드를 작성할 때, 함수 선언문 방식으로 선언된 함수의 경우에는 함수 끝에 세미클론(;)을 붙이지 않지만, 함수 표현식의 방식의 경우에는 세미클론을 붙이는 것을 적극 권장한다. (예상치 못한 에러가 발생할 수 있기 때문에)</li>
</ul>
<br/>

<h4 id="4-function-생성자-함수를-통한-함수-생성하기">[4] Function() 생성자 함수를 통한 함수 생성하기</h4>
<p>자바스크립트 함수도 Function이라는 기본 내장 생성자 함수로부터 생성된 객체라고 볼 수 있다. 생성자 함수로 함수를 생성하는 방법은 다음과 같다. 하지만 이 방법은 잘 사용되지 않으므로 <strong>참고</strong>만 해도 된다.</p>
<pre><code>var add = new Function(&#39;x&#39;, &#39;y&#39;, &#39;return x + y&#39;);
console.log(add(3,4)); //output: 7</code></pre><br/>

<h4 id="5-함수-호이스팅-★"><strong>[5] 함수 호이스팅 ★</strong></h4>
<p>함수를 생성하는 3가지 방법을 살펴봤다. 이들 사이에는 동작 방식이 약간 차이가 있다. 그중 하나가 바로 &#39;함수 호이스팅(<strong>function hoisting</strong>)&#39;이다.</p>
<h4 id="예제-1-규칙-무시-함수-선언문">예제 1) 규칙 무시: 함수 선언문</h4>
<pre><code>add (2,3); //5

function add (x,y) {
    return x + y;
}

add (3,4); //7</code></pre><blockquote>
<p>위와 같은 경우 첫 번째 add 시점에서는 함수가 정의되지 않았음에도 불구하고 호출하는 것이 가능하다. <strong>함수 선언문의 형태로 정의한 함수 유효 범위는 코드 맨 처음부터 시작한다는 것을 확인할 수 있다. 이것을 함수 호이스팅이라고 한다.</strong></p>
</blockquote>
<ul>
<li>문제점 : 코드의 구조를 엉성하게 만들 수 있다는 지적, 이 문제를 해결하기 위해서 함수 표현식 사용을 권장하고 있다.</li>
</ul>
<h4 id="예제-2-규칙-적용-함수-표현식">예제 2) 규칙 적용: 함수 표현식</h4>
<pre><code>add (2,3); // uncaght type error

var add = function (x,y) {
    return x + y;
}

add (3,4); //7</code></pre><blockquote>
<p>함수 표현식의 형태로 되어있어 호이스팅이 일어나지 않는다. 두 번째 ad와 같이 함수가 생성된 이후에 호출이 가능하다. </p>
</blockquote>
<p>이러한 함수 호이스팅이 발생하는 원인은 자바스크립트의 *<em>변수 생성과 초기화의 작업이 분리돼서 진행되기 때문이다. *</em>자세한 내용은 후에 다룰 예정이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[purplepig4657] 자바스크립트 핵심 개념]]></title>
            <link>https://velog.io/@argos_js/purplepig4657-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%95%B5%EC%8B%AC-%EA%B0%9C%EB%85%90</link>
            <guid>https://velog.io/@argos_js/purplepig4657-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%95%B5%EC%8B%AC-%EA%B0%9C%EB%85%90</guid>
            <pubDate>Tue, 05 Oct 2021 14:07:29 GMT</pubDate>
            <description><![CDATA[<h3 id="자바스크립트의-데이터-타입">자바스크립트의 데이터 타입</h3>
<p>​
자바스크립트의 데이터 타입은 크게 &#39;기본 타입&#39;과 &#39;참조 타입&#39;으로 나뉜다.
​</p>
<ul>
<li>기본 타입 - boolean, number, string, null, undefined</li>
<li>참조 타입 - object (array, function, reguler expression 정규 표현식)
​<h3 id="객체">객체</h3>
​
자바스크립트의 거의 모든 것은 객체이다. 하지만 기본 데이터 타입인 boolean, number, string, null, undefined는 객체가 아니다. 여기서 boolean, number, string은 모두 객체처럼 다룰 수 있기 때문에, null과 undefined만이 객체가 아니라고 할 수 있다.
​
기본 타입인 boolean, number, string를 객체처럼 다룰 수 있다는 말의 예시를 들자면 다음과 같다.
​<pre><code class="language-javascript">var a = &quot;javascript&quot;;
a.charAt(2); // &quot;v&quot;</code></pre>
​
이 예시에서, 변수 a는 string타입이지만 객체의 형태로 메서드를 호출했다. 이것은 기본값이 메서드 처리 순간에 객체로 변환되어 호출되고, 다시 기본값으로 복귀하는 과정을 거친다.
​<h3 id="함수">함수</h3>
​
자바스크립트에서의 함수 또한 객체이다. 자바스크립트의 함수는 일급 객체(First class object)이기 때문에 더욱 중요하다.
​
일급 객체만 간단히 알아보겠다. 프로그래밍 언어에서 일급 객체는 자료형을 할당, 전달, 리턴 등을 할 수 있는 자료형이다. 따라서 일급 객체는 다음과 같은 조건을 만족한다.
​</li>
</ul>
<ol>
<li>변수에 할당될 수 있다.</li>
<li>다른 함수의 인자로 전달될 수 있다.</li>
<li>함수의 결과로 리턴될 수 있다.
​
다음은 이에 대한 간략한 예시이다.
​
1. 변수에 할당될 수 있다.<pre><code class="language-javascript">var f = function(x) {
return 2 * x + 1;
}
​
f(1); // 3</code></pre>
​
2. 다른 함수의 인자로 전달될 수 있다.<pre><code class="language-javascript">function a(func) {
return func(1);
}
​
a(f); // 3</code></pre>
​
3. 함수의 결과로 리턴될 수 있다.<pre><code class="language-javascript">function b() {
return function() {
    return 0;
}
}
​
b()(); // 0</code></pre>
​<h3 id="프로토타입">프로토타입</h3>
​
자바스크립트는 객체지향 언어이지만, 다른 객체지향 언어들과 달리 클래스(Class)가 없다. 하지만, 자바스크립트에서는 프로토타입(prototype)이 그 역할을 대신한다.
​
모든 객체는 숨겨진 링크(link)인 프로토타입을 가진다. 함수가 정의될 때 프로토타입 객체 또한 같이 생성된다. 그리고 그 프로토타입은 prototype이라는 속성으로 확인이 가능하다.
​
<img src="https://images.velog.io/images/argos_js/post/1c79b69e-833f-4df3-a5c7-28416a23281e/image.png" alt="">
​자바스크립트의 객체(Object)는 항상 함수로 생성된다.
​
<img src="https://images.velog.io/images/argos_js/post/30da1dd1-70c5-4f95-b701-d3f683b479b8/image.png" alt="">
f.prototype == a._<em>proto_</em><h3 id="실행-컨텍스트">실행 컨텍스트</h3>
​
실행 컨텍스트는 실행할 코드와 관련된 환경 정보를 모아놓은 것이라고 할 수 있다.
​
처음 자바스크립트가 실행될 때, &#39;전역 컨텍스트&#39;가 생성된다. 그 후 함수가 호출된다면, 전역 컨텍스트와 관련된 코드의 실행을 중단하고 호출된 함수의 컨텍스트로 넘어간다. 또한, 컨텍스트가 생성될 때 여러가지 작업을 하는데, 그것은 다음과 같다.
​</li>
</ol>
<ul>
<li>컨텍스트 전체를 한 번 훑음. 필요한 정보 수집.</li>
<li>호이스팅(Hoisting)</li>
<li>스코프 체인(Scope Chain) 생성
​</li>
</ul>
<p>함수가 실행될 때, 내부 코드 전체를 한 번 훑으며 변수 이름, 선언된 함수, 매개변수 등을 컨텍스트에 저장한다. 여기서 호이스팅이라는 개념이 나온다. 호이스팅의 과정은 다음과 같다.
​</p>
<pre><code class="language-javascript">// 호이스팅 전
​
function func() {
    console.log(a);
    var a = 0;
}</code></pre>
<pre><code class="language-javascript">// 호이스팅 후
function func() {
    var a;
    console.log(a);
    a = 0;
}</code></pre>
<p>​
다음과 같이 변수 이름이 맨 위로 끌어올려지는 효과가 있다. 물론 실제로 위로 올라가진 않고, 호이스팅은 컨텍스트의 정보 수집을 표현한 것 뿐이다. 다음은 함수가 호이스팅되는 과정이다.
​</p>
<pre><code class="language-javascript">// 호이스팅 전
​
function func() {
    console.log(a());
    function a() {
        console.log(&quot;a&quot;);
    }
    console.log(b());
    var b = function() {
        console.log(&quot;b&quot;);
    }
}</code></pre>
<pre><code class="language-javascript">// 호이스팅 후
function func() {
    var a = function a() {
        console.log(&quot;a&quot;);
    }
    var b;
    console.log(a());
    console.log(b());
    b = function() {
        console.log(&quot;b&quot;);
    }
}</code></pre>
<p><img src="https://images.velog.io/images/argos_js/post/e5af1623-c7a0-4cb3-92c3-56a6268bf0f3/image.png" alt=""></p>
<p>​위의 코드를 실행한 결과이다. 이렇게 호이스팅 과정에서 &#39;함수 선언문&#39;과 &#39;함수 표현식&#39;의 차이도 확인해 볼 수 있다.
​
스코프 체인은 변수를 참조할 때 사용하는 &#39;지도&#39; 정도로 생각하면 될 것 같다. 스코프 체인은 현제 컨텍스트의 변수 객체와 상위 컨텍스트의 스코프 체인이 합쳐져 생성된다. 현제 컨텍스트에 참조하려는 변수가 없다면 상위 컨텍스트로 가서 참조하려는 변수를 찾아본다.
​</p>
<h3 id="자바스크립트와-객체지향-프로그래밍">자바스크립트와 객체지향 프로그래밍</h3>
<p>​
자바스크립트는 클래스를 지원하지 않지만, 객체지향 프로그래밍이 가능하다. 자바스크립트엔 클래스 대신 프로토타입이 있고, 앞의 실행 컨텍스트의 스코프 체인에서도 보았듯이, 정보의 은닉이 가능하다.
​</p>
<h3 id="자바스크립트의-단점">자바스크립트의 단점</h3>
<p>​
자바스크립트는 느슨한 타입(Loose typing)을 가지고 있다. 느슨한 타입 체크 언어는 변수를 선언할 때 미리 데이터 타입을 명시해 주지 않는다. 자바스크립트는 &#39;var&#39;이라는 단어만 변수를 선언하고, 할당되는 값으로 타입이 결정된다.
​
이와 반대로 C나 Java 같은 언어는 엄격한 타입 체크 언어이다.
​</p>
<pre><code class="language-javascript">// javascript
​
var a = 2;
var b = &quot;javascript&quot;;</code></pre>
<pre><code class="language-java">// Java
int a = 2;
String b = &quot;Java&quot;;</code></pre>
<p>​
느슨한 타입 체크는 개발자에게 자유로움을 줄 수 있다. 하지만 이러한 특성 때문에 &#39;컴파일 타임&#39;에서 프로그램의 오류를 잡아낼 수 없게 되고, 개발자는 &#39;런타임 에러&#39;를 맞닥뜨리게 될 수 있다. 최근엔 이러한 단점을 극복하기 위해 자바스크립트에 타입을 부여한 &#39;typescript&#39;라는 자바스크립트의 확장 언어가 나오게 되었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Begachu]JavaScript의 데이터 타입에 대해 알아보자]]></title>
            <link>https://velog.io/@argos_js/BegachuJavaScript%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@argos_js/BegachuJavaScript%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Tue, 05 Oct 2021 12:39:39 GMT</pubDate>
            <description><![CDATA[<p>오늘은 JavaScript의 데이터 타입의 종류 및 각각의 특징에 대해 알아보고자 합니다.</p>
<hr>
<h2 id="💡javascript의-특징">💡JavaScript의 특징</h2>
<p>JavaScript의 데이터 타입에 대해 공부하기 전에 알아두어야 할 
JavaScript는 기본적으로 <strong>타입 체크가 느슨한 언어</strong>입니다.</p>
<p>타입 체크가 엄격한 언어인 C, Java의 경우를 떠올려 볼까요?
이러한 언어에서 우리는 변수 선언 시 예약어(int, float, …)를 이용하여 데이터 타입을 명시해준 후 이를 사용합니다. 이후 해당 변수에는 명시한 데이터 타입만 삽입할 수 있습니다.</p>
<pre><code class="language-java">int a = 1;      // a의 타입은 int
char b = ‘a’;   // b의 타입은 char</code></pre>
<p>하지만 JavaScript에서는 변수 선언 시 저장할 데이터 타입과 상관없이 var 등의 키워드를 이용합니다. 그리고 <strong>해당 변수의 데이터 타입은 이후 저장될 데이터에 따라 결정</strong>됩니다.</p>
<pre><code class="language-javascript">var a = 1;        // a의 타입은 number
var b = “Hello”;  // b의 타입은 string</code></pre>
<hr>
<h2 id="💡데이터-타입의-분류">💡데이터 타입의 분류</h2>
<p>JavaScript의 데이터 타입은 <strong>프로퍼티를 여러 개 가질 수 있는지 여부</strong>에 따라 <strong>기본 타입</strong>과 <strong>객체 타입</strong>으로 분류할 수 있습니다.</p>
<p><strong>기본 타입</strong>은 <strong>하나의 값</strong>만을 지니며, <strong>값에 의한 호출(Call by Value)</strong> 방식으로 동작합니다. 기본 타입에 포함되는 타입으로는 number, string, boolean, undefined, null이 있습니다. 각 타입에 대한 설명은 아래에서 해보도록 하겠습니다. </p>
<blockquote>
<p><strong>Call by Value</strong>란?
함수 호출 방식 중 하나입니다.
 Call by Value인 변수를 함수에 인자로 전달할 때, 함수에는 해당 변수의 <strong>복사된 값이 전달</strong>되기 때문에 함수 내 변수의 변경 사항이 실제 변수에 영향을 주지 않습니다.</p>
</blockquote>
<p><strong>객체 타입</strong>은 <strong>여러 개의 프로퍼티</strong>를 가질 수 있으며, <strong>참조에 의한 호출(Call by Reference)</strong> 방식으로 동작합니다. 객체 타입에 포함되는 타입으로는 배열(Array), 함수(function) 등이 있습니다.</p>
<blockquote>
<p><strong>Call by Reference</strong>란?
함수 호출 방식 중 하나입니다.
Call by Reference인 변수는 어떠한 객체에 대한 참조값을 지니고 있고, 함수의 인자로 전달될 때 이러한 <strong>참조값을 전달</strong>합니다. 따라서 함수 내에서 해당 값에 변경을 가하면, 참조값이 달라지기 때문에 변수의 값도 달라집니다.</p>
</blockquote>
<hr>
<h2 id="💡기본-타입">💡기본 타입</h2>
<h3 id="숫자number">숫자(number)</h3>
<p>JavaScript에서 숫자 타입인 number는 C, Java등과 같은 언어와 달리 <strong>정수형(int)과 실수형(float)을 모두 포괄하는 타입</strong>입니다. 이는 JavaScript에서 숫자 데이터는 <strong>정수 실수 상관없이 64비트 부동소수점 형태로 저장하기 때문</strong>입니다.</p>
<p>이러한 특성 때문에 다른 언어에서 정수형을 사용해본 경험이 있는 사람이라면 JavaScript에서 정수형을 다룰 때 아래 예시와 같은 실수를 하지 않도록 조심해야 합니다.</p>
<pre><code class="language-javascript">var a = 5/2          // int형이라면 2가 나오겠지?
console.log(a)       // 출력 : 2.5

// 원하는 결과를 얻으려면
console.log(Math.floor(a))    // 출력 : 2</code></pre>
<hr>
<h3 id="문자열string">문자열(string)</h3>
<p>문자열은 작은 따옴표(‘) 또는 큰 따옴표(“)로 나타낼 수 있습니다. JavaScript에서는 char 타입과 같이 하나의 문자를 위한 데이터 타입은 없습니다.</p>
<p>JavaScript의 문자열 사용에 유의해야하는 점은 <strong>한 번 정의된 문자열은 변하지 않는다</strong>는 점입니다. <strong>한 번 정의된 문자열은 읽기만 가능</strong>합니다. 이에 대한 예제는 다음과 같습니다.</p>
<pre><code class="language-javascript">var str = ‘test’;
console.log(str[0], str[1], str[2], str[3]);    // 출력 : test

// 첫 글자를 대문자로 바꾸고 싶다!
str[0] = ‘T’;
console.log(str);    // 출력 : test</code></pre>
<hr>
<h3 id="불린값boolean">불린값(boolean)</h3>
<p>불린값은 참(true)와 거짓(false)을 나타내는 타입입니다.</p>
<hr>
<h3 id="undefined와-null">undefined와 null</h3>
<p>undefined와 null은 모두 <strong>값이 없음</strong>을 의미합니다. 그러나 <strong>undefined</strong>의 경우 JavaScript 내 <strong>기본적으로 값이 할당되지 않았을 때</strong> 적용되는 값이고, null은 개발자가 <strong>명시적으로 빈 값임을 나타낼 때 사용하는 값</strong>입니다.</p>
<p>이때 undefined는 typeof 함수를 이용해 타입 변수를 확인하면 undefined가 나오는 반면, <strong>null은 object가 반환</strong>됩니다. 따라서 데이터에 null이 들어있는지 확인하고자 한다면 <strong>일치 연산자(===)</strong>를 이용해 값을 확인해야 합니다.</p>
<pre><code class="language-javascript">var nullVar = null;

// null 확인 방법
console.log(nullVar === null);     // 출력 : true</code></pre>
<hr>
<h2 id="💡객체-타입">💡객체 타입</h2>
<p>앞서 이야기한 <strong>기본 타입(number, string, boolean, …)을 제외한 모든 값</strong>은 JavaScript에서 <strong>객체</strong>로 표현됩니다. 따라서 배열, 함수, 정규표현식이 이에 해당합니다.</p>
<p>JavaScript에서 <strong>객체</strong>는 단순하게 <strong>이름(key):값(value)</strong> 형태의 프로퍼티들을 저장하는 컨테이너입니다. 이는 자료구조 중 <strong>해시와 유사</strong>합니다.
객체 타입은 여러 개의 프로퍼티를 가질 수 있으며, 기본 타입 뿐만 아니라 다른 객체도 프로퍼티가 될 수 있습니다.</p>
<hr>
<h3 id="1-객체-생성">1. 객체 생성</h3>
<p>객체를 생성하는 방법은 크게 세 가지로 나뉩니다.</p>
<blockquote>
<ol>
<li>Object() 생성자 함수 이용</li>
<li>객체 리터럴 방식 사용</li>
<li>생성자 함수 이용</li>
</ol>
</blockquote>
<p>이번 글에서는 <strong>Object() 생성자 함수 사용</strong>과 <strong>객체 리터럴 방식 사용</strong>에 대해서만 우선적으로 알아보고자 합니다.
<br/></p>
<h4 id="--object-생성자-함수-사용">- Object() 생성자 함수 사용</h4>
<p>Object() 생성자 함수는 JavaScript에서 객제 생성을 위해 제공해주는 함수입니다. 아래와 같이 사용할 수 있습니다.</p>
<pre><code class="language-javascript">// 새로운 객체 생성
var foo = new Object();

// 객체의 프로퍼티 추가
foo.name = ‘begachu’;
foo.age = 23;

// 만든 객체를 출력해보면?
console.log(foo);     // 출력 : { name: ‘begachu’, age: 23 }</code></pre>
<br/>

<h4 id="--객체-리터럴-방식-사용">- 객체 리터럴 방식 사용</h4>
<p>객체 리터럴 방식은 객체 생성 표기법을 의미합니다. 우리는 간단한 표기법으로 JavaScript에서 객체를 생성할 수 있습니다.
먼저 <strong>중괄호({})</strong> 내에  각각의 프로퍼티를 <strong>“프로퍼티 명”: “프로퍼티 값”</strong>으로  추가합니다. 예시는 다음과 같습니다.</p>
<pre><code class="language-javascript">
var foo = {
    name: ‘begachu’,
    age: 23
};

// 만든 객체를 출력해보면?
console.log(foo);     // 출력 : { name: ‘begachu’, age: 23 }</code></pre>
<hr>
<h3 id="2--객체-프로퍼티-읽기-쓰기-갱신하기">2.  객체 프로퍼티 읽기, 쓰기, 갱신하기</h3>
<p>객체의 프로퍼티에 접근하기 위한 방법은 다음과 같습니다.</p>
<ul>
<li>대괄호([]) 표기법</li>
<li>마침표(.) 표기법</li>
</ul>
<p>두 접근 방식의 예는 다음과 같습니다.</p>
<pre><code class="language-javascript">var foo = {
    name: ‘begachu’,
    age: 23
};

console.log(foo.name)        // 출력 : begachu  
console.log(foo[“name”])     // 출력 : begachu

// 잘못된 접근 방법
console.log(foo[name])       // 출력 : undefined</code></pre>
<blockquote>
<p><strong>대괄호 표기법의 주의사항</strong>
위에 예시처럼 대괄호 내 프로퍼티 명을 문자열 형태(“”로 감싸기)로 하지 않은 경우 문제가 발생할 수 있습니다. 이는 대괄호 내 프로퍼티 명이 문자열이 아닌 경우 JavaScript가 모든 객체에서 toString() 메서드를 자동으로 호출하여 문자열로 대체하려고 하기 때문입니다.</p>
</blockquote>
<p>또한 아래와 같은 방법으로 새로운 프로퍼티를 추가하고, 기존의 프로퍼티를 수정할 수 있습니다.</p>
<pre><code class="language-javascript">var foo = {
    name: ‘begachu’,
    age: 23
};

foo.name = ‘bega’;        // 프로퍼티 값 수정
foo.gender = ‘female’;    // 프로퍼티 추가</code></pre>
<hr>
<h3 id="3-객체-프로퍼티-삭제">3. 객체 프로퍼티 삭제</h3>
<p>객체의 프로퍼티는 delete 연산자를 이용하여 삭제할 수 있습니다. 이때 <strong>delete 연산자는 객체의 프로퍼티만 삭제할 수 있으며, 객체 자체는 삭제할 수 없음</strong>에 유의해야합니다.</p>
<pre><code class="language-javascript">var foo = {
    name: ‘begachu’,
    age: 23
};

delete foo.name;
console.log(foo.name);    // 출력 : undefined


// 객체 자체를 삭제하려고 하면?
delete foo;
console.log(foo);         // 출력 : { age: 23 }</code></pre>
]]></description>
        </item>
    </channel>
</rss>