diff options
Diffstat (limited to 'files/ko/learn/javascript/objects')
-rw-r--r-- | files/ko/learn/javascript/objects/basics/index.html | 268 | ||||
-rw-r--r-- | files/ko/learn/javascript/objects/index.html | 50 | ||||
-rw-r--r-- | files/ko/learn/javascript/objects/inheritance/index.html | 394 | ||||
-rw-r--r-- | files/ko/learn/javascript/objects/json/index.html | 351 | ||||
-rw-r--r-- | files/ko/learn/javascript/objects/object-oriented_js/index.html | 287 | ||||
-rw-r--r-- | files/ko/learn/javascript/objects/object_prototypes/index.html | 274 |
6 files changed, 1624 insertions, 0 deletions
diff --git a/files/ko/learn/javascript/objects/basics/index.html b/files/ko/learn/javascript/objects/basics/index.html new file mode 100644 index 0000000000..4220f9bafc --- /dev/null +++ b/files/ko/learn/javascript/objects/basics/index.html @@ -0,0 +1,268 @@ +--- +title: JavaScript 객체 기본 +slug: Learn/JavaScript/Objects/Basics +tags: + - API + - this + - 객체 + - 객체 리터럴 + - 괄호 표기법 + - 구문 + - 배우기 + - 이론 + - 인스턴스 + - 입문자 + - 자바스크립트 + - 점 표기법 + - 코딩스크립트 +translation_of: Learn/JavaScript/Objects/Basics +--- +<div>{{LearnSidebar}}</div> + +<div>{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">이 글에서는 JavaScript 객체와 관련된 기본적인 문법을 살펴보고 이전 코스에서 학습해서 이미 알고 있는 JavaScript 의 특징들과 우리가 이미 사용하고 있는 기능들이 이미 객체와 관련되어 있다는 사실을 다시 한번 복습할 것입니다.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">사전 지식:</th> + <td>컴퓨터와 관련된 기본지식, HTML 과 CSS, 그리고 JavaScript 에 대한 기본 지식 (<a href="/ko/docs/Learn/JavaScript/First_steps">JavaScript 첫걸음</a> 및 <a href="/ko/docs/Learn/JavaScript/Building_blocks">JavaScript 구성요소</a> 참조).</td> + </tr> + <tr> + <th scope="row">목표:</th> + <td>객체지향 프로그래밍에 대한 기본 이론을 이해하고, JavaScript 에서 객체가 어떻게 처리되는지("대부분이 객체임") 학습 후, JavaScript 객체를 실제로 이용하는 방법에 대해 알게되는 것을 목표로 합니다.</td> + </tr> + </tbody> +</table> + +<h2 id="객체_기본">객체 기본</h2> + +<p>객체는 관련된 데이터와 함수(일반적으로 여러 데이터와 함수로 이루어지는데, 객체 안에 있을 때는 보통 프로퍼티와 메소드라고 부릅니다)의 집합입니다. 예제를 통해서 실제 객체가 무엇인지 알아보도록 합시다.</p> + +<p>시작하기에 앞서, <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a> 파일의 복사본을 로컬 환경에 만듭니다. 이 파일은 우리가 작성한 소스코드를 포함하는 작은 {{HTMLElement("script")}} 요소를 포함하고 있습니다. 우리는 기본 객체 문법을 탐구하기 위한 기반으로 이 파일을 사용할 것입니다. 예제를 제대로 따라하려면 반드시 <a href="/ko/docs/Learn/Common_questions/What_are_browser_developer_tools#The_JavaScript_console">개발자 도구 JavaScript 콘솔</a>을 열어두고, 몇몇 명령어를 직접 입력할 준비가 되어있어야 합니다.</p> + +<p>여타 JavaScript 의 요소들과 마찬가지로, 객체를 생성하는 것은 변수를 정의하고 초기화하는 것으로 시작합니다. 아래의 JavaScript 코드를 oojs.html 파일의 script tag 사이에 입력하고 저장 한 후, 리로드 해보세요.</p> + +<pre class="brush: js">var person = {};</pre> + +<p>이제 JS 콘솔에 <code>person</code> 을 입력하면 다음과 같은 결과를 보게됩니다.</p> + +<pre class="brush: js">[object Object]</pre> + +<p>축하합니다, 여러분은 벌써 첫 번째 객체를 생성하였습니다. 하지만 텅 빈 객체여서 우린 이걸로 뭘 할 수는 없습니다. 자, 이제 이 오브젝트를 다음과 같이 고쳐봅시다.</p> + +<pre class="brush: js">var person = { + name: ['Bob', 'Smith'], + age: 32, + gender: 'male', + interests: ['music', 'skiing'], + bio: function() { + alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.'); + }, + greeting: function() { + alert('Hi! I\'m ' + this.name[0] + '.'); + } +}; +</pre> + +<p>저장 후 리로드 한 다음에 아래의 내용을 브라우저 개발자 도구의 JavaScript 콘솔에 입력해보세요.</p> + +<pre class="brush: js">person.name +person.name[0] +person.age +person.interests[1] +person.bio() +person.greeting()</pre> + +<p>자, 이제 당신은 객체에 포함된 데이터와 함수를 갖게 되었으며, 이것들을 간단하고 멋진 문법을 통해 사용할 수 있게되었습니다!</p> + +<div class="note"> +<p><strong>Note</strong>: 만약 여기까지 진행하는데 어려움이 있다면, 제가 만들어놓은 파일과 비교해보세요 — <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-finished.html">oojs-finished.html</a> (그리고 <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-finished.html">실행되는 예제도 보세요</a>). Live 버전에서는 텅빈 화면만 보이겠지만, 그게 정상입니다 — 다시, 개발자도구를 열고 객체 구조를 들여다보기 위해 위에 언급된 명령어를 입력해보세요.</p> +</div> + +<p>자, 이제 뭘 해볼까요? 객체는 각기 다른 이름(위의 예에서는 <code>name</code> 과 <code>age</code>)과 값(예제에서, <code>['Bob', 'Smith']</code> 과 <code>32</code>)을 갖는 복수개의 멤버로 구성됩니다. 한 쌍의 이름과 값은 ',' 로 구분되야 하고, 이름과 값은 ':' 으로 분리됩니다. 결국 문법은 아래와 같은 패턴이 됩니다.</p> + +<pre class="brush: js">var objectName = { + member1Name: member1Value, + member2Name: member2Value, + member3Name: member3Value +};</pre> + +<p>객체를 구성하는 멤버의 값은 어떤 것이라도 될 수 있습니다. 우리가 만든 person 객체는 문자열, 숫자, 배열 두개와 두개의 함수를 가지고 있습니다. 처음 4개의 아이템은 데이터 아이템인데, 이걸 객체의 <strong>프로퍼티(속성) </strong>라고 부릅니다. 끝에 두개의 아이템은 함수인데 이 함수를 통해 데이터를 가지고 뭔가 일을 할 수 있게 됩니다. 이걸 우리는 <strong>메소드</strong> 라고 부릅니다.</p> + +<p>이런 객체는 객체 리터럴(<strong>object literal)</strong> 이라고 부릅니다. 객체를 생성할 때 컨텐츠를 그대로 대입합니다. 객체 리터럴은 클래스로부터 생성하는 방식과는 다릅니다. 이 방식은 뒤에서 살펴보게 될겁니다.</p> + +<p>객체 리터럴을 사용해서 객체를 생성하는 것은 연속된 구조체나 연관된 데이터를 일정한 방법으로 변환하고자 할 때 많이 쓰이는 방법입니다. 예를 들면 서버에게 주소를 데이터베이스에 넣어달라고 요청하는 경우입니다. 각 아이템들을 하나 하나 개별 전송하는 것보다, 하나의 객체를 전송하는 것이 훨씬 효율적입니다. 또 각 아이템들을 이름으로 구분해서 사용하기 원할 때도 배열을 사용하는 것보다 훨씬 쉽습니다.</p> + +<h2 id="점_표기법">점 표기법</h2> + +<p>위에서, 우리는 객체의 프로퍼티와 메소드를 <strong>점 표기법</strong>을 통해 접근했습니다. 객체 이름(person)은 <strong>네임스페이스</strong>처럼 동작합니다. 객체내에 <strong>캡슐화되어있는</strong>것에 접근하려면 먼저 점을 입력해야합니다. 그 다음 점을 찍고 접근하고자 하는 항목을 적습니다. 간단한 프로퍼티의 이름일 수도 있을 것이고, 배열의 일부이거나 객체의 메소드를 호출할 수도 있습니다.</p> + +<pre class="brush: js">person.age +person.interests[1] +person.bio()</pre> + +<h3 id="하위_namespaces">하위 namespaces</h3> + +<p>다른 객체를 객체 멤버의 값으로 갖는 것도 가능합니다. 예를 들면, 다음과 같은 name 멤버를 </p> + +<pre class="brush: js">name: ['Bob', 'Smith'],</pre> + +<p>아래와 같이 바꿔봅시다.</p> + +<pre class="brush: js">name : { + first: 'Bob', + last: 'Smith' +},</pre> + +<p>자, 이제 우리는 성공적으로 <strong>하위 namespace</strong> 를 만들었습니다. 복잡해보이지만, 사실 그렇지도 않습니다. 이 속성을 사용하려면 그저 끝에 다른 점을 하나 찍어주기만 하면 됩니다. JS 콘솔에서 아래와 같이 입력해보세요.</p> + +<pre class="brush: js">person.name.first +person.name.last</pre> + +<p><strong>중요</strong>: 객체의 속성이 바뀌었으니까, 기존 메소드 코드를 바꿔 줘야 합니다. 기존 코드를</p> + +<pre class="brush: js">name[0] +name[1]</pre> + +<p>아래와 같이 바꿔줘야 합니다.</p> + +<pre class="brush: js">name.first +name.last</pre> + +<p>그렇지 않으면 기존 메소드는 더 이상 동작하지 않을 것입니다.</p> + +<h2 id="괄호_표기법">괄호 표기법</h2> + +<p>객체의 프로퍼티에 접근하는 다른 방법으로 괄호 표기법을 사용하는 것이 있습니다. 다음과 같이 사용하는 대신</p> + +<pre class="brush: js">person.age +person.name.first</pre> + +<p>이렇게 사용할 수 있습니다.</p> + +<pre class="brush: js">person['age'] +person['name']['first']</pre> + +<p>이런 방식은 배열 속에 있는 항목에 접근하는 방법과 매우 유사해 보이는데 실제로도 이는 기본적으로 동일한 것입니다. 한 항목을 선택하기 위해 인덱스 숫자를 이용하는 대신에 각 멤버의 값들과 연결된 이름을 이용합니다. 객체가 간혹 <strong>연관배열 (associative arrays</strong>)이라고 불리는 것이 당연합니다. 연관배열은 배열이 숫자를 값에 연결하는 것과 같은 방법으로 스트링을 값에 매핑합니다.</p> + +<h2 id="객체_멤버_설정하기">객체 멤버 설정하기</h2> + +<p>지금까지는 객체 멤버를 단순히 가져오기만(또는 <strong>반환</strong>) 했습니다. 설정할 멤버를 간단히 명시하여(점이나 대괄호 표기법을 사용) 객체 멤버의 값을 <strong>설정</strong>(갱신)하는 것도 물론 가능합니다.</p> + +<pre class="brush: js">person.age = 45; +person['name']['last'] = 'Cratchit';</pre> + +<p>위의 코드를 입력한 다음, 객체 멤버값을 아래와 같이 다시 확인해봅시다.</p> + +<pre class="brush: js">person.age +person['name']['last']</pre> + +<p>객체 멤버를 설정하는 것은 단순히 기존에 존재하는 프로퍼티나 메소드로 값을 설정하는 것 뿐 아니라, 완전히 새로운 멤버를 생성할 수도 있습니다. JS 콘솔에서 아래 내용을 입력해보세요.</p> + +<pre class="brush: js">person['eyes'] = 'hazel'; +person.farewell = function() { alert("Bye everybody!"); }</pre> + +<p>자, 이제 새로운 멤버를 테스트해보세요.</p> + +<pre class="brush: js">person['eyes'] +person.farewell()</pre> + +<p>대괄호 표현의 이점 중 하나는 멤버의 값을 동적으로 변경할 수 있을 뿐아니라, 멤버 이름까지도 동적으로 사용할 수 있다는 것입니다. 자, 만약 사용자가 두개의 텍스트 입력을 통해서 people 데이터에 커스텀 값을 넣고 싶어한다고 가정해봅시다. 그 값은 다음과 같이 얻어올 수 있을겁니다.</p> + +<pre class="brush: js">var myDataName = nameInput.value; +var myDataValue = nameValue.value;</pre> + +<p>이제 <code>person</code> 객체에 다음과 같이 새 멤버의 이름과 값을 추가할 수 있습니다.</p> + +<pre class="brush: js">person[myDataName] = myDataValue;</pre> + +<p>자, 제대로 동작하는지 보려면 아래와 같이 <code>person</code> 객체에 대괄호를 붙여서 확인해보면 됩니다.</p> + +<pre class="brush: js">var myDataName = 'height'; +var myDataValue = '1.75m'; +person[myDataName] = myDataValue;</pre> + +<p>이제 저장하고 리로드후 아래코드를 입력해보세요.</p> + +<pre class="brush: js">person.height</pre> + +<p>점 표기법으로는 위의 예제처럼 멤버의 이름을 동적으로 사용할 수 없고, 상수 값만을 사용해야 합니다.</p> + +<h2 id="this_는_무엇인가">"this" 는 무엇인가?</h2> + +<p>자, 우리가 이제 보게될 메소드가 좀 이상하게 보일 수도 있을겁니다. 예제를 한번 봐주세요</p> + +<pre class="brush: js">greeting: function() { + alert('Hi! I\'m ' + this.name.first + '.'); +}</pre> + +<p>아마도 "this" 가 뭔지 의아하실 것입니다. <code>this</code> 키워드는 지금 동작하고 있는 코드를 가지고 있는 객체를 가리킵니다. 위의 예제에서 <code>this</code> 는 <code>person</code> 객체와 동일합니다. 그럼 왜 직접 <code>person</code> 객체를 쓰지 않은걸까요? 앞으로 보게될 <a href="/ko/docs/Learn/JavaScript/Objects/Object-oriented_JS">입문자를 위한 객체 지향 JavaScript</a> 문서에서 우리가 생성자를 공부하게 될 때, 혹은 그것 말고도 기타 등등의 상황에서 <code>this</code> 는 매우 유용하게 사용됩니다. 이 this 라는 녀석은 객체 멤버의 컨텍스트가 바뀌는 경우에도 언제나 정확한 값을 사용하게 해줍니다(예를 들어, 두개의 다른 <code>person</code> 객체가 각각 다른 이름으로 인스턴스로 생성된 상태에서 인사말을 출력하기 위해 객체의 name 을 참조해야 한다고 생각해보세요).</p> + +<p>간략화된 person 객체를 가지고 설명을 좀 해보겠습니다.</p> + +<pre class="brush: js">var person1 = { + name: 'Chris', + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +} + +var person2 = { + name: 'Brian', + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +}</pre> + +<p>이 예제에서, 메소드의 실제 코드는 완전히 동일하지만 <code>person1.greeting()</code> 은 "Hi! I'm Chris." 를 출력합니다. 반면 <code>person2.greeting()</code> 은 "Hi! I'm Brian." 을 출력하게 됩니다. 앞서 이야기한 것처럼, <code>this</code> 은 실행중인 코드가 속해있는 객체입니다. 객체 리터럴을 직접 지정해서 사용하는 경우라면 그리 유용하지 않겠지만, 동적으로 객체를 생성하는 경우(예를 들면 생성자를 사용하는 경우)에는 매우 유용합니다. 이 부분은 추후에 더 명확하게 이해가 될 겁니다.</p> + +<h2 id="객체를_줄곧_사용해_왔습니다">객체를 줄곧 사용해 왔습니다</h2> + +<p>예제코드를 따라하다보니, 이쯤 되면 슬슬 "점" 표기법을 사용하는 것이 꽤 자연스럽게 느껴질 것입니다. 물론 이 코스 내내 사용했기 때문입니다! 샘플에서 사용하였던 브라우저 내장 API 나 JavaScript 객체들은 실제로 우리가 공부했던 구조와 완전히 동일한 방법으로 구현된 것들입니다. 물론 우리가 봤던 예제보다 복잡하기는 합니다.</p> + +<p>자, 다음과 같이 String의 메소드를 사용했다고 가정합시다.</p> + +<pre class="brush: js">myString.split(',');</pre> + +<p><code><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> 클래스의 인스턴스가 가진 메소드를 사용하고 있습니다. 코드에서 String 을 생성할 때 마다 <code>String</code> 의 인스턴스가 만들어지고, 그렇게 만들어진 인스턴스는 당연히 공통적으로 사용할 수 있는 메소드와 프러퍼티를 가집니다.</p> + +<p>아래와 같이 도큐먼트 오브젝트 모델(DOM)에 접근할때면,</p> + +<pre class="brush: js">var myDiv = document.createElement('div'); +var myVideo = document.querySelector('video');</pre> + +<p><code><a href="https://developer.mozilla.org/ko/docs/Web/API/Document">Document</a></code> 클래스의 인스턴스를 통해 메소드를 사용하고 있는 것입니다. 각 웹페이지가 로딩될 때, <code>Document</code> 인스턴스가 만들어지고, 전체 웹 페이지 구조와 컨텐츠 그리고 URL같은 기능들을 제공하는 <code>document</code> 가 호출됩니다. 다시 말하지만 이건 여러 공통 메소드와 프로퍼티들이 이 인스턴스를 통해 사용가능하게 됩니다.</p> + +<p>우리가 계속 사용해왔던 다른 내장 객체/API(<code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code>, <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Math">Math</a></code> 등등)들도 마찬가지입니다</p> + +<p>모든 내장 객체/API가 자동으로 객체의 인스턴스를 생성하는 것은 아니라는 것에 주의 하세요. 예를 들어, <a href="/ko/docs/Web/API/Notifications_API">Notifications API</a> — 최근 브라우져들이 시스템 알림을 사용하게 하는 기능 — 는 사용자가 발생시시길 원하는 notification 만을 선택하게 하는 생성자를 사용해야 합니다. JavaScript 콘솔에 다음 내용을 입력해보세요</p> + +<pre class="brush: js">var myNotification = new Notification('Hello!');</pre> + +<p>다음 문서에서 생성자에 대해서 좀더 자세히 알아볼 것입니다.</p> + +<div class="note"> +<p><strong>Note</strong>: 객체간 통신은 <strong>message passing</strong> 방식을 사용한다고 생각하는게 좋습니다. 한 객체가 다른 객체에게 어떤 액션을 요청해야 하는 경우, 그 객체는 다른 객체가 가지고 있는 메소드를 통해서 메세지를 보내는 것이고, 응답을 기다리는 것입니다. 그 응답은 것이 우리가 알고 있는 return 값입니다.</p> +</div> + +<h2 id="요약">요약</h2> + +<p>축하합니다, 첫 번째 JavaScript 객체 설명 문서를 끝까지 읽으셨습니다. 이제 여러분은 JavaScript 객체를 어떻게 활용하는지 이해하게 되었습니다. 간단한 사용자 정의 객체를 만드는 방법을 포함해서요. 또 객체는 데이터와 연관된 함수를 저장하는데 매우 유용한 구조라는 것도 알게 되었습니다. 만약 <code>person</code> 객체가 가지고 있는 모든 프로퍼티와 메소드를 따로 따로 분리된 변수와 함수로 구현하려고 한다면 그것이야 말로 비효율적이고 끔찍한 일이 될 것입니다. 변수명과 함수명들이 중복된다거나 하는 일도 비일비재 할 것입니다. 객체는 고유의 패키지에 우리의 정보를 안전하게 정보를 보호해주는 역활을 합니다.</p> + +<p>다음 장에서는 객체지향(OOP) 이론을 배우고, JavaScript 에서는 객체지향이 어떻게 사용되었는지 알아볼 것입니다.</p> + +<p>{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}</p> + +<h2 id="이_모듈_에서는">이 모듈 에서는</h2> + +<ul> + <li><a href="https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Basics">객체 기본</a></li> + <li><a href="https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Object-oriented_JS">입문자를위한 객체 지향 JavaScript</a></li> + <li><a href="https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Object_prototypes">객체 프로토타입</a></li> + <li><a href="https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Inheritance">JavaScript 에서의 상속</a></li> + <li><a href="https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/JSON">JSON 데이터와 작업</a></li> + <li><a href="https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Object_building_practice">객체 생성 실습</a></li> + <li><a href="https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">bouncing balls demo 에 기능들 추가하기</a></li> +</ul> diff --git a/files/ko/learn/javascript/objects/index.html b/files/ko/learn/javascript/objects/index.html new file mode 100644 index 0000000000..9bdd5d8a66 --- /dev/null +++ b/files/ko/learn/javascript/objects/index.html @@ -0,0 +1,50 @@ +--- +title: JavaScript 객체 소개 +slug: Learn/JavaScript/Objects +tags: + - 객체 + - 배우기 + - 입문자 + - 자바스크립트 + - 지침 + - 코딩스크립트 + - 평가 +translation_of: Learn/JavaScript/Objects +--- +<div>{{LearnSidebar}}</div> + +<p class="summary"> 자바스크립트에서는 스트링과 배열과같은 기본적인 기능부터 가장 상단에 놓여진 브라우저 API에 이르기까지 대부분의 것들이 객체입니다. 사용자는 관련된 함수들과 변수들을 효율적인 패키지로 추상화하거나 편리한 데이터 컨테이너로 작동하는 객체를 만들 수 있습니다. 언어에 대한 지식을 가지고 더 멀리 나아고자 한다면 자바스크립트의 객체 기반의 본질을 이해하는 것이 중요하므로, 여러분을 돕기위해 이 모듈을 제공하였습니다. 여기에서는 객체 이론과 구문을 자세히 가르쳐드리며, 사용자 정의 객체를 만드는 방법도 알아볼 것입니다.</p> + +<h2 id="사전_지식">사전 지식</h2> + +<p>이 장을 읽기 전에, 여러분은 HTML 과 CSS 를 어느 정도 알고 있어야 합니다. 그렇지 않다면 <a href="/ko/docs/Web/Guide/HTML/Introduction">HTML 소개</a>와 <a href="/ko/docs/Learn/CSS/Introduction_to_CSS">CSS 소개</a>를 먼저 읽고 오시기 바랍니다.</p> + +<p>JavaScript 객체에 대해 자세히 알아보려면, 기본 문법에 대해 어느 정도 능숙해야 합니다. 이 장을 읽기 전에 <a href="/ko/docs/Learn/JavaScript/First_steps">JavaScript 첫걸음</a>과 <a href="/ko/docs/Learn/JavaScript/Building_blocks">JavaScript 구성 요소</a>를 먼저 읽어보시기를 바랍니다.</p> + +<div class="note"> +<p><strong>Note</strong>: 컴퓨터/태블릿/혹은 다른 디바이스 상에서 스스로 파일을 만들수 없는 환경이라면, <a href="http://jsbin.com/">JSBin</a> 또는 <a href="https://thimble.mozilla.org/">Thimble</a> 과 같은 온라인 코딩 프로그램을 이용하여 (거의 모든) 예제 코드를 테스트해 보실 수 있습니다.</p> +</div> + +<h2 id="가이드">가이드</h2> + +<dl> + <dt><a href="/ko/docs/Learn/JavaScript/Objects/Basics">객체 기본</a></dt> + <dd>JavaScript 객체 소개의 첫 장에서는, 기본적인 JavaScript 객체 문법을 볼 것이며, 이전 과정에서 이미 봐왔던 몇몇 JavaScript 특징들을 다시 들여다 볼 것입니다. 이를 통해 우리는 이전에 다루었던 많은 특징들이 사실상 객체였다는 사실을 알게 될 것입니다.</dd> + <dt><a href="/ko/docs/Learn/JavaScript/Objects/Object-oriented_JS">입문자를 위한 객체지향 자바스크립트</a></dt> + <dd>가장 기본적인 것으로, 우리는 객체 지향 JavaScript(OOJS) 에 초점을 둘 것입니다. 이 글에서는 객체 지향 프로그래밍(OOP) 이론의 기본 관점을 보여주고, JavaScript 가 생성자함수를 이용하여 객체 클래스를 에뮬레이트 하는 방법과 객체 인스턴스를 생성하는 방법에 대해 탐구합니다.</dd> + <dt><a href="/ko/docs/Learn/JavaScript/Objects/Object_prototypes">객체 프로토타입</a></dt> + <dd>프로토타입은 JavaScript 객체가 또다른 객체로 특성을 상속시키기 위한 메커니즘이고, 그것들은 고전적인 객체 지향 프로그래밍 언어들의 상속 메커니즘과 다르게 작동합니다. 이 글에서는 그 다름을 탐구하고, 프로토타입 체인이 동작하는 방식을 설명하며 프로토타입의 속성이 기본 생성자들로 메소드를 추가하기 위해 사용되는 방법을 보여줍니다.</dd> + <dt><a href="/ko/docs/Learn/JavaScript/Objects/Inheritance">자바스크립트에서의 상속</a></dt> + <dd>이제 OOJS 에 대한 대부분의 세부사항들에 대해서 설명이 되었으므로, 본 장에서는 "부모" 클래스로부터 특성을 상속받은 "자식" 오브젝트 클래스를 생성하는 방법을 보여줍니다. 뿐만 아니라, OOJS 를 언제 또는 어디서 사용하면 좋을 지에 대한 몇몇 조언도 기술되어있습니다.</dd> + <dt><a href="/ko/docs/Learn/JavaScript/Objects/JSON">JSON 데이터와 작업</a></dt> + <dd>JSON(JavaScript Object Notation) 은 JavaScript 객체 문법상의 구조화된 데이터를 표현하기 위한 표준 텍스트기반 포맷입니다. 그래서 주로 웹사이트 상에 데이터를 표현하고 전송하는 데 사용되고 있습니다(예를 들면, 웹페이지 상에 데이터를 디스플레이할 수 있도록 서버에서 클라이언트로의 데이터 전송). 이 글에서는 데이터에 접근하기 위해 JSON 을 파싱하고, 또 자신만의 JSON 을 작성하는 것처럼 자바스크립트를 사용하여 JSON 과 연동할 필요가 있는 모든 것들을 보여드릴 것입니다.</dd> + <dt><a href="/ko/docs/Learn/JavaScript/Objects/Object_building_practice">객체 생성 실습</a></dt> + <dd>이전 글들에서 우리는 JavaScript 객체 이론과 문법 세부사항의 중요한 것들을 보았습니다. 본 장에서는 커스텀 JavaScript 객체를 생성하는 다양한 연습을 하면서 실용적인 예들을 깊이 다룹니다.</dd> +</dl> + +<h2 id="평가">평가</h2> + +<dl> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Bouncing balls demo 에 기능들 추가</a></dt> + <dd>이 평가에서는 여러분이 이전 글의 bouncing balls demo 를 시작점으로 하여, 몇 가지 새롭고 재미있는 기능들을 추가하길 기대합니다.</dd> +</dl> diff --git a/files/ko/learn/javascript/objects/inheritance/index.html b/files/ko/learn/javascript/objects/inheritance/index.html new file mode 100644 index 0000000000..72a2302d15 --- /dev/null +++ b/files/ko/learn/javascript/objects/inheritance/index.html @@ -0,0 +1,394 @@ +--- +title: Inheritance in JavaScript +slug: Learn/JavaScript/Objects/Inheritance +translation_of: Learn/JavaScript/Objects/Inheritance +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">OOJS에 대한 온갖 잡지식을 설명했으니, 이 글에서는 부모 클래스에서 자식 클래스를 상속하는 방법을 알아봅니다. 덤으로 OOJS를 구현하는데 몇 가지 참고사항도 있습니다.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">선수조건:</th> + <td>컴퓨터 기본지식, HTML과 CSS에 대한 기본적인 이해,자바스크립트에 어느 정도 익숙할 것 (see <a href="/ko/docs/Learn/JavaScript/First_steps">First steps</a> and <a href="/ko/docs/Learn/JavaScript/Building_blocks">Building blocks</a>). OOJS 기초 지식 (see <a href="/ko/docs/Learn/JavaScript/Objects/Basics">Introduction to objects</a>).</td> + </tr> + <tr> + <th scope="row">학습목표:</th> + <td>Javascript에서 상속을 구현하는 법을 이해합니다.</td> + </tr> + </tbody> +</table> + +<h2 id="프로토타입_상속">프로토타입 상속</h2> + +<p>지금까지 몇 가지 상속을 살펴보았습니다 — 프로토타입 체인이 어떻게 동작하는지, 체인을 통해 멤버들을 탐색하는 것도 보았죠. 하지만 이는 대부분 브라우저가 알아서 처리하는 로직이었습니다. 그러면 우리가 직접 객체를 생성하고 상속하려면 어떻게 해야 할까요?</p> + +<p>실질적인 예제를 통해 알아보도록 합시다.</p> + +<h2 id="시작하기">시작하기</h2> + +<p>먼저 <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-start.html">oojs-class-inheritance-start.html</a>를 다운 받으시고 (<a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-start.html">running live</a> 페이지도 보시구요). 파일 내에서 이전 예제에서 계속 봐 왔던 <code>Person()</code> 생성자를 보실 수 있습니다 — 생성자에 속성 몇 개를 정의했기에 조금 다릅니다:</p> + +<pre class="brush: js">function Person(first, last, age, gender, interests) { + this.name = { + first, + last + }; + this.age = age; + this.gender = gender; + this.interests = interests; +};</pre> + +<p>메소드는 <em>전부</em> 아래처럼 prototype에 정의되어 있습니다:</p> + +<pre class="brush: js">Person.prototype.greeting = function() { + alert('Hi! I\'m ' + this.name.first + '.'); +};</pre> + +<div class="note"> +<p><strong>Note</strong>: 소스 코드에는 <code>bio()와</code> <code>farewell()</code>메소드가 정의되어 있습니다. 잠시 후에 다른 생성자로 어떻게 상속하는지 알아보도록 합시다.</p> +</div> + +<p>객체 지향에 대해 처음 정의할 때 언급했었던 <code>Teacher</code> 클래스를 만들어 봅시다. <code>Person</code>을 상속받고 아래 몇 가지를 추가해서요:</p> + +<ol> + <li><code>subject</code> 속성 — 교사가 가르치는 과목을 나타냅니다.</li> + <li>기존의 <code>greeting()</code> 보다 조금 더 공손한 인사를 하는 메소드 — 교사가 학생들에게 건넬 만한 표현으로 하죠.</li> +</ol> + +<h2 id="Teacher()_생성자_함수_정의">Teacher() 생성자 함수 정의</h2> + +<p>제일 처음 단계에서는 <code>Teacher()</code> 생성자를 만들어야 합니다 — 기존 코드 밑에 아래 코드를 추가하세요:</p> + +<pre class="brush: js">function Teacher(first, last, age, gender, interests, subject) { + Person.call(this, first, last, age, gender, interests); + + this.subject = subject; +}</pre> + +<p>Person() 생성자와 여러모로 비슷해 보이지만 여지껏 보지 못했던 한가지 차이점이 있습니다 — <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/call">call()</a></code> 함수죠. call() 함수의 첫번째 매개변수는 다른 곳에서 정의된 함수를 현재 컨텍스트에서 실행할 수 있도록 합니다. 실행하고자 하는 함수의 첫 번째 매개변수로 this를 전달하고 나머지는 실제 함수 실행에 필요한 인자들을 전달하면 됩니다.</p> + +<p>Teacher()의 생성자는 <code>Person()</code>을 상속받았으므로 같은 매개변수들이 필요합니다. 따라서 동일한 매개변수들을 <code>call()</code>의 인자로 전달하여 실행합니다.</p> + +<p>마지막 줄에서는 새 속성인 <code>subject</code>를 정의하여 Person이 아닌 Teacher만이 갖는 속성을 만들어 줍니다.</p> + +<p>참고로 아래와 같이 할 수도 있습니다:</p> + +<pre class="brush: js">function Teacher(first, last, age, gender, interests, subject) { + this.name = { + first, + last + }; + this.age = age; + this.gender = gender; + this.interests = interests; + this.subject = subject; +}</pre> + +<p>다만 이는 <code>Person()</code>을 상속받은게 아니라 단지 동일한 인자를 정의했을 뿐이죠. 이건 원하는 방법이 아닐 뿐더러 코드의 길이만 더 늘어났습니다.</p> + +<h3 id="매개변수가_없는_생성자_상속하기">매개변수가 없는 생성자 상속하기</h3> + +<p>상속하려는 생성자가 속성을 매개변수로 받지 않는다면 <code>call()</code>의 매개변수에도 아무것도 전달할 필요가 없습니다. 아래처럼 간단한 생성자가 있다면:</p> + +<pre class="brush: js">function Brick() { + this.width = 10; + this.height = 20; +}</pre> + +<p><code>width</code>와 <code>height</code> 속성을 상속받기 위해 아래처럼만 하면 됩니다(물론 이후 설명할 방법을 써도 되구요):</p> + +<pre class="brush: js">function BlueGlassBrick() { + Brick.call(this); + + this.opacity = 0.5; + this.color = 'blue'; +}</pre> + +<p><code>call() </code>함수에 this만 넘긴 것을 보세요. — <code>Brick()</code> 생성자에서 매개변수를 통해 초기화 하는 속성들이 없으므로 <code>call()</code>에도 넘길 필요가 없습니다.</p> + +<h2 id="Teacher()의_프로토타입과_생성자_참조_설정하기">Teacher()의 프로토타입과 생성자 참조 설정하기</h2> + +<p>다 좋은데 문제가 있습니다. 방금 정의한 새 생성자에는 생성자 함수 자신에 대한 참조만 가지고 있는 프로토타입 속성이 할당되어 있습니다. 정작 상속 받은 Person() 생성자의 prototype 속성은 없죠. Javascript 콘솔에서 <code>Object.getOwnPropertyNames(Teacher.prototype)</code>을 쳐서 확인해 보세요. 다음엔 <code>Teacher</code>를 <code>Person</code>으로 바꿔서 확인해 보세요. Teacher()생성자는 Person()의 메소드를 상속받지 못하였습니다. <code>Person.prototype.greeting</code>과 <code>Teacher.prototype.greeting</code> 구문을 실행하여 비교해 보세요. <code>Teacher()</code>가 메소드도 상속 받으려면 어떻게 해야 할까요?</p> + +<ol> + <li>기존 코드에 아래 코드를 추가하세요: + <pre class="brush: js">Teacher.prototype = Object.create(Person.prototype);</pre> + 구원 투수 <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create()</a></code>의 등판입니다. 새 객체를 생성하여 <code>Teacher.prototype</code>으로 할당했죠. 새 객체는 <code>Person.prototype</code> 객체를 자신의 프로토타입으로 가지고 있으므로 <code>Person.prototype</code>에 정의된 모든 메소드를 사용할 수 있습니다.</li> + <li>넘어가기 전에 한가지 더 해야 합니다. 마지막 줄을 추가하고 나면 <code>Teacher.prototype</code>의 <code>constructor</code> 속성이 Person()으로 되어 있습니다. <code>Teacher.prototype</code>에 <code>Person.prototype</code>을 상속받은 객체를 할당했기 때문이죠. 코드를 저장한 뒤 브라우저로 불러와서 Teacher.prototype.constructor 구문의 반환 값을 확인해 보세요.</li> + <li>문제의 소지가 있으므로 고쳐야 됩니다. 소스에 아래 코드를 추가하세요: + <pre class="brush: js">Teacher.prototype.constructor = Teacher;</pre> + </li> + <li>저장하고 다시 브라우저에서 불러오면 의도한대로 <code>Teacher.prototype.constructor</code>가 <code>Teacher()</code>를 반환합니다. 게다가 <code>Person()</code>도 상속받았죠!</li> +</ol> + +<h2 id="Teacher()에_새_greeting()_함수_부여하기">Teacher()에 새 greeting() 함수 부여하기</h2> + +<p><code>Teacher()</code>에 새로운 <code>greeting()</code> 함수를 정의하여 코드를 완성합시다.</p> + +<p>가장 간단한 방법은 Teacher()의 프로토타입에 정의합니다. — 아래 코드를 추가하세요:</p> + +<pre class="brush: js">Teacher.prototype.greeting = function() { + var prefix; + + if (this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') { + prefix = 'Mr.'; + } else if (this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') { + prefix = 'Mrs.'; + } else { + prefix = 'Mx.'; + } + + alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.'); +};</pre> + +<p>조건문을 이용해서 성별에 따라 적절한 호칭이 붙은 교사의 인삿말을 alert 창으로 띄웁니다.</p> + +<h2 id="예제_사용해_보기">예제 사용해 보기</h2> + +<p>소스를 환성했으니 아래 코드를 통해 새 <code>Teacher()</code> 인스턴스를 생성해 봅시다(아니면 인자를 원하는 값으로 변경하시거나요):</p> + +<pre class="brush: js">var teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');</pre> + +<p>저장한 코드를 다시 불러와서 아래처럼 <code>teacher1</code>의 속성과 메소드를 확인해 봅시다:</p> + +<pre class="brush: js">teacher1.name.first; +teacher1.interests[0]; +teacher1.bio(); +teacher1.subject; +teacher1.greeting(); +teacher1.farewell();</pre> + +<p>아주 잘 실행될 겁니다. 1, 2, 3, 6 줄은 Person() 생성자(클래스)에서 상속 받은 멤버에 접근합니다. 4번째 줄은 Teacher() 생성자(클래스)만 가지고 있는 멤버에 접근합니다. 5번째 줄은 Person()에서 상속 받은 멤버도 있지만 Teacher()가 이미 자신만의 새 메소드를 정의했으므로 Teacher()의 메소드에 접근합니다.</p> + +<div class="note"> +<p><strong>Note</strong>: 코드가 잘 동작하지 않으면 <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-finished.html">완성된 버전</a>을 확인해 보세요. (<a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-finished.html">실행 페이지</a>도 보시구요).</p> +</div> + +<p>이 테크닉이 Javascript에서 상속 받는 클래스를 만드는 유일한 방법은 아니지만 잘 동작하며 상속을 구현하는 방법을 잘 설명하고 있습니다.</p> + +<p>조금 더 명확한 방식으로 Javascript에서 상속을 구현하는 새 {{glossary("ECMAScript")}} 기능도 관심 가질만한 주제입니다(<a href="/ko/docs/Web/JavaScript/Reference/Classes">Classes</a> 참조). 아직까지 많은 브라우저에서 지원하지 못하고 있기 때문에 여기서 다를 주제는 아닙니다. 여러 문서에서 제시한 코드들은 IE9보다 더 오래된 구형 브라우저에서도 사용 가능하며 더 이전 버전을 지원하기 위한 방법들도 있습니다. </p> + +<p>JavaScript 라이브러리를 쓰면 간단합니다 — 상속 기능을 사용하기 위한 보편적인 방법이죠. 예를들어 <a href="http://coffeescript.org/#classes">CoffeeScript</a>는 <code>class</code>와 <code>extends</code>등의 기능을 제공합니다.</p> + +<h2 id="더_연습하기">더 연습하기</h2> + +<p><a href="/ko/docs/Learn/JavaScript/Objects/Object-oriented_JS#Object-oriented_programming_from_10000_meters">OOP theory section</a>, 에서는 개념적으로 Person을 상속받고 Teacher보다 덜 공손한 <code>greeting()</code> 메소드를 재정의한 <code>Student</code> 클래스를 정의했었습니다. 해당 절에서 <code>Student</code>의 인삿말이 어땠는지 확인해 보시고 <code>Person()</code>을 상속받는 <code>Student()</code> 생성자를 구현해 보세요. <code>greeting()</code> 함수도 재정의 해 보시구요.</p> + +<div class="note"> +<p><strong>Note</strong>: 코드가 잘 동작하지 않으면 <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-student.html">완성된 버전</a> 을 확인해 보세요.(<a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-student.html">실행 페이지</a>도 보시구요).</p> +</div> + +<h2 id="객체_멤버_요약">객체 멤버 요약</h2> + +<p>요약하면, 상속에 있어 고려해야 할 세 가지 유형의 속성/메소드가 있습니다:</p> + +<ol> + <li>생성자 함수 내에서 인스턴스에 정의하는 유형. 직접 작성한 코드에서는 생성자 함수 내에 <code>this.x = x</code> 구문과 유사하게 정의되어 있으므로 발견하기 쉽습니다. 브라우저 내장 코드에서는 객체 인스턴스(보통 <code>new</code> 키워드를 통해 생성, ex) <code>var myInstance = new myConstructor()</code>)에서만 접근할 수 있는 멤버입니다.</li> + <li>생성자에 직접 정의하는 유형, 생성자에서만 사용 가능합니다. 브라우저 내장 객체에서 흔히 사용하는 방식인데, 인스턴스가 아니라 생성자 함수에서 바로 호출되는 유형입니다. <code>Object.key()</code> 같은 함수들이죠.</li> + <li>인스턴스와 자식 클래스에 상속하기 위해 생성자의 프로토타입에 정의하는 유형. 생성자의 프로토타이비 속성에 정의되는 모든 멤버를 의미합니다. ex) <code>myConstructor.prototype.x()</code>.</li> +</ol> + +<p>뭐가 뭔지 헷갈려도 걱정하지 마세요 — 배우는 중이니 차츰 익숙해질겁니다.</p> + +<h2 id="ECMAScript_2015_클래스">ECMAScript 2015 클래스</h2> + +<p>ECMAScript 2015에서는 C++나 Java와 유사한 <a href="/ko/docs/Web/JavaScript/Reference/Classes">클래스 문법</a>을 공개하여 클래스를 조금 더 쉽고 명확하게 재활용 할 수 있게 되었습니다. 이 절에서는 프로토타입 상속으로 작성한 Person과 Teacher 예제를 클래스 문법으로 변경하고 어떻게 동작하는지 설명하겠습니다.</p> + +<div class="note"> +<p><strong>Note</strong>: 대부분의 최신 브라우저에서 새로운 클래스 작성 방식을 지원합니다만 일부 구형 브라우저(Internet Explorer가 대표적)에서는 동작하지 않으므로 하위호환성을 위해 프로토타입 상속을 배워둘 필요가 있습니다.</p> +</div> + +<p>Class-스타일로 재작성한 Person 예제를 보시죠:</p> + +<pre><code>class Person { + constructor(first, last, age, gender, interests) { + this.name = { + first, + last + }; + this.age = age; + this.gender = gender; + this.interests = interests; + } + + greeting() { + console.log(`Hi! I'm ${this.name.first}`); + }; + + farewell() { + console.log(`${this.name.first} has left the building. Bye for now!`); + }; +}</code></pre> + +<p><a href="/ko/docs/Web/JavaScript/Reference/Statements/class">class</a> 구문은 새로운 클래스를 작성함을 의미합니다. Class 블록 내에서 모든 기능을 정의할 수 있습니다.</p> + + + +<ul> + <li><code><a href="/ko/docs/Web/JavaScript/Reference/Classes/constructor">constructor()</a></code> 메소드는 <code>Person</code> 클래스의 생성자를 의미합니다.</li> + <li><code>greeting()</code> and <code>farewell()</code>는 멤버 메소드입니다. 클래스의 메소드는 생성자 다음에 아무 메소드나 추가할 수 있습니다. 여기서는 읽기 쉬우라고 string 결합이 아닌 <a href="/ko/docs/Web/JavaScript/Reference/Template_literals">template literals</a>을 사용했습니다.</li> +</ul> + +<p>이제 위에서 했듯이 <a href="/ko/docs/Web/JavaScript/Reference/Operators/new"><code>new</code> 연산자</a>로 객체 인스턴스를 생성할 수 있습니다:</p> + +<pre><code>let han = new Person('Han', 'Solo', 25, 'male', ['Smuggling']); +han.greeting(); +// Hi! I'm Han + +let leia = new Person('Leia', 'Organa', 19, 'female' ['Government']); +leia.farewell(); +// Leia has left the building. Bye for now</code></pre> + +<div class="note"> +<p><strong>Note</strong>: 코드를 까보면 class 부분은 프로토타입 상속으로 변환이 됩니다. — 문법 설탕(syntactic sugar)의 일종인거죠. 하지만 읽기 쉽다는데 대부분 동의하실 겁니다.</p> +</div> + +<h3 id="class_문법으로_상속">class 문법으로 상속</h3> + +<p>위에서 사람을 나타내는 클래스를 만들었습니다. Person 클래스는 일반적인 사람이 가질 만한 특성들을 나열하고 있죠; 이 절에서는 <code>Person</code>을 class 문법으로 상속받아 <code>Teacher</code> 클래스를 만들 예정입니다. 이 작업을 하위 클래스 생성이라 부릅니다.</p> + +<p>하위 클래스를 만드려면 Javascript에서 <a href="/ko/docs/Web/JavaScript/Reference/Classes/extends">extends 키워드</a>를 통해 상속 받을 클래스를 명시합니다.</p> + +<pre><code>class Teacher extends Person { + constructor(first, last, age, gender, interests, subject, grade) { + this.name = { + first, + last + }; + + this.age = age; + this.gender = gender; + this.interests = interests; + // subject and grade are specific to Teacher + this.subject = subject; + this.grade = grade; + } +}</code></pre> + +<p><code>constructor()</code>에서 첫번쨰로 <a href="/ko/docs/Web/JavaScript/Reference/Operators/super"><code>super()</code> 연산자</a>를 정의하면 코드를 조금 더 읽기 쉬워집니다. 이는 상위 클래스의 생성자를 호출하며 super()의 매개변수를 통해 상위 클래스의 멤버를 상속받을 수 있는 코드입니다.</p> + +<pre><code>class Teacher extends Person { + constructor(first, last, age, gender, interests, subject, grade) { + super(first, last, age, gender, interests); + + // subject and grade are specific to Teacher + this.subject = subject; + this.grade = grade; + } +}</code></pre> + +<p><code>Teacher</code>의 인스턴스를 생성하면 의도한대로 이제 <code>Teacher</code>와 <code>Person</code> 양 쪽의 메소드와 속성을 사용할 수 있습니다.</p> + +<pre><code>let snape = new Teacher('Severus', 'Snape', 58, 'male', ['Potions'], 'Dark arts', 5); +snape.greeting(); // Hi! I'm Severus. +snape.farewell(); // Severus has left the building. Bye for now. +snape.age // 58 +snape.subject; // Dark arts</code></pre> + +<p>Person을 수정하지 않고 Teacher를 생성한 것처럼 또 다른 하위클래스도 생성할 수 있습니다.</p> + +<div class="note"> +<p><strong>Note</strong>: GitHub에서 <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/es2015-class-inheritance.html">es2015-class-inheritance.html</a> 예제를 참조하세요(<a href="https://mdn.github.io/learning-area/javascript/oojs/advanced/es2015-class-inheritance.html">실행 페이지</a>).</p> +</div> + +<h2 id="Getters와_Setters">Getters와 Setters</h2> + +<p>생성한 클래스 인스턴스의 속성 값을 변경하거나 최종 값을 예측할 수 없는 경우가 있을 겁니다. Teacher 예제를 보면 인스턴스를 생성하기 전에는 어떤 과목을 가르칠지 아직 모릅니다. 학기 도중에 가르치는 과목이 변경될 수도 있구요.</p> + +<p>이런 상황에 getter/setter가 필요합니다.</p> + +<p>Teacher 클래스에 getter/setter를 추가해 봅시다. 마지막에 작성했던 예제를 그대로 사용해보죠.</p> + +<p>Getter와 setter는 쌍으로 동작합니다. Getter가 현재 값을 반환한다면 그에 대응하는 setter는 해당하는 값을 변경합니다.</p> + +<p>수정된 <code>Teacher</code> 클래스는 아래와 같습니다:</p> + +<pre><code>class Teacher extends Person { + constructor(first, last, age, gender, interests, subject, grade) { + super(first, last, age, gender, interests); + // subject and grade are specific to Teacher + this._subject = subject; + this.grade = grade; + } + + get subject() { + return this._subject; + } + + set subject(newSubject) { + this._subject = newSubject; + } +}</code></pre> + +<p>위 클래스를 보시면 <code>subject</code> 속성에 대해 getter와 setter가 생겼습니다. 멤버 변수에는 _를 붙여 getter/setter와 구분을 하였습니다. 이렇게 하지 않으면 get/set을 호출할때마다 에러가 발생합니다:</p> + +<ul> + <li><code>snape</code> 객체의 <code>_subject</code> 속성 값을 보려면 <code>snape._subject</code>를 실행합니다.</li> + <li>To show the current value of the <code>_subject</code> property of the <code>snape</code> object we can use <code>snape._subject</code>.</li> + <li><code>_subject</code>에 새 값을 할당하려면 <code>snape._subject="new value"</code>를 실행합니다.</li> +</ul> + +<p>두 기능이 실제로 어떻게 작동하는지 아래를 참조하세요:</p> + +<pre><code>// Check the default value +console.log(snape._subject) // Returns "Dark arts" + +// Change the value +snape._subject="Balloon animals" // Sets subject to "Balloon animals" + +// Check it again and see if it matches the new value +console.log(snape._subject) // Returns "Balloon animals"</code></pre> + +<div class="note"> +<p><strong>Note</strong>: GitHub에서 <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/es2015-getters-setters.html">es2015-getters-setters.html</a> 예제를 참조하세요(<a href="https://mdn.github.io/learning-area/javascript/oojs/advanced/es2015-getters-setters.html">실행 페이지</a>).</p> +</div> + +<h2 id="JavaScript에서_언제_상속을_사용해야_할까">JavaScript에서 언제 상속을 사용해야 할까?</h2> + +<p>이 마지막 문서를 읽고 나면 "뭐가 이리 어렵냐"고 생각하실지도 모르겠습니다. 어렵긴 합니다 프로토타입과 상속은 Javascript에서 가장 난해한 부분이거든요. 하지만 이 부분은 Javascript가 강력하고 유연한 언어로써 작용할 수 있는 원동력이기에 충분한 시간을 들여 배울 가치가 있습니다.</p> + +<p>어찌보면 여러분은 항상 상속하고 있었습니다. Web API나 브라우저 내장 객체인 string, array 등의 메소드/속성을 사용하면서 암묵적으로 상속을 사용하고 있었던거죠.</p> + +<p>처음 시작하거나 작은 프로젝트에서 직접 상속을 구현하는 코드를 작성하는 경우는 그리 많지 않습니다. 필요하지도 않는데 상속을 위한 코드를 구현하는 건 시간 낭비에 불과하죠. 하지만 코드량이 많아질수록 상속이 필요한 경우가 생깁니다. 동일한 기능을 가진 클래스가 많아졌음을 발견했다면 기능들을 한데 묶어 공유할 수 있도록 일반 객체를 만들고 특이 객체들에게 상속하는 방식이 훨씬 편하고 유용하다는 점을 알 수 있습니다.</p> + +<div class="note"> +<p><strong>Note</strong>: Javascript에서는 프로토타입을 통해 상속이 구현되어 있어 이 방식을 흔히 <strong>위임</strong>이라고 표현합니다. 특이 객체들이 일반 객체에게 일부 기능의 실행을 위임하는 것이죠.</p> +</div> + +<p>상속을 구현할때 상속 레벨을 너무 깊게 하지 말고, 메소드와 속성들이 정확히 어디에 구현되어 있는지 항상 인지해야 합니다. 브라우저 내장 객체의 prototype 역시 일시적으로 수정이 가능하지만 정말로 필요한 경우를 제외하고는 건드리지 말아야 합니다. 너무 깊은 상속은 디버그 할 때 끝없는 혼돈과 고통만을 줄 겁니다.</p> + +<p>궁극적으로 객체는 함수나 반복문과 같이 고유한 역할과 장점을 지닌 채 코드를 재사용하는 또 다른 방법입니다. 서로 연관된 변수와 함수들을 하나로 묶어 다룰 필요가 있을때 객체가 좋은 아이디어입니다. 한 곳에서 다른 곳으로 데이터 집합을 전달할 때에도 객체가 유용합니다. 두가지 모두 생성자나 상속 없이도 가능한 일입니다. 딱 하나의 인스턴스만 필요할 경우 객체를 선언하지 않고 객체 리터럴만으로도 충분합니다. 당연히 상속은 필요없구요.</p> + +<h2 id="요약">요약</h2> + +<p>이 글에서는 여러분들이 반드시 알아야 할 OOJS 이론과 문법의 나머지 부분에 대해 다루고 있습니다. 이 시점에서 여러분은 javascript 객체와 OOP 기초, 프로토타입과 프로토타입 상속, 클래스(생성자)를 만들고 인스턴스를 생성하며 기능을 추가하고, 다른 클래스를 상속 받아 하위 클래스를 만드는 방법을 배웠습니다.</p> + +<p>다음 글에서는 Javascript 객체로 데이터를 교환하는 방식인 Javascript Object Notation(JSON)에 대해 알아봅시다.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="http://www.objectplayground.com/">ObjectPlayground.com</a> — A really useful interactive learning site for learning about objects.</li> + <li><a href="https://www.amazon.com/gp/product/193398869X/">Secrets of the JavaScript Ninja</a>, Chapter 6 — A good book on advanced JavaScript concepts and techniques, by John Resig and Bear Bibeault. Chapter 6 covers aspects of prototypes and inheritance really well; you can probably track down a print or online copy fairly easily.</li> + <li><a href="https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&%20object%20prototypes/README.md#you-dont-know-js-this--object-prototypes">You Don't Know JS: this & Object Prototypes</a> — Part of Kyle Simpson's excellent series of JavaScript manuals, Chapter 5 in particular looks at prototypes in much more detail than we do here. We've presented a simplified view in this series of articles aimed at beginners, whereas Kyle goes into great depth and provides a more complex but more accurate picture.</li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</p> + + + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li> +</ul> diff --git a/files/ko/learn/javascript/objects/json/index.html b/files/ko/learn/javascript/objects/json/index.html new file mode 100644 index 0000000000..a9d5751319 --- /dev/null +++ b/files/ko/learn/javascript/objects/json/index.html @@ -0,0 +1,351 @@ +--- +title: JSON으로 작업하기 +slug: Learn/JavaScript/Objects/JSON +tags: + - JSON + - JSON 객체 + - JSON 문자열로 변환 + - 입문자 + - 초보자 +translation_of: Learn/JavaScript/Objects/JSON +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">JavaScript Object Notation (JSON)은 Javascript 객체 문법으로 구조화된 데이터를 표현하기 위한 문자 기반의 표준 포맷입니다. 웹 어플리케이션에서 데이터를 전송할 때 일반적으로 사용합니다(서버에서 클라이언트로 데이터를 전송하여 표현하려거나 반대의 경우). 여기저기서 자주 보았을테니 여기선 JSON을 파싱, 데이터에 접근하고 JSON을 생성하는 등 Javascript로 JSON을 다루는 법에 대해 알아봅시다.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">사전지식:</th> + <td>컴퓨터 기초, HTML과 CSS에 대한 기본 지식, Javascript 기초 (<a href="/en-US/docs/Learn/JavaScript/First_steps">First steps</a>과 <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Building blocks</a> 참조), OOJS 기초 (<a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction to objects</a> 참조).</td> + </tr> + <tr> + <th scope="row">목표:</th> + <td>JSON에 담긴 데이터를 이용하는 법과 JSON 객체 생성하는 법에 대해 알아보기.</td> + </tr> + </tbody> +</table> + +<h2 id="아니_대체_JSON이_뭐죠">아니, 대체 JSON이 뭐죠?</h2> + +<p>{{glossary("JSON")}} 는 <a href="https://en.wikipedia.org/wiki/Douglas_Crockford">Douglas Crockford</a>가 널리 퍼뜨린 Javascript 객체 문법을 따르는 문자 기반의 데이터 포맷입니다. JSON이 Javascript 객체 문법과 매우 유사하지만 딱히 Javascript가 아니더라도 JSON을 읽고 쓸 수 있는 기능이 다수의 프로그래밍 환경에서 제공됩니다.</p> + +<p>JSON은 문자열 형태로 존재합니다 — 네트워크를 통해 전송할 때 아주 유용하죠. 데이터에 억세스하기 위해서는 네이티브 JSON 객체로 변환될 필요가 있습니다. 별로 큰 문제는 아닌 것이 Javascript는 <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">JSON</a> 전역 객체를 통해 문자열과 JSON 객체의 상호변환을 지원합니다.</p> + +<div class="note"> +<p><strong>Note</strong>: 문자열에서 네이티브 객체로 변환하는 것은 파싱(Parsing)이라고 합니다. 네트워크를 통해 전달할 수 있게 객체를 문자열로 변환하는 과정은 문자열화(Stringification)이라고 합니다.</p> +</div> + +<p>개별 JSON 객체를 <code>.json</code> 확장자를 가진 단순 텍스트 파일에 저장할 수 있습니다. {{glossary("MIME 타입")}}은 <code>application/json</code> 입니다.</p> + +<h3 id="JSON_구조">JSON 구조</h3> + +<p>위에서 설명했듯이 JSON은 Javascript 객체 리터럴 문법을 따르는 문자열입니다. JSON 안에는 마찬가지로 Javascript의 기본 데이터 타입인 문자열, 숫자, 배열, 불리언 그리고 다른 객체를 포함할 수 있습니다. 이런 방식으로 여러분은 데이터 계층을 구축할 수 있습니다, 아래 처럼요.</p> + +<pre class="brush: json notranslate">{ + "squadName": "Super hero squad", + "homeTown": "Metro City", + "formed": 2016, + "secretBase": "Super tower", + "active": true, + "members": [ + { + "name": "Molecule Man", + "age": 29, + "secretIdentity": "Dan Jukes", + "powers": [ + "Radiation resistance", + "Turning tiny", + "Radiation blast" + ] + }, + { + "name": "Madame Uppercut", + "age": 39, + "secretIdentity": "Jane Wilson", + "powers": [ + "Million tonne punch", + "Damage resistance", + "Superhuman reflexes" + ] + }, + { + "name": "Eternal Flame", + "age": 1000000, + "secretIdentity": "Unknown", + "powers": [ + "Immortality", + "Heat Immunity", + "Inferno", + "Teleportation", + "Interdimensional travel" + ] + } + ] +}</pre> + +<p>이 객체를 Javascript 프로그램에서 로드하고, 예를 들어 <code>superHeroes</code>라는 이름의 변수에 파싱하면 <a href="/en-US/docs/Learn/JavaScript/Objects/Basics">JavaScript object basics</a> 문서에서 보았던 것처럼 점/브라켓 표현법을 통해 객체 내 데이터에 접근할 수 있게 됩니다. 아래와 같이요:</p> + +<pre class="brush: js notranslate">superHeroes.homeTown +superHeroes['active']</pre> + +<p>하위 계층의 데이터에 접근하려면, 간단하게 프로퍼티 이름과 배열 인덱스의 체인을 통해 접근하면 됩니다. 예를 들어 superHeroes의 두 번째 member의 세 번째 power에 접근하려면 아래와 같이 하면 됩니다.</p> + +<pre class="brush: js notranslate">superHeroes['members'][1]['powers'][2]</pre> + +<ol> + <li>우선 변수 이름은 — <code>superHeroes</code>입니다.</li> + <li><code>members</code> 프로퍼티에 접근하려면, <code>["members"]</code>를 입력합니다.</li> + <li><code>members</code>는 객체로 구성된 배열입니다. 두 번째 객체에 접근할 것이므로 <code>[1]</code>를 입력합니다.</li> + <li>이 객체에서 <code>powers</code> 프로퍼티에 접근하려면 <code>["powers"]</code>를 입력합니다.</li> + <li><code>powers</code> 프로퍼티 안에는 위에서 선택한 hero의 superpower들이 있습니다. 세 번째 것을 선택해야 하므로 <code>[2]</code>.</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: 위에서 볼 수 있듯 <a href="http://mdn.github.io/learning-area/javascript/oojs/json/JSONTest.html">JSONTest.html</a> 예제에서 JSON 내 변수(<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/JSONTest.html">source code</a> 참고)를 만들었다. 당신 브라우저의 Javascript 콘솔을 통하여 이 코드를 로드하고 그 변수 안에 얻을 수 있는 데이터에 접근해보자.</p> +</div> + +<h3 id="JSON에서의_배열">JSON에서의 배열</h3> + +<p>앞서 JSON 텍스트는 기본적으로 자바스크립트의 오브젝트와 비슷하게 생겼다고 언급하였습니다. 그리고 그것은 대부분 맞습니다. "대부분 맞다"라고 말한 이유는 자바스크립트의 배열 또한 JSON에서 유효하기 때문입니다.</p> + +<pre class="brush: json notranslate">[ + { + "name": "Molecule Man", + "age": 29, + "secretIdentity": "Dan Jukes", + "powers": [ + "Radiation resistance", + "Turning tiny", + "Radiation blast" + ] + }, + { + "name": "Madame Uppercut", + "age": 39, + "secretIdentity": "Jane Wilson", + "powers": [ + "Million tonne punch", + "Damage resistance", + "Superhuman reflexes" + ] + } +]</pre> + +<p>위 예제는 완벽히 올바른 형태의 JSON입니다. 배열의 요소(파싱된 버전)에 접근하기 위해서는 배열의 인덱스를 사용하면 됩니다. <code>[0]["powers"][0]</code> 와 같이 말이죠.</p> + +<h3 id="Other_notes">Other notes</h3> + +<ul> + <li>JSON은 순수히 데이터 포맷입니다. 오직 프로퍼티만 담을 수 있습니다. 메서드는 담을 수 없습니다.</li> + <li>JSON은 문자열과 프로퍼티의 이름 작성시 큰 따옴표만을 사용해야 합니다. 작은 따옴표는 사용불가합니다.</li> + <li>콤마나 콜론을 잘못 배치하는 사소한 실수로 인해 JSON파일이 잘못되어 작동하지 않을 수 있습니다. <a href="http://jsonlint.com/">JSONLint</a>같은 어플리케이션을 사용해 JSON 유효성 검사를 할 수 있습니다.</li> + <li>JSON은 JSON내부에 포함할 수 있는 모든 형태의 데이터 타입을 취할 수 있습니다. 즉, 배열이나 오브젝트 외에도 단일 문자열이나 숫자또한 유효한 JSON 오브젝트가 됩니다.</li> + <li>자바스크립트에서 오브젝트 프로퍼티가 따옴표로 묶이지 않을 수도 있는 것과는 달리, JSON에서는 따옴표로 묶인 문자열만이 프로퍼티로 사용될 수 있습니다.</li> +</ul> + +<h2 id="해보면서_배우기_JSON을_다뤄_보자">해보면서 배우기: JSON을 다뤄 보자</h2> + +<p>웹사이트에서 JSON 데이터를 어떻게 사용할 수 있는지 예제를 통해 살펴봅시다.</p> + +<h3 id="시작하기">시작하기</h3> + +<p>우선 로컬 저장소에 <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes.html">heroes.html</a> 와 <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/style.css">style.css</a> 파일을 복사해주세요. style.css 파일은 페이지에 적용할 간단한 CSS를 담고 있으며, heros.html 파일은 간단한 body HTML을 담고 있습니다.</p> + +<pre class="brush: html notranslate"><header> +</header> + +<section> +</section></pre> + +<p>자바스크립트 코드를 담기 위한{{HTMLElement("script")}} 요소를 추가해 주세요. 현재는 두 줄의 코드만 작성되어 있습니다. {{HTMLElement("header")}} 와 {{HTMLElement("section")}} 요소를 참조하여 변수에 담는 코드입니다. :</p> + +<pre class="brush: js notranslate">var header = document.querySelector('header'); +var section = document.querySelector('section');</pre> + +<p>JSON 데이터를 다음 깃허브 링크에서 가져올수 있습니다. <a href="https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json">https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json</a>.</p> + +<p>페이지에 JSON 데이터를 로딩하고 DOM 조작을 통해 아래와 같이 만들어 봅시다. :</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13857/json-superheroes.png" style="display: block; margin: 0 auto;"></p> + +<h3 id="JSON_가져오기">JSON 가져오기</h3> + +<p>JSON을 가져오기 위해서는, {{domxref("XMLHttpRequest")}} (때론 <strong>XHR</strong>)로 불리는 API를 사용하면 된다. 이것은 매우 유용한 JavaScript 오브젝트로 JavaScript (e.g. images, text, JSON, even HTML snippets)를 통해 우리가 서버로 부터 다양한 리소스를 가져오는 요청을 만들어 준다. 즉, 전체 페이지를 불러오지 않고도 필요한 부분만을 업데이트 할 수 있다. 이 기능은 좀 더 효과적으로 반응형 웹페이지을 다루는데 흥미로울 수 있으나, 아쉽게도 이 내용에 대한 자세한 부분은 여기서 다루지 않는다.</p> + +<ol> + <li>일단, 변수로 둘 JSON의 URL을 가져와야 합니다. 아래의 코드를 당신의 JavaScript 코드 내에 추가해 주세요. + <pre class="brush: js notranslate">var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';</pre> + </li> + <li>요청을 만들기 위해, 우리는 <code>new</code> 키워드를 이용하여 <code>XMLHttpRequest</code> 생성자로부터 새로운 request 인스턴스를 생성해야 합니다. 아래의 코드를 추가해 주세요. + <pre class="brush: js notranslate">var request = new XMLHttpRequest();</pre> + </li> + <li>이제 <code><a href="/en-US/docs/Web/API/XMLHttpRequest/open">open()</a></code> 메소드를 사용해 새로운 요청을 만듭니다. 아래의 코드를 추가해 주세요. + <pre class="brush: js notranslate">request.open('GET', requestURL);</pre> + + <p>이것은 최소 두 개의 매개변수를 가집니다. 다른 선택적 매개변수도 가능해요. 이건 단순 예제니깐 두 가지 필수 매개변수만 취할게요.</p> + + <ul> + <li>HTTP 메서드는 네트워크 요청을 만들 때 사용됩니다. 이 경우 <code><a href="/en-US/docs/Web/HTTP/Methods/GET">GET</a></code> 을 사용하는게 좋겠어요. 우린 그저 데이터를 가져오면 되니깐요.</li> + <li>URL은 요청을 보낼 곳을 지정합니다. 우리가 저장해 둔 JSON 파일의 URL로 지정할게요.</li> + </ul> + </li> + <li>다음으로, 아래의 두 줄을 추가해 주세요. <code><a href="/en-US/docs/Web/API/XMLHttpRequest/responseType">responseType</a></code> 을 JSON으로 설정했어요. XHR로 하여금 서버가 JSON 데이터를 반환할 것이며, 자바스크립트 객체로서 변환될 것이라는 걸 알게 하기 위해서죠. 이제 <code><a href="/en-US/docs/Web/API/XMLHttpRequest/send">send()</a></code> 메서드를 이용해 요청을 보냅시다. + <pre class="brush: js notranslate">request.responseType = 'json'; +request.send();</pre> + </li> + <li>마지막 부분은 서버의 응답을 기다리고, 그것의 처리까지와 관련된 섹션입니다. 코드 아래에 다음의 코드를 추가해 주세요. + <pre class="brush: js notranslate">request.onload = function() { + var superHeroes = request.response; + populateHeader(superHeroes); + showHeroes(superHeroes); +}</pre> + </li> +</ol> + +<p>우리는 요청에 대한 응답을 <code>superHeroes</code>라는 변수에 저장할 겁니다.(<code><a href="/en-US/docs/Web/API/XMLHttpRequest/response">response</a></code> 프로퍼티로 가능) 이 변수는 이제 JSON 데이터에 기반한 자바스크립트 객체를 포함하게 됩니다! 두 개의 함수를 호출해 이 객체를 전달합시다. 하나는 <<code>header></code> 를 적절한 데이터로 채울 것이고, 다른 하나는 팀의 각 히어로에 대한 정보 카드를 생성하여 <code><section></code>내에 집어넣을 겁니다.</p> + +<p>우리는 로드 이벤트가 request 객체에 발생할 때에 작동하는 이벤트 핸들러 내에 코드를 넣었습니다. (<code><a href="/en-US/docs/Web/API/XMLHttpRequestEventTarget/onload">onload</a></code> 참고) 왜냐하면 응답이 성공적으로 돌아왔을 때만 로드 이벤트가 작동하기 때문입니다. 이러한 방식은 우리가 무언가를 시도하려고 할 때 <code>request.response</code> 가 확실히 가능하다는 것을 보장해 줍니다.</p> + +<h3 id="헤더_조작하기">헤더 조작하기</h3> + +<p>우린 JSON 데이터를 가져왔고, 그것을 자바스크립트 객체로 변환했어요. 이제 우리가 위에서 언급한 두 개의 함수를 사용함으로써 이것을 활용해 봅시다. 우선, 이전 코드 아래에 다음 함수 정의를 추가해 주세요.</p> + +<pre class="brush: js notranslate">function populateHeader(jsonObj) { + var myH1 = document.createElement('h1'); + myH1.textContent = jsonObj['squadName']; + header.appendChild(myH1); + + var myPara = document.createElement('p'); + myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed']; + header.appendChild(myPara); +}</pre> + +<p>우리는 이 매개변수를 <code>jsonObj</code>라고 이름 붙였습니다. 여러분으로 하여금 이 자바스크립트 객체가 JSON으로 부터 생겨났다는 걸 상기시켜 주기 위해서죠. 첫번째로 <code><a href="/en-US/docs/Web/API/Document/createElement">createElement()</a></code>로 {HTMLElement("h1")}} 요소를 생성하고, 이것의 <code><a href="/en-US/docs/Web/API/Node/textContent">textContent</a></code>를 객체의 <code>squadName</code> 프로퍼티와 같도록 만들어 준 뒤, <code><a href="/en-US/docs/Web/API/Node/appendChild">appendChild()</a></code>를 사용해서 헤더에 붙이도록 했습니다. We then do a very similar 이와 비슷한 과정을 paragraph에도 적용했죠. 생성하고,그것의 text content를 설정하고 헤더에 붙이도록요. 차이점이라면 그것의 텍스트가 객체의 <code>homeTown</code> 과 <code>formed</code> 프로퍼티를 포함한 문자열로 설정된 거예요.</p> + +<h3 id="히어로_정보_카드_만들기">히어로 정보 카드 만들기</h3> + +<p>자, 다음으로 슈퍼히어로 카드를 생성하고 보여줄 함수를 코드의 마지막에 추가해 주세요.</p> + +<pre class="brush: js notranslate">function showHeroes(jsonObj) { + var heroes = jsonObj['members']; + + for (var i = 0; i < heroes.length; i++) { + var myArticle = document.createElement('article'); + var myH2 = document.createElement('h2'); + var myPara1 = document.createElement('p'); + var myPara2 = document.createElement('p'); + var myPara3 = document.createElement('p'); + var myList = document.createElement('ul'); + + myH2.textContent = heroes[i].name; + myPara1.textContent = 'Secret identity: ' + heroes[i].secretIdentity; + myPara2.textContent = 'Age: ' + heroes[i].age; + myPara3.textContent = 'Superpowers:'; + + var superPowers = heroes[i].powers; + for (var j = 0; j < superPowers.length; j++) { + var listItem = document.createElement('li'); + listItem.textContent = superPowers[j]; + myList.appendChild(listItem); + } + + myArticle.appendChild(myH2); + myArticle.appendChild(myPara1); + myArticle.appendChild(myPara2); + myArticle.appendChild(myPara3); + myArticle.appendChild(myList); + + section.appendChild(myArticle); + } +}</pre> + +<p>우선, 새로운 변수 내의 자바스크립트 객체에 <code>members</code> 프로퍼티를 저장해 주세요. 이 배열은 각 히어로에 대한 정보를 가진 여러 개의 객체를 포함합니다.</p> + +<p>다음으로, 우리는 <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code#The_standard_for_loop">for loop</a>를 사용하여 배열 내의 각 객체에 반복 실행을 걸겁니다.</p> + +<ol> + <li>몇 개의 새로운 요소를 생성해 주세요: <code><article></code>, <code><h2></code>, 3개의 <code><p></code>, 그리고 <code><ul></code>.</li> + <li><h2>가 히어로의 <code>name</code>을 가지도록 설정해 주세요.</li> + <li>목록 내의 정보를 소개하기 위해 세 개의 paragraph 안에 그들의 <code>secretIdentity</code>, <code>age</code>, 그리고 "Superpowers:" 라는 문장을 넣어 주세요.</li> + <li><code>superPowers</code> 라는 새로운 변수 안에 <code>powers</code>프로퍼티를 저장해 주세요. 이것은 현재 히어로의 초능력(superpower)을 열거한 배열을 포함합니다.</li> + <li>현재 히어로의 초능력을 반복 실행할 또다른 <code>for</code> 반복문을 사용합니다. 하나의 객체씩 <code><li></code> 를 생성하고, 그 안에 초능력을 집어 넣고, <code>appendChild()</code>를 사용하여 '<code>myList'</code> 라는 <code><ul></code> 안에 <code>listItem</code> 을 집어 넣습니다.</li> + <li>마지막으로 <code><article></code> (<code>myArticle</code>) 안에 <code><h2></code>, <code><p></code>, 그리고 <code><ul></code> 넣은 뒤, <code><section></code> 안에 <code><article></code>을 넣어 줍니다. 요소가 추가되어 지는 순서가 중요해요.왜냐하면 HTML 내에 보여질 거거든요.</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: 만약 실습에 문제를 겪고 있다면, <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes-finished.html">heroes-finished.html</a> 코드를 참조하세요. (<a href="http://mdn.github.io/learning-area/javascript/oojs/json/heroes-finished.html">running live</a> 또한 보세요.)</p> +</div> + +<div class="note"> +<p><strong>Note</strong>: 만약 우리가 주로 사용하는 JavaScript 객체에 접근하기 위한 점/괄호 표기법을 따르는데 문제를 겪고 있다면, 다른 탭이나 당신의 선호하는 텍스트 에디터에 <a href="http://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json">superheroes.json</a> 파일을 여는 것이 도움이 될 것이다. 또한 당신은 점/괄호 표기법에 대한 다른 정보를 위해 <a href="/en-US/docs/Learn/JavaScript/Objects/Basics">JavaScript object basics</a> 글을 다시 확인하는 것을 권합니다.</p> +</div> + +<h2 id="객체와_문자_사이의_변환">객체와 문자 사이의 변환</h2> + +<p>위의 예제는 자바스크립트 객체에 접근한다는 관점에서 단순한 편이었죠. 왜냐하면 자바스크립트 객체를 사용해 우리는 XHR 요청을 곧장 JSON 응답으로 변환했으니깐요.</p> + +<pre class="brush: js notranslate">request.responseType = 'json';</pre> + +<p>하지만 우리는 이따금 재수 없어요. 때때로 우리는 날것의 JSON 문자열을 받기도 하고, 그것을 우리 스스로가 객체로 변환시켜야 할 때도 생기거든요. 그리고 네트워크를 통해 자바스크립트 객체를 보내고 싶을 때도 우리는 전송 전에 그걸 JSON(문자열)로 변환시켜야 해요. 다행히도, 이 두가지 문제가 웹 개발에 있어서 매우 흔한 덕에 다음과 같은 두가지 방법을 포함한 JSON 내장 객체가 브라우저 내에서 이용 가능합니다. </p> + +<ul> + <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse">parse()</a></code>: JSON 문자열을 매개변수로서 수용하고, 일치하는 자바스크립트 객체로서 변환합니다.</li> + <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify">stringify()</a></code>: 객체를 매개변수로서 수용하고, JSON 문자열 형태로 변환합니다. </li> +</ul> + +<p> 당신은 예제인 <a href="http://mdn.github.io/learning-area/javascript/oojs/json/heroes-finished-json-parse.html">heroes-finished-json-parse.html</a>에서 첫번째 동작을 확인할 수 있습니다.(아래 코드 참고-<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes-finished-json-parse.html">source code</a>) — JSON 텍스트를 반환하기 위한 추가한 XHR와 JavaScript 객체로 전환하기 위해 사용된 <code>parse()</code>제외하면 이 코드는 이전에 우리가 빌드한 것과 완전히 같은 코드입니다. 다음은중요한 코드의 일부입니다.:</p> + +<pre class="brush: js notranslate">request.open('GET', requestURL); +request.responseType = 'text'; // now we're getting a string! +request.send(); + +request.onload = function() { + var superHeroesText = request.response; // get the string from the response + var superHeroes = JSON.parse(superHeroesText); // convert it to an object + populateHeader(superHeroes); + showHeroes(superHeroes); +}</pre> + +<p>예상했겠지만, <code>stringify()</code> 는 반대의 방식으로 작용됩니다. 다음 나오는 코드 라인들을 당신의 브라우저 JavaScript 콘솔에 동작을 확인하면서 한 줄씩 입력해봅시다.:</p> + +<pre class="brush: js notranslate">var myJSON = { "name": "Chris", "age": "38" }; +myJSON +var myString = JSON.stringify(myJSON); +myString</pre> + +<p>이 페이지에서는 우리는 JavaScript 객체를 생성하고 있으며 이 객체가 무엇을 포함하고 있는지 확인하고 <code>stringify()</code> —반환된 값을 새로운 변수에 저장합니다—를 사용해서 JSON 문자열로 변환시켰습니다. 다시 한 번 더 확인해 봅시다.</p> + +<h2 id="실력을_시험해보자!">실력을 시험해보자!</h2> + +<p> 당신은 이 글의 끝에 도달했지만 가장 중요한 정보들을 기억하고 있습니까? 다음 단계를 가기 전 당신이 얼마나 이 정보를 습득하고 있는지 확인할 수 있는 테스트를 할 수 있습니다. — <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Test_your_skills:_JSON">Test your skills: JSON</a></p> + +<h2 id="요약">요약</h2> + +<p> 이 글에서, 당신의 프로그램에서 JSON을 어떻게 생성하고 구성 요소를 파악할 수 있는지, 그리고 JSON 안에 묶여 있는 자료들에 어떻게 접근하는 방법을 포함한 JSON을 사용하기 위한 간단한 가이드를 제공했습니다. 다음 글에서는, 객체 지향적인 JavaScript에 대해 시작해 볼 것입니다.</p> + +<h2 id="참고">참고</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">JSON object reference page</a></li> + <li><a href="/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest object reference page</a></li> + <li><a href="/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest">Using XMLHttpRequest</a></li> + <li><a href="/en-US/docs/Web/HTTP/Methods">HTTP request methods</a></li> + <li><a href="http://json.org">Official JSON web site with link to ECMA standard</a></li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}</p> + +<h2 id="다음_단계">다음 단계</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li> +</ul> diff --git a/files/ko/learn/javascript/objects/object-oriented_js/index.html b/files/ko/learn/javascript/objects/object-oriented_js/index.html new file mode 100644 index 0000000000..df1bf59c17 --- /dev/null +++ b/files/ko/learn/javascript/objects/object-oriented_js/index.html @@ -0,0 +1,287 @@ +--- +title: Object-oriented JavaScript for beginners +slug: Learn/JavaScript/Objects/Object-oriented_JS +tags: + - Article + - Beginner + - CodingScripting + - JavaScript + - Learn + - 'l10n:priority' +translation_of: Learn/JavaScript/Objects/Object-oriented_JS +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">자, 이제 기초 단계를 벗어나서,객체지향 JavaScript (OOJS) 을 보도록 하죠 — 이 문서에서 객체지향 (OOP) 이론에 대한 기초를 훑어본 후, 자바스크립트가 생성자와 함수를 통해 객체 클래스 개념을 따라했는지, 그리고 어떻게 객체를 만드는지 알아볼겁니다.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">선수조건:</th> + <td>컴퓨터 기본지식, HTML과 CSS에 대한 기본적인 이해,자바스크립트에 어느 정도 익숙할 것 (see <a href="/ko/docs/Learn/JavaScript/First_steps">First steps</a> and <a href="/ko/docs/Learn/JavaScript/Building_blocks">Building blocks</a>). OOJS 기초 지식 (see <a href="/ko/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction to objects</a>).</td> + </tr> + <tr> + <th scope="row">학습목표:</th> + <td>객체지향에 대한 기본 지식을 습득 하고, 객체 지향이 자바스크립트에 어떻게 적용되었는지 ( "모든 것은 객체다") 와 어떻게 생성자와 객체 인스턴스를 만드는지에 대해 이해한다.</td> + </tr> + </tbody> +</table> + +<h2 id="객체지향_프로그래밍_—_기초">객체지향 프로그래밍 — 기초</h2> + +<p>객체지향 프로그래밍(OOP)의 개요를 설명하는 것으로 시작하겠습니다. 지금 단계에서 OOP의 모든 것을 설명면 너무 복잡해서 혼란만을 가중시킬 것이기 때문에 최대한 간단히 설명하겠습니다. OOP의 기본 컨셉은 프로그램 내에서 표현하고자 하는 실 세계(real world)의 일들을 객체를 사용해서 모델링 하고, 객체를 사용하지 않으면 불가능 혹은 무지 어려웠을 일들을 쉽게 처리하는 방법을 제공한다는 것입니다.</p> + +<p>객체는 당신이 모델링하고자 하고자 하는 일이나 기능 혹은 필요한 행동들을 표현하는 프로그램 코드와 그와 연관된 데이터로 구성됩니다. 객체는 데이터(그리고, 함수 역시)를 감싸서 ,(공식적인 표현으로는 <strong>encapsulate</strong>) 객체 패키지(해당 객체를 참조하기 위한 이름. <strong>namespace </strong>라고도 불리죠)안에 보관합니다. 이는 계층 구조를 만드는데 용이하고 사용하기에도 쉽게 하기 위해서죠; 또한, 객체는 네트워크를 통해 쉽게 전송될 수 있도록 데이터를 저장하는 용도로도 많이 사용됩니다.</p> + +<h3 id="객체_템플릿_정의">객체 템플릿 정의</h3> + +<p>자, 학교의 선생님과 학생들의 정보를 보여주는 간단한 프로그램이 있다고 칩시다. 여기서는 OOP의 일반적인 개념만을 살펴볼 뿐이지, 특정 언어에 국한된 내용을 이야기하지는 않을겁니다.</p> + +<p>시작해보자면, <a href="/ko/docs/Learn/JavaScript/Objects/Basics">first objects article</a> 에서 배웠던 Person 객체로 돌아가봅시다. 거기서 "사람"에 대한 기초적인 데이터와 기능을 정의했었죠. "사람"을 구별할 수 있는 특징은 많습니다 (그들의 주소, 키,신발사이즈, DNA 프로필, 여권번호, 중요한 개인적 자실 등 ...) ,하지만 이 예제에서는 오직 이름, 나이, 성별 그리고 취미만을 다룰겁니다. 여기에 더불어 이 데이터를 기반으로 각 개인에 대한 간단한 소개말과 인사말을 표시할 수 있도록 할 겁니다 . 이런 과정을 <strong>추상화</strong> — 프로그래머의 의도에 맞추어 가장 중요한 것들만을 뽑아서 복잡한 것들을 보다 단순한 모델로 변환하는 작업 - 라고 합니다.<img alt="" src="https://mdn.mozillademos.org/files/13889/person-diagram.png" style="display: block; height: 219px; margin: 0px auto; width: 610px;"></p> + +<h3 id="실제_객체_생성">실제 객체 생성</h3> + +<p><strong>객체 인스턴스</strong>는 클래스를 통해서 만들 수 있습니다.— 객체는 클래스에 정의된 데이터와 함수를 갖습니다. Person클래스를 통해서, 실제 '사람' 객체를 생성할 수 있습니다.:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/15163/MDN-Graphics-instantiation-2-fixed.png" style="display: block; height: 702px; margin: 0px auto; width: 695px;"></p> + +<p>클래스로부터 객체의 인스턴스가 생성될 때는 클래스의 <strong>생성자 함수</strong> 가 호출됩니다.클래스에서 객체 인스턴스가 생성되는 일련의 과정을 인스턴스화(<strong>instantiation</strong>)라고 합니다 — 객체의 인스턴스는 클래스를 통해 만들어집니다.</p> + +<h3 id="특별한_클래스">특별한 클래스</h3> + +<p>자, 이번에는 일반적인 사람이 아니라 — 일반적인 사람보다 세분화된 선생님과 학생들이 필요합니다. OOP 에서는,특정 클래스를 기반으로 새로운 클래스를 만들 수 있습니다 — <strong>child 클래스</strong> 는 <strong>부모 클래스</strong>를<strong> </strong><strong>상속</strong> 받아서 만들어집니다. child 클래스는 상속을 통해 부모 클래스에 정의된 데이터와 함수를 고스란히 사용할 수 있습니다. 클래스마다 기능이 달라지는 부분이 있다면, 직접 해당 클래스에 원하는 기능을 정의할 수 있습니다.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13881/MDN-Graphics-inherited-3.png" style="display: block; height: 743px; margin: 0px auto; width: 700px;"></p> + +<p>이것은 매우 유용합니다. 이름,성별,나이 등과 같이 선생님과 학생이 공유하는 많은 공통적인 특징들을 한번만 정의해도 되기 때문이죠. 또한 서로 다른 클래스에 같은 기능을 따로 정의할 수도 있습니다. 정의된 각각의 기능은 서로 다른 namespace에 존재하기 때문입니다. 예를 들어, 학생의 인사는 "안녕, 난 [이름]이야." 와 같은 형식이 될 것입니다. (ex) 안녕, 난 샘이야.) 반면 선생님은 "안녕하세요, 제 이름은 [성] [이름]이고 [과목명]을 담당하고 있습니다." 와 같이 좀 더 격식있는 형식을 사용할 것입니다. (ex) 안녕하세요, 제 이름은 데이브 그리피스이고 화학을 담당하고 있습니다.)</p> + +<div class="note"> +<p><strong>노트</strong>: 혹시 궁금해 하실까봐 말씀드리면, 여러 객체 타입에 같은 기능을 정의할 수 있는 능력을 멋진 용어로 <strong>"다형성(polymorphism)"</strong> 이라고 합니다.</p> +</div> + +<p>이제 자식 클래스들로부터 객체 인스턴스를 만들 수 있습니다. 예를 들면 :</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13885/MDN-Graphics-instantiation-teacher-3.png" style="display: block; height: 743px; margin: 0px auto; width: 700px;"></p> + +<p>다음 부분에선, 어떻게 객체지향 프로그래밍 이론이 자바스크립트에 실제로 적용될 수 있는지 살펴보겠습니다.</p> + +<h2 id="생성자와_객체_인스턴스">생성자와 객체 인스턴스</h2> + +<p>자바스크립트는 객체와 그 기능을 정의하기 위해 <strong>생성자 함수</strong>라고 불리는 특별한 함수를 사용합니다. 이는 보통 우리가 얼마나 많은 객체들을 생성해야 할지 모르기 때문에 유용합니다. 생성자는 효율적으로 필요한 만큼 객체를 생성하고, 데이터와 함수들을 설정하는 방법을 제공합니다.</p> + +<p>생성자로부터 새로운 객체 인스턴스가 생성되면, 객체의 핵심 기능 (프로토타입에 의해 정의됩니다. <a href="/ko/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a> 글에서 자세히 다룰 것입니다.)이 <strong>프로토타입 체인</strong>에 의해 연결됩니다.</p> + +<p>자바스크립트에서 생성자를 이용해 클래스를 만들고, 클래스에서 객체 인스턴스를 만드는 방법을 알아봅시다. 가장 먼저, 첫 객체 글에서 보았던 <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a> 파일을 로컬에 새로 복사하십시오.</p> + +<h3 id="간단한_예제">간단한 예제</h3> + +<ol> + <li>어떻게 일반적인 함수를 이용해 한 사람을 정의할 수 있는지부터 보겠습니다. 이 함수를 <code>script</code> 태그 안에 추가하세요: + + <pre class="brush: js">function createNewPerson(name) { + var obj = {}; + obj.name = name; + obj.greeting = function() { + alert('Hi! I\'m ' + this.name + '.'); + }; + return obj; +}</pre> + </li> + <li>이제 이 함수를 호출하여 새로운 사람을 만들 수 있습니다. 브라우저의 자바스크립트 콘솔을 열어 다음 코드를 입력해보세요: + <pre class="brush: js">var salva = createNewPerson('Salva'); +salva.name; +salva.greeting();</pre> + 이것은 잘 작동하지만, 썩 깔끔하진 않습니다. 객체를 만들기를 원하는데, 왜 굳이 빈 객체를 만들고 내용을 채워 리턴해야 할까요? 다행스럽게도 자바스크립트는 생성자 함수의 형태로 간단한 단축 명령을 제공합니다. 하나 만들어 보도록 하죠!</li> + <li>이전의 createNewPerson 함수를 다음의 코드로 교체하세요: + <pre class="brush: js">function Person(name) { + this.name = name; + this.greeting = function() { + alert('Hi! I\'m ' + this.name + '.'); + }; +}</pre> + </li> +</ol> + +<p>생성자 함수는 클래스의 자바스크립트 버전입니다. 이 함수가 함수가 가질 것 같은 모든 특징을 가지고 있지만, 아무것도 리턴하지 않고 객체를 만들지도 않는다는 것을 깨달으셨나요? 생성자 함수는 단순히 프로퍼티와 메소드를 정의합니다. 또 이를 정의할 때 this 라는 키워드가 사용되고 있는 것을 보실 수 있습니다. 이것은 객체 인스턴스가 생성될 때마다, 객체의 <code>name</code> 프로퍼티가 생성자 함수 호출에서 전달된 name 값과 같아질 것이라고 말하고 있습니다. 그리고 <code>greeting()</code> 메소드 역시 생성자에서 전달된 name 값을 사용할 것입니다.</p> + +<div class="note"> +<p><strong>노트</strong>: 관습적으로, 생성자 함수명은 대문자로 시작하게 합니다. 이 규칙은 생성자 함수가 코드 안에서 잘 구별되도록 해줍니다.</p> +</div> + +<p>그래서 어떻게 생성자 함수를 호출하여 객체들을 만들까요?</p> + +<ol> + <li>이전 코드 아래에 다음 코드들을 추가하세요: + <pre class="brush: js">var person1 = new Person('Bob'); +var person2 = new Person('Sarah');</pre> + </li> + <li> + <p>코드를 저장하고 브라우저를 새로고침합니다. 자바스크립트 콘솔에 다음 코드를 입력해보세요:</p> + </li> + <li> + <pre class="brush: js">person1.name +person1.greeting() +person2.name +person2.greeting()</pre> + </li> +</ol> + +<p>멋지군요! 이제 두 객체가 페이지에 생성된 것이 보입니다. 각각은 서로 다른 namespace에 저장되어있습니다. 객체의 프로퍼티와 메소드들을 사용하려면, <code>person1</code> 또는 <code>person2</code>로부터 호출하여야 합니다. 두 객체의 기능은 따로 패키징되어 서로 충돌하지 않을 것입니다. 그리고 두 Person 객체는 각각 고유의 <code>name</code> 프로퍼티와 <code>greeting()</code> 메소드를 사용할 수 있습니다. 이 둘이 생성될 때 부여받은 자신의 <code>name</code> 값을 사용한다는 것에 주목하십시오. 이것이 <code>this</code>를 사용하는 매우 중요한 이유 중 하나입니다. 객체들은 다른 값이 아니라, 그들이 가진 고유의 값을 사용합니다.</p> + +<p>생성자 호출을 다시 봅시다:</p> + +<pre class="brush: js">var person1 = new Person('Bob'); +var person2 = new Person('Sarah');</pre> + +<p>각각의 경우, <code>new</code> 키워드가 브라우저에게 우리가 새로운 객체 인스턴스를 만들고 싶어한다는 것을 알려줍니다. 괄호로 감싸진 매개변수들과 함께 생성자 이름을 호출하고, 결과는 변수에 담겨집니다. 일반적인 함수가 호출되는 방식과 매우 유사하죠. 각각의 인스턴스는 다음 정의에 따라 생성됩니다.</p> + +<pre class="brush: js">function Person(name) { + this.name = name; + this.greeting = function() { + alert('Hi! I\'m ' + this.name + '.'); + }; +}</pre> + +<p>새 객체가 생성된 이후, <code>person1</code>과 <code>person2</code> 변수는 다음 객체들을 가지게 됩니다.</p> + +<pre class="brush: js">{ + name: 'Bob', + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +} + +{ + name: 'Sarah', + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +}</pre> + +<p>우리가 생성자 함수를 호출할 때마다 매번 <code>greeting()</code> 함수를 다시 정의하는 것이 보입니다. 최선의 방법은 아니죠. 이를 피하기 위해, 우리는 prototype에 함수를 정의합니다. 이를 차후에 다시 살펴보겠습니다.</p> + +<h3 id="생성자_완성시키기">생성자 완성시키기</h3> + +<p>위에서 살펴본 예제는 시작에 불과합니다. 최종적인 <code>Person()</code> 생성자를 만들어봅시다.</p> + +<ol> + <li>여태 작성한 코드를 지우고 아래의 생성자로 대체하세요. 원리는 이전의 예제와 똑같으며, 약간 더 복잡할 뿐입니다: + <pre class="brush: js">function Person(first, last, age, gender, interests) { + this.name = { + 'first': first, + 'last' : last + }; + this.age = age; + this.gender = gender; + this.interests = interests; + this.bio = function() { + alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.'); + }; + this.greeting = function() { + alert('Hi! I\'m ' + this.name.first + '.'); + }; +}</pre> + </li> + <li>이제 생성자로 객체 인스턴스를 만들기 위해, 아래에 이 코드를 추가하세요: + <pre class="brush: js">var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);</pre> + </li> +</ol> + +<p>이제 이전에 해보았듯이, 브라우저의 자바스크립트 콘솔에서 프로퍼티와 메소드를 사용할 수 있습니다:</p> + +<pre class="brush: js">person1['age'] +person1.interests[1] +person1.bio() +// etc.</pre> + +<div class="note"> +<p><strong>노트</strong>: 만약 실행에 문제가 생긴다면, 저희가 준비한 코드와 비교해보세요. <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-finished.html">oojs-class-finished.html</a> (<a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-finished.html">또한 실제로 실행되는 모습을 보세요</a>).</p> +</div> + +<h3 id="추가_예제">추가 예제</h3> + +<p>이를 시작하기 위해서, 몇 개의 객체를 더 생성하는 코드를 추가해보세요. 그리고 생성된 객체 인스턴스의 멤버들을 사용하거나 바꿔보세요.</p> + +<p>더 나아가, 우리의 <code>bio()</code> 메소드엔 몇 가지 문제점이 있습니다. 먼저 결과가 항상 대명사 "He"를 포함한다는 점입니다. 생성된 사람이 여성이거나 다른 성별 분류를 가질지라도 말이죠. 그리고 <code>interests</code> 배열에 몇 개가 포함되어 있더라도 bio는 2개의 취미만을 출력합니다. 클래스 정의 (생성자)에서 이를 해결할 방법이 있을까요? 자유롭게 생성자를 수정해보세요. (약간의 조건문과 반복문이 필요할지도 모르겠습니다). 어떻게 성별에 따라, 혹은 취미의 개수에 따라 문장이 다르게 구성되어야할지 생각해보세요 .</p> + +<div class="note"> +<p><strong>노트</strong>: 하다가 막힌다면, 저희가 제공하는 <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">GitHub 저장소의 모법 답안</a> (<a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">그리고 실행 버전</a>)을 참고하세요. 하지만 일단 직접 해보시죠!</p> +</div> + +<h2 id="객체_인스턴스를_생성하는_다른_방법들">객체 인스턴스를 생성하는 다른 방법들</h2> + +<p>여태까지 객체 인스턴스를 만드는 두 가지 방법을 살펴보았습니다. <a href="/ko/docs/Learn/JavaScript/Objects/Basics#Object_basics">객체 리터럴을 선언하는 방법</a>과, 생성자 함수를 사용하는 방법(위를 보세요)이죠.</p> + +<p>이것들은 잘 동작하지만, 다른 방법들도 있습니다. 웹에서 정보를 찾다가 마주칠 경우를 대비해 익숙해져보는 것도 좋을 것 같습니다.</p> + +<h3 id="Object()_생성자">Object() 생성자</h3> + +<p>첫번째로, 새 객체를 만들기 위해 <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object">Object()</a></code> 생성자를 사용할 수 있습니다. 네, 최초의 object 역시 생성자를 가지고 있습니다. 빈 객체를 생성하는 함수이죠.</p> + +<ol> + <li>브라우저의 자바스크립트 콘솔에 아래 코드를 입력해보세요: + <pre class="brush: js">var person1 = new Object();</pre> + </li> + <li>이는 빈 객체를 <code>person1</code> 변수에 담습니다. 이제 이 객체에 점 표기법이나 괄호 표기법을 이용해 프로퍼티와 메소드들을 추가할 수 있습니다. 이 예제 코드를 콘솔 창에 입력해보세요. + <pre class="brush: js">person1.name = 'Chris'; +person1['age'] = 38; +person1.greeting = function() { + alert('Hi! I\'m ' + this.name + '.'); +};</pre> + </li> + <li>사전에 프로퍼티와 메소드를 정의하기 위해, <code>Object()</code> 생성자의 파라미터로 객체 리터럴을 전달할 수도 있습니다. 이 예제 코드를 콘솔 창에 입력해보세요. + <pre class="brush: js">var person1 = new Object({ + name: 'Chris', + age: 38, + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +});</pre> + </li> +</ol> + +<h3 id="create()_함수_사용">create() 함수 사용</h3> + +<p>생성자는 여러분의 코드에 규칙을 부여해줍니다. 일단 생성자를 만들어두면, 이를 이용해 원하는대로 인스턴스를 생성할 수 있고, 이 인스턴스가 어디서 유래했는지 명백합니다.</p> + +<p>하지만 몇몇 사람들은 객체 인스턴스들을 생성할 때 먼저 생성자를 만들기를 원하지 않습니다. 특히 그들이 적은 수의 객체만을 생성할 때 말이죠. 자바스크립트는 <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create()</a></code>라는 내장함수를 가지고 있어 이를 가능하게 해줍니다. 이를 이용하면, 이미 존재하는 객체를 이용해 새로운 객체를 만들 수 있습니다.</p> + +<ol> + <li>이전 섹션에서 완료한 예제를 브라우저에서 열어, 아래 코드를 콘솔창에 입력해보세요. + <pre class="brush: js">var person2 = Object.create(person1);</pre> + </li> + <li>이제 이 코드를 입력해보세요. + <pre class="brush: js">person2.name +person2.greeting()</pre> + </li> +</ol> + +<p><code>person2</code>가 <code>person1</code>을 기반으로 만들어졌습니다. 새 객체는 원 객체와 같은 프로퍼티와 메소드들을 가집니다. </p> + +<p><code>create()</code> 함수의 한 가지 단점은 익스플로러 8에서는 지원하지 않는다는 점입니다. 따라서 오래된 브라우저들까지 지원하고 싶다면 생성자를 사용하는 것이 효과적입니다.</p> + +<p>다음에 <code>create()</code> 함수의 효과에 대해 더 살펴보겠습니다.</p> + +<h2 id="요약">요약</h2> + +<p>이 글은 객체지향 이론을 요약하여 설명해줍니다. 모든 부분을 다루지는 않지만, 지금 어떤 것들을 다루고 있는지에 대한 아이디어 정도는 얻을 수 있습니다. 게다가 객체 인스턴스를 생성하는 여러가지 방법에 대해서도 알아보기 시작했습니다.</p> + +<p>다음 글에서는 자바스크립트 객체 프로토타입에 대해 탐험해보겠습니다.</p> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li> +</ul> + +<p> </p> diff --git a/files/ko/learn/javascript/objects/object_prototypes/index.html b/files/ko/learn/javascript/objects/object_prototypes/index.html new file mode 100644 index 0000000000..f2eaf03498 --- /dev/null +++ b/files/ko/learn/javascript/objects/object_prototypes/index.html @@ -0,0 +1,274 @@ +--- +title: Object prototypes +slug: Learn/JavaScript/Objects/Object_prototypes +tags: + - 객체 지향 + - 상속 + - 자바스크립트 + - 프로토타입 +translation_of: Learn/JavaScript/Objects/Object_prototypes +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">Javascript에서는 객체를 상속하기 위하여 프로토타입이라는 방식을 사용합니다. 본 문서에서는 프로토타입 체인이 동작하는 방식을 설명하고 이미 존재하는 생성자에 메소드를 추가하기 위해 프로토타입 속성을 사용하는 법을 알아봅니다.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">선수조건:</th> + <td>컴퓨터 기본지식, HTML과 CSS에 대한 기본적인 이해,자바스크립트에 어느 정도 익숙할 것 (see <a href="/ko/docs/Learn/JavaScript/First_steps">First steps</a> and <a href="/ko/docs/Learn/JavaScript/Building_blocks">Building blocks</a>). OOJS 기초 지식 (see <a href="/ko/docs/Learn/JavaScript/Objects/Basics">Introduction to objects</a>).</td> + </tr> + <tr> + <th scope="row">학습목표:</th> + <td>Javascript 객체 프로토타입을 이해하고 프로토타입 체인이 어떻게 동작하는지, 또 프로토타입 속성에 새 메소드를 추가하는 방법을 배웁니다.</td> + </tr> + </tbody> +</table> + +<h2 id="프로토타입_기반_언어"> 프로토타입 기반 언어?</h2> + +<p>JavaScript는 흔히 <strong>프로토타입 기반 언어(prototype-based language)</strong>라 불립니다.— 모든 객체들이 메소드와 속성들을 상속 받기 위한 템플릿으로써 <strong>프로토타입 객체(prototype object)</strong>를 가진다는 의미입니다. 프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메소드와 속성을 상속 받을 수도 있고 그 상위 프로토타입 객체도 마찬가지입니다. 이를 <strong>프로토타입 체인(prototype chain)</strong>이라 부르며 다른 객체에 정의된 메소드와 속성을 한 객체에서 사용할 수 있도록 하는 근간입니다.</p> + +<p>정확히 말하자면 상속되는 속성과 메소드들은 각 객체가 아니라 객체의 생성자의 <code>prototype</code>이라는 속성에 정의되어 있습니다.</p> + +<p>JavaScript에서는 객체 인스턴스와 프로토타입 간에 연결(많은 브라우저들이 생성자의 <code>prototype</code> 속성에서 파생된 <code>__proto__</code> 속성으로 객체 인스턴스에 구현하고 있습니다.)이 구성되며 이 연결을 따라 프로토타입 체인을 타고 올라가며 속성과 메소드를 탐색합니다.</p> + +<div class="note"> +<p><strong>Note:</strong> 객체의 prototype(<code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf">Object.getPrototypeOf(obj)</a></code>함수 또는 deprecated 된 <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">__proto__</a></code>속성으로 접근 가능한)과 생성자의 <code>prototype</code> 속성의 차이를 인지하는 것이 중요합니다. 전자는 개별 객체의 속성이며 후자는 생성자의 속성입니다. 이 말은 <code>Object.getPrototypeOf(new Foobar())</code>의 반환값이 <code>Foobar.prototype</code>과 동일한 객체라는 의미입니다.</p> +</div> + +<p>자세히 알기 위해 예제를 하나 봅시다.</p> + +<h2 id="프로토타입_객체_이해하기">프로토타입 객체 이해하기</h2> + +<p><code>Person()</code> 생성자를 작성했던 예제 코드로 되돌아가 봅시다. — 브라우저로 예제 코드를 불러 오시구요. 이전 페이지에서 작업했던 예제 코드를 날려버렸다면 <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">oojs-class-further-exercises.html</a> 페이지를 방문해 주세요. (<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">source code</a>도 보시구요).</p> + +<p>이 예제에서 생성자 함수를 정의했었습니다:</p> + +<pre class="brush: js">function Person(first, last, age, gender, interests) { + + // 속성과 메소드 정의 + this.first = first; + this.last = last; +//... +}</pre> + +<p>그리고 인스턴스도 하나 만들었구요:</p> + +<pre class="brush: js">var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);</pre> + +<p>Javascript 콘솔에서 "person1."을 치게 되면 브라우저는 아래처럼 해당 객체의 멤버 이름을 자동 완성 팝업으로 보여줄 것입니다:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13853/object-available-members.png" style="display: block; margin: 0 auto;"></p> + +<p>위에서 <code>person1</code>의 프로토타입 객체인 <code>Person()</code>에 정의된 멤버들 — <code>name</code>, <code>age</code>, <code>gender</code>, <code>interests</code>, <code>bio</code>, <code>greeting</code>을 볼 수 있습니다. 또한 — <code>watch</code>, <code>valueOf</code>처럼 <code>Person()</code>의 프로토타입 객체인 <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code>에 정의된 다른 멤버들도 보실 수 있습니다. 이는 프로토타입 체인이 동작한다는 증거입니다.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13891/MDN-Graphics-person-person-object-2.png" style="display: block; height: 150px; margin: 0px auto; width: 700px;"></p> + +<p>그럼 실제로는 <code>Object</code>에 정의되어 있는 메소드를 <code>person1</code>에서 호출하면 어떻게 될까요?<br> + 아래 처럼 말이죠:</p> + +<pre class="brush: js">person1.valueOf()</pre> + +<p>이 메소드는 호출된 객체의 값을 단순 반환합니다. — 직접 실행해 보세요! 이때 일어나는 일은 아래와 같습니다:</p> + +<ul> + <li>브라우저는 우선 <code>person1</code> 객체가 <code>valueOf()</code> 메소드를 가지고 있는지 체크합니다.</li> + <li>없으므로 <code>person1</code>의 프로토타입 객체(<code>Person()</code> 생성자의 프로토타입)에 <code>valueOf()</code> 메소드가 있는지 체크합니다.</li> + <li>여전히 없으므로 <code>Person()</code> 생성자의 프로토타입 객체의 프로토타입 객체(<code>Object()</code> 생성자의 프로토타입)가 <code>valueOf()</code> 메소드를 가지고 있는지 체크합니다. 여기에 있으니 호출하며 끝납니다!</li> +</ul> + +<div class="note"> +<p><strong>Note</strong>: 프로토타입 체인에서 한 객체의 메소드와 속성들이 다른 객체로 <strong>복사되는 것이 아님</strong>을 재차 언급합니다. — 위에서 보시다 시피 체인을 타고 올라가며 접근할 뿐입니다.</p> +</div> + +<div class="note"> +<p><strong>Note</strong>: 특정 객체의 프로토타입 객체에 바로 접근하는 공식적인 방법은 없습니다. — Javascript 언어 표준 스펙에서<code>[[prototype]]</code>으로 표현되는 프로토타입 객체에 대한 "링크"는 내부 속성으로 정의되어 있습니다. ({{glossary("ECMAScript")}} 참조). 하지만 많은 수의 모던 브라우저들이 <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">__proto__</a></code> (앞뒤로 언더바 2개씩) 속성을 통해 특정 객체의 프로토타입 객체에 접근할 수 있도록 구현하였습니다. 예를 들자면 <code>person1.__proto__</code> 또는 <code>person1.__proto__.__proto__</code> 코드로 체인이 어떻게 구성되어 있는지 확인해 보세요!</p> + +<p>ECMAScript 2015부터는 <code>Object.getPrototypeOf(obj)</code> 함수를 통해 객체의 프로토타입 객체에 <strong>바로 접근할 수 있게</strong> 되었습니다..</p> +</div> + +<h2 id="프로토타입_속성_상속_받은_멤버들이_정의된_곳">프로토타입 속성: 상속 받은 멤버들이 정의된 곳</h2> + +<p>그럼 상속 받은 속성과 메소드들은 어디에 정의되어 있을까요? <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code> 레퍼런스 페이지에 가시면 좌측에 수 많은 속성과 메소드들이 나열되어 있는 것을 볼 수 있습니다. — 위 스크린샷에서 person1가 상속받은 멤버들보다 훨씬 많죠. 일부는 상속 되었지만 나머지는 아닙니다. — 왜일까요?</p> + +<p>정답은 상속 받는 멤버들은 <code>prototype</code> 속성(sub-namespace라고도 하죠)에 정의되어 있기 때문입니다. — <code>Object.</code>로 시작하는게 아니라, <code>Object.prototype.</code>로 시작하는 것들이죠. <code>prototype</code> 속성도 하나의 객체이며 프로토타입 체인을 통해 상속하고자 하는 속성과 메소드를 담아두는 버킷으로 주로 사용되는 객체입니다.</p> + +<p>So <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/watch">Object.prototype.watch()</a></code>, <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf">Object.prototype.valueOf()</a></code>등등은, 생성자를 통해 새로 생성되는 인스턴스는 물론 <code>Object.prototype</code>을 상속 받는 객체라면 어떤 객체에서든지 접근할 수 있습니다.</p> + +<p><code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/is">Object.is()</a></code>, <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></code>등 <code>prototype</code> 버킷에 정의되지 않은 멤버들은 상속되지 않습니다. 이 것들은 <code>Object()</code> 생성자에서만 사용할 수 있는 멤버들이죠.</p> + +<div class="note"> +<p><strong>Note</strong>: 척 보기엔 이상합니다. — 함수에 불과한 생성자에 멤버를 정의한다니요? 함수 역시 객체의 하나입니다 — 못 미더우시면 <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Function">Function()</a></code> 생성자 레퍼런스 페이지를 확인해 보세요.</p> +</div> + +<ol> + <li>prototype 속성을 직접 확인해 볼 수 있습니다. — 예제로 돌아가서 Javascript console에 아래 코드를 타이핑 해 보세요: + <pre class="brush: js">Person.prototype</pre> + </li> + <li>출력되는 것이 별로 많지 않을 겁니다 — 아직 이 커스텀 생성자 프로토타입에 아무것도 정의하지 않았거든요! 기본적으로 생성자의 프로토타입은 비어있습니다. 이번에는 아래 코드를 실행해 봅시다: + <pre class="brush: js">Object.prototype</pre> + </li> +</ol> + +<p>위의 예제에서 확인했듯이 <code>Object</code>를 상속받은 객체에서 사용 가능한 수 많은 메소드들이 <code>Object</code>의 <code>prototype</code> 속성에 정의되어 있음을 알 수 있습니다.</p> + +<p>Javascript 전반에 걸쳐 프로토타입 체인 상속이 어떻게 구성되어 있는지 확인할 수 있습니다 — 전역 객체인 <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code>, <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Date">Date</a></code>, <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Number">Number</a></code>, <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code>의 프로토타입에 정의된 메소드와 속성들을 체크해 보세요. 이 프로토타입 객체들에는 이미 많은 수의 메소드가 정의되어 있으며 이는 아래처럼 문자열 객체를 생성 했을 때:</p> + +<pre class="brush: js">var myString = 'This is my string.';</pre> + +<p><code>myString</code> 인스턴스가 생성되는 즉시 <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/String/split">split()</a></code>, <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf">indexOf()</a></code>, <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace()</a></code>등의 문자열을 위한 유용한 메소드들을 사용할 수 있는 이유입니다.</p> + +<div class="warning"> +<p><strong>Important</strong>: <code>prototype</code> 속성은 Javascript에서 가장 헷갈리는 명칭중 하나입니다. — 보통 <code>this</code>가 현재 객체의 프로토타입 객체를 가리킬 것이라 오해하지만 그렇지 않죠. (프로토타입 객체는 <code>__proto__</code> 속성으로 접근 가능한 내장 객체인 것 기억 하시나요?). 대신에 <code>prototyp</code>e 속성은 상속 시키려는 멤버들이 정의된 객체를 가리킵니다.</p> +</div> + +<h2 id="create()_다시보기">create() 다시보기</h2> + +<p>이전에 새 인스턴스를 생성하기 위해서 <code>Object.create()</code> 메소드를 사용하는 법을 알아 보았습니다.</p> + +<ol> + <li>예를 들어서 이전 예제에서 아래 코드를 Javascript console에서 실행했었다면: + <pre class="brush: js">var person2 = Object.create(person1);</pre> + </li> + <li><code>create()</code> 메소드가 실제로 하는 일은 주어진 객체를 프로토타입 객체로 삼아 새로운 객체를 생성합니다. 여기서 person2는 person1을 프로토타입 객체로 삼습니다. 아래 코드를 실행하여 이를 확인할 수 있습니다: + <pre class="brush: js">person2.__proto__</pre> + </li> +</ol> + +<p>콘솔 상에는 <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">person1</span></font>이 출력됩니다.</p> + +<h2 id="생성자_속성">생성자 속성</h2> + +<p>모든 생성자 함수는 <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">constructor</a></code> 속성을 지닌 객체를 프로토타입 객체로 가지고 있습니다. 이 <code>constructor</code> 속성은 원본 생성자 함수 자신을 가리키고 있습니다. 다음 장에서 볼 수 있듯이 <code>Person.prototype</code> 속성(또는 위 절에서 언급된 아무 생성자 함수의 prototype 속성)에 정의된 속성들은 <code>Person()</code> 생성자로 생성된 모든 인스턴스에서 사용할 수 있습니다. 그러므로 person1과 person2에서도 constructor 속성에 접근할 수 있습니다.</p> + +<ol> + <li>예를 들어 아래 코드를 콘솔에서 실행해 보세요: + <pre class="brush: js">person1.constructor +person2.constructor</pre> + + <p>두 구문 모두 <code>Person()</code> 생성자 함수를 반환할 것입니다.</p> + + <p><code>constructor</code> 속성에 괄호를 붙이고 실행하여(인자가 필요하면 전달하구요) 새 인스턴스를 생성하는 트릭이 있습니다. 어쨌든 생성자도 함수의 일종이므로 괄호를 붙이면 실행할 수 있습니다; new 키워드를 통해 실행하면 함수를 인스턴스를 생성하기 위한 생성자로 사용할 수 있죠.</p> + </li> + <li>아래 코드를 실행해 보세요: + <pre class="brush: js">var person3 = new person1.constructor('Karen', 'Stephenson', 26, 'female', ['playing drums', 'mountain climbing']);</pre> + </li> + <li>새로 생성된 객체를 테스트 해보세요, 아래처럼요: + <pre class="brush: js">person3.name.first +person3.age +person3.bio()</pre> + </li> +</ol> + +<p>잘 동작함을 알 수 있습니다. 이런 방식을 자주 사용할 필요는 없지만 실행 도중 명시적인 생성자 함수를 예측할 수 없는 상황에서 인스턴스를 생성해야 하거나 하는 경우 유용하게 사용할 수 있는 방법입니다.</p> + +<p><code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">constructor</a></code> 속성은 여러 사용법이 있습니다. 예를 들어 인스턴스의 생성자 이름이 필요한 경우 아래의 코드로 알아낼 수 있습니다:</p> + +<pre class="brush: js">instanceName.constructor.name</pre> + +<p>아래 코드도 시험해 보세요:</p> + +<pre class="brush: js">person1.constructor.name +</pre> + +<div class="note"> +<p><strong>Note</strong>: <code>constructor.name</code> 는 변경이 가능하므로(상속이나 바인딩, 전처리, 트랜스파일러 등에 의해) 복잡한 로직에 적용하기 위해서는 <code><a href="/ko/docs/Web/JavaScript/Reference/Operators/instanceof">instanceof</a></code> 연산자를 사용하세요.</p> +</div> + +<ol> +</ol> + +<h2 id="프로토타입_수정하기">프로토타입 수정하기</h2> + +<p><code><font face="Open Sans, arial, x-locale-body, sans-serif"><span style="background-color: #ffffff;">생성자의 </span></font>prototype</code> 속성을 수정하는 법에 대해 알아봅시다(프로토타입에 메소드를 추가하면 해당 생성자로 생성된 모든 객체에서 사용 가능합니다).</p> + +<ol> + <li><a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">oojs-class-further-exercises.html</a> 예제로 돌아가서 <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">source code</a>를 다운 받으세요. 기존 코드에 아래 샘플 코드를 추가하여 <code>prototype</code> 속성에 새 메소드를 추가하세요: + + <pre class="brush: js">Person.prototype.farewell = function() { + alert(this.name.first + ' has left the building. Bye for now!'); +};</pre> + </li> + <li>저장한 코드를 브라우저로 실행하고 콘솔에서 아래 코드를 실행해 보세요. + <pre class="brush: js">person1.farewell();</pre> + </li> +</ol> + +<p>생성자에서 지정했던 person의 name이 alert 창으로 출력되는 것을 확인할 수 있습니다. 매우 유용한 기능이지만 중요한 점은 prototype에 새 메소드를 추가하는 순간 동일한 생성자로 생성된 모든 객체에서 추가된 메소드를 바로 사용할 수 있다는 점입니다.</p> + +<p>잠시 정리해 봅시다. 예제에서는 생성자를 정의하고, 객체를 생성하였으며, 그 이후에 프로토타입에 새 메소드를 추가하였습니다:</p> + +<pre class="brush: js">function Person(first, last, age, gender, interests) { + + // 속성과 메소드 정의 + +} + +var person1 = new Person('Tammi', 'Smith', 32, 'neutral', ['music', 'skiing', 'kickboxing']); + +Person.prototype.farewell = function() { + alert(this.name.first + ' has left the building. Bye for now!'); +};</pre> + +<p>그런데도 person1에서 바로 farewell() 메소드를 사용할 수 있습니다 - 자동으로 업데이트 되기 때문이죠(역주:원문은 이런 뉘앙스입니다만 실제로는 프로토타입 객체는 모든 인스턴스에서 공유하기 때문에 정의하는 즉시 별도의 갱신 과정 없이 접근이 가능합니다).</p> + +<div class="note"> +<p><strong>Note</strong>: 코드가 잘 동작하지 않는다면 <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-prototype.html">oojs-class-prototype.html</a> 코드를 참조하세요 (<a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-prototype.html">running live</a> 페이지도 보시구요).</p> +</div> + +<p>prototype에 속성을 정의하는 경우는 별로 본 적이 없을겁니다. 왜냐면 별로 좋은 방법이 아니거든요. 속성을 추가할 때 아래와 같이 할 수 있습니다:</p> + +<pre class="brush: js">Person.prototype.fullName = 'Bob Smith';</pre> + +<p>사람들이 항상 밥 스미스로 부르지 않을 수 있으니 별로 좋은 방법 같지는 않아 보입니다. <code>fullname</code>을 <code>name.first</code>와 <code>name.last</code>로 나누어 보죠:</p> + +<pre class="brush: js">Person.prototype.fullName = this.name.first + ' ' + this.name.last;</pre> + +<p>이 경우 <code>this</code>는 함수 범위가 아닌 전역 범위를 가리키므로 코드가 의도대로 동작하지 않습니다. 이대로 실행해도 <code>undefined undefined</code>만 볼 수 있죠. 윗 절에서 프로토타입에 정의한 메소드 내에서는 정상적으로 동작하는데 이는 코드가 함수 범위 내에 있으며 객체의 멤버 함수로써 동작하기에 객체 범위로 전환되었기 때문입니다. 따라서 프로토타입에 상수(한 번 할당하면 변하지 않는 값)를 정의하는 것은 가능하지만 일반적으로 생성자에서 정의하는 것이 낫습니다.</p> + +<p>사실 일반적인 방식으로는 속성은 생성자에서, 메소드는 프로토타입에서 정의합니다. 생성자에는 속성에 대한 정의만 있으며 메소드는 별도의 블럭으로 구분할 수 있으니 코드를 읽기가 훨씬 쉬워집니다. 아래처럼요:</p> + +<pre class="brush: js">// 생성자에서 속성 정의 + +function Test(a, b, c, d) { + // 속성 정의 +} + +// 첫 메소드 정의 + +Test.prototype.x = function() { ... }; + +// 두번째 메소드 정의 + +Test.prototype.y = function() { ... }; + +// 그 외.</pre> + +<p>이런 패턴은 Piotr Zalewa의 <a href="https://github.com/zalun/school-plan-app/blob/master/stage9/js/index.js">school plan app</a> 예제 코드에서 볼 수 있습니다.</p> + +<h2 id="요약">요약</h2> + +<p>이 글에서는 객체 프로토타입에 대한 설명과 프로토타입 체인을 통해 다른 객체를 상속하는 방법, 프로토타입 속성과 생성자에 새 메소드를 추가하는 방법과 그와 관련된 지식을 다루고 있습니다.</p> + +<p>다음 글에서는 직접 만든 객체간의 상속을 구현하는 방법에 대해 알아봅시다.</p> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}</p> + +<p> </p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li> +</ul> + +<p> </p> |