aboutsummaryrefslogtreecommitdiff
path: root/files/zh-tw/learn/javascript/objects
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:43:23 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:43:23 -0500
commit218934fa2ed1c702a6d3923d2aa2cc6b43c48684 (patch)
treea9ef8ac1e1b8fe4207b6d64d3841bfb8990b6fd0 /files/zh-tw/learn/javascript/objects
parent074785cea106179cb3305637055ab0a009ca74f2 (diff)
downloadtranslated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.gz
translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.bz2
translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.zip
initial commit
Diffstat (limited to 'files/zh-tw/learn/javascript/objects')
-rw-r--r--files/zh-tw/learn/javascript/objects/adding_bouncing_balls_features/index.html184
-rw-r--r--files/zh-tw/learn/javascript/objects/basics/index.html243
-rw-r--r--files/zh-tw/learn/javascript/objects/index.html42
-rw-r--r--files/zh-tw/learn/javascript/objects/inheritance/index.html210
-rw-r--r--files/zh-tw/learn/javascript/objects/json/index.html325
-rw-r--r--files/zh-tw/learn/javascript/objects/object-oriented_js/index.html277
-rw-r--r--files/zh-tw/learn/javascript/objects/object_building_practice/index.html283
-rw-r--r--files/zh-tw/learn/javascript/objects/object_prototypes/index.html236
8 files changed, 1800 insertions, 0 deletions
diff --git a/files/zh-tw/learn/javascript/objects/adding_bouncing_balls_features/index.html b/files/zh-tw/learn/javascript/objects/adding_bouncing_balls_features/index.html
new file mode 100644
index 0000000000..33cb338c8d
--- /dev/null
+++ b/files/zh-tw/learn/javascript/objects/adding_bouncing_balls_features/index.html
@@ -0,0 +1,184 @@
+---
+title: 為彈跳彩球添增其他功能
+slug: Learn/JavaScript/Objects/Adding_bouncing_balls_features
+translation_of: Learn/JavaScript/Objects/Adding_bouncing_balls_features
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}</div>
+
+<p class="summary">在本文中,你將繼續使用前一篇文章的彈跳彩球展示程式,另外加入幾項有趣的新功能。</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">必備條件:</th>
+ <td>在開始本文所提的實作之前,應先看過先前的相關文章。</td>
+ </tr>
+ <tr>
+ <th scope="row">要點:</th>
+ <td>測試 JavaScript 物件與 OO 架構的完整性。</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="開始">開始</h2>
+
+<p>在開始之前,請先複製先前文章所提供的 <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/index-finished.html">index-finished.html</a>、<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/style.css">style.css</a>、<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/main-finished.js">main-finished.js</a> 等檔案,儲存於本端磁碟的新資料夾中。</p>
+
+<div class="note">
+<p><strong>注意:</strong>你也可透過如 <a class="external external-icon" href="http://jsbin.com/">JSBin</a> 或 <a class="external external-icon" href="https://thimble.mozilla.org/">Thimble</a> 等網站進行此一實作。你可將 HTML、CSS、JavaScript 貼入相關線上編輯器之一。如果你所用的線上編輯器並未提供獨立的 JavaScript/CSS 面板,則可將之放入 HTML 頁面內的行內 <code>&lt;script&gt;</code>/<code>&lt;style&gt;</code> 元素中。</p>
+</div>
+
+<h2 id="專案簡介">專案簡介</h2>
+
+<p>彈跳彩球很有趣,但接著我們要加入使用者可控制的「邪惡圈」,在碰到彩球之後隨即吃掉彩球,添加更多互動性。也希望透過邪惡圈與彩球所繼承的通用 <code>Shape()</code> 物件,測試你的物件技術。最後還要加上計分功能,顯示尚未吃掉的彩球數量。</p>
+
+<p>下方擷圖則讓你了解最終成品的樣子:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13875/bouncing-evil-circle.png" style="display: block; margin: 0 auto;"></p>
+
+<ul>
+</ul>
+
+<p>可先參考<a href="http://mdn.github.io/learning-area/javascript/oojs/assessment/">完成範例</a>讓心裡有個底 (別偷看原始碼啊!)</p>
+
+<h2 id="須進行的步驟">須進行的步驟</h2>
+
+<p>下列段落將逐步說明。</p>
+
+<h3 id="建立新物件">建立新物件</h3>
+
+<p>首先將現有的 <code>Ball()</code> 建構子變更為 <code>Shape()</code> 建構子,以及新的 <code>Ball()</code> 建構子:</p>
+
+<ol>
+ <li><code>Shape()</code> 建構子對 <code>x</code>、<code>y</code>、<code>velX</code>、<code>velY</code> 屬性的定義方式,就如同 <code>Ball()</code> 建構子所用的方式。</li>
+ <li>另須定義新的 <code>exists</code> 屬性,用以追蹤球體是否存在於程式之中 (也就是尚未遭邪惡圈所吃掉)。此屬性必為布林值 (Boolean),初始值為 <code>true</code>。</li>
+ <li><code>Ball()</code> 建構子應從 <code>Shape()</code> 建構子繼承 <code>x</code>、<code>y</code>、<code>velX</code>、<code>velY</code>、<code>exists</code> 等屬性。另必須將這些屬性定義為參數以利呼叫之。</li>
+ <li>必須定義 <code>color</code> 與 <code>size</code> 屬性各 1 組,且由於兩者均來自於原始的 <code>Ball()</code> 建構子之中,所以剛開始的隨機值亦須相同。</li>
+ <li>記得應正確設定 <code>Ball()</code> 建構子的 <code>prototype</code> 與 <code>constructor</code>。</li>
+</ol>
+
+<p>彩球的 <code>draw()</code>、<code>update()</code>、<code>collisionDetect()</code> 函式定義,均與之前完全相同。</p>
+
+<p>到此為止可重新載入程式碼,搭配重新設計的物件也應該運作無誤。</p>
+
+<h3 id="定義_EvilCircle()">定義 EvilCircle()</h3>
+
+<p>再來見見這個壞蛋 — <code>EvilCircle()</code>!這個遊戲要加入 1 個會吃球的邪惡圈,而且要透過繼承自 <code>Shape()</code> 的建構子來定義這個邪惡圈。你可能也想添增另個讓第二個玩家控制的圈圈,或許多加幾個由電腦控制的邪惡圈。當然,光一個邪惡圈並無法統治世界,但可為此遊戲增添不少樂趣。</p>
+
+<p><code>EvilCircle()</code> 建構子應繼承 <code>Shape()</code> 的 <code>x、</code><code>y、</code><code>exists。</code></p>
+
+<p>亦可定義自有的屬性如下:</p>
+
+<ul>
+ <li><code>color</code> — <code>'white'</code></li>
+ <li><code>size</code> — <code>10</code></li>
+ <li><code>velX</code> — <code>20</code></li>
+ <li><code>velY</code> — <code>20</code></li>
+</ul>
+
+<p>再次提醒,請記得要將所繼承的屬性在建構子中定義為參數,並應正確設定 <code>prototype</code> 與 <code>constructor</code> 屬性。</p>
+
+<h3 id="定義_EvilCircle()_的函式">定義 EvilCircle() 的函式</h3>
+
+<p><code>EvilCircle()</code> 應具備 4 個函式,如下:</p>
+
+<h4 id="draw()"><code>draw()</code></h4>
+
+<p>此函式的功能與 <code>Ball()</code> 的 <code>draw()</code> 函式相同,就是在 canvas 上繪製物件實體;且運作的方式也類似,所以你可以複製 <code>Ball.prototype.draw</code> 定義來開始。接著要完成下列改變:</p>
+
+<ul>
+ <li>我們要空心的邪惡圈,但不只是單純實心黑線畫成的圓而已 (要有邊框)。只要將 <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle">fillStyle</a></code> 與 <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/fill">fill()</a></code> 更新成 <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle">strokeStyle</a></code> 與 <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/stroke">stroke()</a></code> 即可辦到。</li>
+ <li>還可以讓邊框更粗一點,有助你更容易看到邪惡圈。只要在 <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/beginPath">beginPath()</a></code> 呼叫之後的某個地方設定 <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth">lineWidth</a></code> 的值 (「3」就可以) 即可。</li>
+</ul>
+
+<h4 id="checkBounds()"><code>checkBounds()</code></h4>
+
+<p>此函式功能就與 <code>Ball()</code> 的 <code>update()</code> 函式第一部分相同,負責邪惡圈是否跳出螢幕邊界之外並適時阻止。同樣的,你還是可以複製 <code>Ball.prototype.update</code> 定義來用,但須更改下列:</p>
+
+<ul>
+ <li>Get rid of the last two lines — we don't want to automatically update the evil circle's position on every frame, because we will be moving it in some other way, as you'll see below.</li>
+ <li>Inside the <code>if()</code> statements, if the tests return true we don't want to update <code>velX</code>/<code>velY</code>; we want to instead change the value of <code>x</code>/<code>y</code> so the evil circle is bounced back onto the screen slightly. Adding or subtracting (as appropriate) the evil circle's <code>size</code> property would make sense.</li>
+</ul>
+
+<h4 id="setControls()"><code>setControls()</code></h4>
+
+<p>This method will add an <code>onkeydown</code> event listener to the <code>window</code> object so that when certain keyboard keys are pressed, we can move the evil circle around. The following code block should be put inside the method definition:</p>
+
+<pre class="brush: js">var _this = this;
+window.onkeydown = function(e) {
+ if(e.keyCode === 65) {
+ _this.x -= _this.velX;
+ } else if(e.keyCode === 68) {
+ _this.x += _this.velX;
+ } else if(e.keyCode === 87) {
+ _this.y -= _this.velY;
+ } else if(e.keyCode === 83) {
+ _this.y += _this.velY;
+ }
+ }</pre>
+
+<p>So when a key is pressed, the event object's <a href="/en-US/docs/Web/API/KeyboardEvent/keyCode">keyCode</a> property is consulted to see which key is pressed. If it is one of the four represented by the specified keycodes, then the evil circle will move left/right/up/down.</p>
+
+<ul>
+ <li>For a bonus point, let us know which keys the specified keycodes map to.</li>
+ <li>For another bonus point, can you tell us why we've had to set <code>var _this = this;</code> in the position it is in? It is something to do with function scope.</li>
+</ul>
+
+<h4 id="collisionDetect()"><code>collisionDetect()</code></h4>
+
+<p>This method will act in a very similar way to <code>Ball()</code>'s <code>collisionDetect()</code> method, so you can use a copy of that as the basis of this new method. But there are a couple of differences:</p>
+
+<ul>
+ <li>In the outer <code>if</code> statement, you no longer need to check whether the current ball in the iteration is the same as the ball that is doing the checking — because it is not longer a ball, it is the evil circle! Instead, you need to do a test to see if the ball being checked exists (with which property could you do this with?). If it doesn't exist, it has already been eaten by the evil circle, so there is no need to check it again.</li>
+ <li>In the inner <code>if</code> statement, you no longer want to make the objects change color when a collision is detected — instead, you want to set any balls that collide with the evil circle to not exist any more (again, how do you think you'd do that?).</li>
+</ul>
+
+<h3 id="Bringing_the_evil_circle_into_the_program">Bringing the evil circle into the program</h3>
+
+<p>Now we've defined the evil circle, we need to actually make it appear in our scene. To do this, you need to make some changes to the <code>loop()</code> function.</p>
+
+<ul>
+ <li>First of all, create a new evil circle object instance, then call its <code>setControls()</code> method. You only need to do these two things once, not on every iteration of the loop.</li>
+ <li>At the point where you loop through every ball and call the <code>draw()</code>, <code>update()</code>, and <code>collisionDetect()</code> functions for each one, make it so that these functions are only called if the current ball exists.</li>
+ <li>Call the evil ball instance's <code>draw()</code>, <code>checkBounds()</code>, and <code>collisionDetect()</code> methods on every iteration of the loop.</li>
+</ul>
+
+<h3 id="Implementing_the_score_counter">Implementing the score counter</h3>
+
+<p>To implement the score counter, follow the following steps:</p>
+
+<ol>
+ <li>In your HTML file, add a {{HTMLElement("p")}} element just below the {{HTMLElement("h1")}} element containing the text "Ball count: ".</li>
+ <li>In your CSS file, add the following rule at the bottom:
+ <pre class="brush: css">p {
+ position: absolute;
+ margin: 0;
+ top: 35px;
+ right: 5px;
+ color: #aaa;
+}</pre>
+ </li>
+ <li>In your JavaScript, make the following updates:
+ <ul>
+ <li>Create a variable that stores a reference to the paragraph.</li>
+ <li>Keep a count of the number of balls on screen in some way.</li>
+ <li>Increment the count and display the updated number of balls each time a ball is added to the scene.</li>
+ <li>Decrement the count and display the updated number of balls each time the evil circle eats a ball (causes it not to exist).</li>
+ </ul>
+ </li>
+</ol>
+
+<h2 id="Hints_and_tips">Hints and tips</h2>
+
+<ul>
+ <li>This assessment is quite challenging. Take each step slowly and carefully.</li>
+ <li>It might be an idea to keep a separate copy of the demo after you get each stage working, so you can refer back to it if you find yourself in trouble later on.</li>
+</ul>
+
+<h2 id="交作業">交作業</h2>
+
+<p>如果你是在某個課堂上操作這份作業,那麼請將成品交給您的老師 / 助教;如果您是自學者,在我們的<a href="https://discourse.mozilla-community.org/t/learning-web-development-marking-guides-and-questions/16294">專屬討論區</a>或 <a href="https://wiki.mozilla.org/IRC">Mozilla IRC </a>上的 <a href="irc://irc.mozilla.org/mdn">#mdn</a> 頻道都可以很輕鬆地找到人給予指教。記得先認真做一下習題,要怎麼收獲先那麼栽呀!</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}</p>
diff --git a/files/zh-tw/learn/javascript/objects/basics/index.html b/files/zh-tw/learn/javascript/objects/basics/index.html
new file mode 100644
index 0000000000..3b70536656
--- /dev/null
+++ b/files/zh-tw/learn/javascript/objects/basics/index.html
@@ -0,0 +1,243 @@
+---
+title: JavaScript 物件基礎概念
+slug: Learn/JavaScript/Objects/Basics
+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 物件語法,複習了某些先前提過的 JavaScript 功能,也再次強調你現正使用中的許多功能其實就是物件。</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">必要條件:</th>
+ <td>基本的電腦素養、對 HTML 與 CSS 已有初步認識、熟悉 JavaScript 基本概念 (參閱〈<a href="/zh-TW/docs/Learn/JavaScript/First_steps">First steps</a>〉與〈<a href="/zh-TW/docs/Learn/JavaScript/Building_blocks">Building blocks</a>〉)。</td>
+ </tr>
+ <tr>
+ <th scope="row">主旨:</th>
+ <td>了解「物件導向 (OO)」程式設計背後的基礎理論、其與 JavaScript (多屬於物件) 之間的關係、該如何使用 JavaScript 物件進行開發。</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="物件基礎概念">物件基礎概念</h2>
+
+<p>物件是一批相關的數據以及/或者功能(通常包含了幾個變數及函式 — 當它們包含在物件中時被稱做「屬性」(properties)或「函式」(methods)),讓我們用一個範例來看看物件的長相。</p>
+
+<p>在開始之前,請先複製一份 <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a> 檔案到你自己的本端硬碟中。此檔案內容物不多,就 1 組 {{HTMLElement("script")}} 元素可寫入我們的原始碼;在繪製頁面時,1 組元素可輸入簡易指令;幾個變數定義;1 組函式可針對輸入至 input 的程式碼,將之輸出到 {{HTMLElement("p")}} 元素。我們將透過此檔案說明基礎的物件語法。</p>
+
+<p>JavaScript 內的大多數東西,均是透過定義並初始設定變數來建立物件。</p>
+
+<p>現在, 請在自己的 oojs.html 檔案中、JavaScript 程式碼中加入下列程式碼,接著儲存並重新整理:</p>
+
+<pre class="brush: js">var person = {};</pre>
+
+<p>然後在瀏覽器中開啟 oojs.html, 再打開瀏覽器的開發者工具, 在 JavaScript 的控制台下, 輸入<code>person</code>, 並按下 Enter 鈕,就會得到下列結果:</p>
+
+<pre class="brush: js">[object Object]</pre>
+
+<p>恭喜, 你已經建立了自己的第一個物件。但這仍是空的物件,所以能做的事不多。接下來, 再如下所示, 幫 person 物件更新內容:</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>改完後同樣儲存 oojs.html、重新整理瀏覽器之後,再到控制台輸入 person, 將會看到新的結果:</p>
+
+<pre class="brush: js">person.name[0]
+person.age
+person.interests[1]
+person.bio()
+person.greeting()</pre>
+
+<p>現在你的物件裡面已經有了某些資料與功能,而且能透過某些簡易語法存取之。</p>
+
+<div class="note">
+<p><strong>注意:</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>)。你最容易犯下的錯誤是在物件中的最後一個成員 (member)末端加上逗號,如此就會造成錯誤。</p>
+</div>
+
+<p>目前為止發生了什麼事呢?現在這個物件是由多個成員所構成,各個成員均有 1 個名稱 (如上述的 <code>name</code> 與 <code>age</code>) 以及 1 組數值 (如 <code>['Bob', 'Smith']</code> 與 <code>32</code>)。由名稱與數值構成的組合均以逗號區隔,而名稱與數值之間則以冒號隔開。語法應如下所示:</p>
+
+<pre class="brush: js">var objectName = {
+ member1Name : member1Value,
+ member2Name : member2Value,
+ member3Name : member3Value
+}</pre>
+
+<p>物件成員的數值可能是任何東西,像上述的範例物件就有 1 組字串、1 組數字、2 個陣列、2 組函式。前 4 組項目均為資料項目,可說是該物件的<strong>屬性</strong>。最後 2 組項目的功能則是用以指定物件對該筆資料所應進行的作業,可說是物件的<strong>函式 (Method)</strong>。</p>
+
+<p>類似這種物件即稱為「<strong>實字物件 (Object literal)</strong>」,按照字面上的意思寫出物件內容;與其相對的就是根據「類別」做出的物件實體。我們稍後會再說明。</p>
+
+<p>在傳送一系列結構化的相關資料項目時 (例如傳送請求至伺服器並置入資料庫中),就常常會透過實字物件的方式建立物件。另與「分別傳送多個項目」相較,送出單一物件當然效率更高,且當你想根據名稱找出各個項目時,更易於搭配陣列。</p>
+
+<h2 id="點記法_(Dot_notation)">點記法 (Dot notation)</h2>
+
+<p>你可透過點記法 (Dot notation) 存取物件的屬性與函式。物件名稱 (這裡是 person) 作為<strong>命名空間 (Namespace)</strong> —為了能存取物件所<strong>封裝</strong>的所有東西,這也是必須首先輸入的項目。接著你寫一個「點」以及你所想存取的項目,可能是簡單屬性的名稱、陣列屬性的項目,又或是針對物件函式之一的呼叫。舉例來說:</p>
+
+<pre class="brush: js">person.age
+person.interests[1]
+person.bio()</pre>
+
+<h3 id="子命名空間">子命名空間</h3>
+
+<p>甚至可以將物件成員的數值轉為另一個物件。舉例來說,你可將名稱成員從</p>
+
+<pre class="brush: js">name : ['Bob', 'Smith'],</pre>
+
+<p>改變為</p>
+
+<pre class="brush: js">name : {
+ first : 'Bob',
+ last : 'Smith'
+},</pre>
+
+<p>我們這裡以極高效率建立了子命名空間。看起來複雜但其實不然。若要存取這些項目,你只要透過另一個點,將 onto the end 的額外步驟串連起來即可。如下所示:</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="括弧記法_(Bracket_notation)">括弧記法 (Bracket notation)</h2>
+
+<p>括弧記法 (Bracket notation) 是另個存取物件屬性的方法。之前的:</p>
+
+<pre class="brush: js">person.age
+person.name.first</pre>
+
+<p>可寫成</p>
+
+<pre class="brush: js">person['age']
+person['name']['first']</pre>
+
+<p>這很像在陣列中存取項目的方法。其實基本上是一樣的東西 ─ 但前者是透過指數  (index number) 選擇項目;括弧記法則是透過各成員數值相關的名稱來選擇項目。因此物件有時亦稱作<strong>「相聯陣列 (Associative array)」</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>設定成員不只是更新現有屬性與函式的數值,也可以建立全新的成員,如下:</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>此外,括弧記法不僅可動態設定成員數值,亦可設定成員名稱。假設使用者可在自己的人事資料中儲存自訂的數值類型,例如鍵入成員名稱與數值為 2 組文字輸入項,就會類似:</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」是幹嘛用的。「this」是指目前寫入程式碼的物件;所以此範例的 <code>this </code>就等於 <code>person</code>。那又為何不寫 <code>person</code> 就好呢?如同你在〈<a href="/zh-TW/docs/Learn/JavaScript/Objects/Object-oriented_JS">初學者的物件導向 JavaScript</a>〉一文中所看過的,當我們開始設定建構子等東西時,有用的「<code>this</code>」就可在成員內文改變時 (例如 2 個不同 <code>person</code> 物件實例可能具備不同的名稱,但打招呼時仍要使用自己的名稱),確保仍使用了正確的值。</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>所以當你使用字串函式如下:</p>
+
+<pre class="brush: js">myString.split(',');</pre>
+
+<p>你就是在使用 <code><a href="/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> 類別實例可用的方法。每次只要你在程式碼中建立字串,該字串就會自動建立成為 <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="/zh-TW/docs/Web/API/Document">Document</a></code> 類別實例上的函式。當載入網頁時,就會建立 <code>Document</code> 的實例,亦所謂的 <code>document</code>,將呈現整個網頁的架構、內容,以及其他功能 (如網址)。同樣的,這代表其上已有多個常見的函式\屬性。</p>
+
+<p>同理可證,目前你在使用的許多物件\API (如 <code><a href="/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code><code>、<a href="/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math">Math</a></code> 等) 也都是類似情形。</p>
+
+<p>另該注意的是,內建的物件\API 不見得會自動建立物件實例。像以 <a href="/zh-TW/docs/Web/API/Notifications_API">Notifications API</a>  (它可以幫助你使用現代瀏覽器向使用者發送通知 ) 為例,就需要你針對想要觸發的通知,使用建構子逐一建立新的物件實例。試著將下列程式碼丟進你的 JavaScript 主控台:</p>
+
+<pre class="brush: js">var myNotification = new Notification('Hello!');</pre>
+
+<p>我們會在後續文章中說明建構子 (Constructor)。</p>
+
+<div class="note">
+<p><strong>注意:</strong>可思考一下物件「訊息傳遞」的溝通方式。當某個物件需要其他物件執行其他作業時,往往會透過其函式之一傳送訊息給其他物件並等待回應。這也是我們所謂的回傳值。</p>
+</div>
+
+<h2 id="摘要">摘要</h2>
+
+<p>恭喜你已經快讀完我們第一篇 JS 物件的文章了。你應該已經知道該如何使用 JavaScript 中的物件,並建立自己的簡單物件了。你也應該了解物件在儲存相關資料的好用之處。如果你將 <code>person</code> 物件中的所有屬性與函式,當做個別的變數與函式並試著追蹤,肯定吃力不討好;且其他具備相同名稱的變數與函式也可能發生問題。「物件」讓我們能在其封包中安全的與資訊相互區隔。</p>
+
+<p>下一篇文章將說明「物件導向程式設計 (OOP)」理論,並了解相關技術是如何用於 JavaScript 之中。</p>
+
+<p>{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}</p>
diff --git a/files/zh-tw/learn/javascript/objects/index.html b/files/zh-tw/learn/javascript/objects/index.html
new file mode 100644
index 0000000000..aa4b296a95
--- /dev/null
+++ b/files/zh-tw/learn/javascript/objects/index.html
@@ -0,0 +1,42 @@
+---
+title: JavaScript 物件介紹
+slug: Learn/JavaScript/Objects
+translation_of: Learn/JavaScript/Objects
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">在 JavaScript 裡面,從諸如字串與陣列的核心功能、到以 JavaScript 建構的瀏覽器 API,大部分的東西都可算是「物件 (Object)」。你甚至可建立自己的物件,將相關函式與變數封裝 (Encapsulate) 為有效封包,並可作為多樣的資料容器 (Data container)。如果你想更精進既有的程式語言知識,就必須了解 JavaScript 的「物件導向 (Object-Oriented;OO)」本質。為此,我們設計了相關文章來協助你更進一步。本文將先說明物件理論和語法的細節,再引導你建立自己的物件。</p>
+
+<h2 id="必備條件">必備條件</h2>
+
+<p>在開始閱讀本文之前,你應該已經對 HTML 與 CSS 有一定程度的認識。建議你先看過〈<a href="https://developer.mozilla.org/zh-TW/docs/Web/Guide/HTML/Introduction">HTML 介紹</a>〉以及〈<a href="https://developer.mozilla.org/zh-TW/docs/Learn/CSS/Introduction_to_CSS">CSS 介紹</a>〉,再開始了解 JavaScript。</p>
+
+<p>你也應該已經初步了解過 JavaScript 基本概念,再進一步閱讀 JavaScript 物件。所以另請先看過〈<a href="/zh-TW/docs/Learn/JavaScript/First_steps">JavaScript 的第一步</a>〉與〈<a href="/zh-TW/docs/Learn/JavaScript/Building_blocks">JavaScript 基礎要件</a>〉。</p>
+
+<div class="note">
+<p><strong>注意:</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="/zh-TW/docs/Learn/JavaScript/Objects/Basics">物件基本概念</a></dt>
+ <dd>第一篇主述 JavaScript 物件。我們將說明基本的 JavaScript 物件語法,並重新講解某些先前已經說過的 JavaScript 功能,也會再提及許多物件是你現正使用中的功能。</dd>
+ <dt><a href="/zh-TW/docs/Learn/JavaScript/Objects/Object-oriented_JS">適合初學者的 OO JaveScript</a></dt>
+ <dd>說明過基本概念之後,就會將重點放在物件導向的 JavaScript (OOJS) 本質上。本文會先介紹 OO 程式設計的基礎理論,再說明 JavaScript 是如何透過建構子 (Constructor) 函式模擬物件類別並建立物件實體 (Instance)。</dd>
+ <dt><a href="/zh-TW/docs/Learn/JavaScript/Objects/Object_prototypes">物件原型</a></dt>
+ <dd>原型 (Prototype) 是 JavaScript 物件用以互相繼承功能的機制,且其與典型 OO 程式語言中的繼承機制有所不同。本文將探討其中相異性、說明原型鏈的運作方式,並透過原型屬性將函式新增至現有建構子。</dd>
+ <dt><a href="/zh-TW/docs/Learn/JavaScript/Objects/Inheritance">JavaScript 中的繼承</a></dt>
+ <dd>再說明了 JavaScript 大多數的 OO 特性之後,將說明應如何建立「子」物件類別 (建構子) 並繼承其「母」類別的功能。此外,我們將針對你可能使用 OOJS 的時機提供建言。</dd>
+ <dt><a href="/zh-TW/docs/Learn/JavaScript/Objects/JSON">利用 JSON 資料</a></dt>
+ <dd>JavaScript Object Notation (JSON) 為標準格式,用以將「結構化資料 (Structured data)」呈現為 JavaScript 物件,並常用於網站之間呈現\傳輸資料 (如從伺服器傳送資料到用戶端,以於網頁上顯示內容)。你一定會常接觸到類似情形,所以本文將提供用 JavaScript 搭配 JSON 開發時的所有資訊,包含在 JSON 物件中存取資料項目,以及撰寫你自己的 JSON。</dd>
+ <dt><a href="/zh-TW/docs/Learn/JavaScript/Objects/Object_building_practice">物件打造實例</a></dt>
+ <dd>前幾篇文章帶領你看過基本的 JavaScript 物件理論和語法細節,幫你打下厚實的基礎。而本文要讓你實際操作,透過更多實例自訂出 JavaScript 物件,讓你享受多采多姿的學習過程 (讓你寫出彩色的跳跳球喔)。</dd>
+</dl>
+
+<h2 id="評量">評量</h2>
+
+<dl>
+ <dt><a href="/zh-TW/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">為彩色跳跳球展示範例新增其他功能</a></dt>
+ <dd>在此評量中,你已經先寫出了跳跳球範例。接著要讓你新增其他有趣的功能。</dd>
+</dl>
diff --git a/files/zh-tw/learn/javascript/objects/inheritance/index.html b/files/zh-tw/learn/javascript/objects/inheritance/index.html
new file mode 100644
index 0000000000..f9db84dae8
--- /dev/null
+++ b/files/zh-tw/learn/javascript/objects/inheritance/index.html
@@ -0,0 +1,210 @@
+---
+title: 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 基本概念、熟悉 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>了解應如何建構 JavaScript 中的繼承。</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="原型繼承">原型繼承</h2>
+
+<p>目前為止,我們看過幾個繼承的實作範例:原型鍊的運作方式,以及繼承的成員如何形成原型鍊。但這些大部分都與內建的瀏覽器函式有關。那我們又該如何在 JavaScript 建立物件且由其他物件繼承而來呢?</p>
+
+<p>如稍早的系列文章中所述,某些人認為 JavaScript 並非真正的物件導向 (OO) 語言。在「典型 OO」中,你必須定義特定的類別物件,才能定義哪些類別所要繼承的類別 (可參閱〈<a href="http://www.tutorialspoint.com/cplusplus/cpp_inheritance.htm">C++ inheritance</a>〉了解簡易範例)。JavaScript 則使用不同的系統 —「繼承」的物件並不會一併複製功能過來,而是透過原型鍊連接其所繼承的功能,亦即所謂的原型繼承 (<strong>Prototypal inheritance</strong>)。</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">實際執行</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>這些函式均已定義於建構子的原型之上,例如:</p>
+
+<pre class="brush: js">Person.prototype.greeting = function() {
+ alert('Hi! I\'m ' + this.name.first + '.');
+};</pre>
+
+<p>假設要建立一個像前面 OO 定義中說過的 <code>Teacher</code> 類別,且除了繼承 <code>Person</code> 的所有成員,還要包含:</p>
+
+<ol>
+ <li>新的 <code>subject</code> 屬性,可包含老師所傳授的科目。</li>
+ <li>更新過的 <code>greeting()</code> 函式,要比標準的 <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="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call">call()</a></code> 函式。此函式基本上可讓你呼叫在其他地方定義的函數,而非目前內文 (context) 中定義的函式。當執行函式時,第一個參數用來指定你要使用 <code>this</code> 值,其他參數則指定應該傳送到該函式的參數。</p>
+
+<div class="note">
+<p><strong>注意:</strong>我們此範例中建立新的物件實例時,會指定所要繼承的屬性。但必須注意的是,即使實例不需將屬性指定為參數,你還是必須在建構子中將屬性指定為參數  (在建立物件時,你可能獲得設定為隨意值的屬性)。</p>
+</div>
+
+<p>所以這裡可在 <code>Teacher()</code> 建構子函式之內有效執行 <code>Person() </code>建構子函式 (如上述),藉以在 <code>Teacher()</code> 之內定義相同的屬性,但使用的是傳送到 <code>Teacher()</code> 的屬性值,而非 <code>Person()</code> 的屬性值 (我們將 <code>this</code> 值設為簡單的「<code>this」並</code>傳送到 <code>call()</code>,代表這個 <code>this</code> 是 <code>Teacher()</code> 的函式)。</p>
+
+<p>建構子的最後一行則定義了新的 <code>subject</code> 屬性,代表只有老師具備,一般人不會有。</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>
+
+<h2 id="設定_Teacher()_的原型與建構子參考">設定 Teacher() 的原型與建構子參考</h2>
+
+<p>到目前為止發現一個問題:我們定義了新的建構子,但預設只有 1 個空白的 <code>prototype</code> 屬性。接著要讓 <code>Teacher()</code> 繼承 <code>Person()</code> 原型中所定義的函式,該怎麼做呢?</p>
+
+<ol>
+ <li>繼續在現有程式碼下方加入:
+ <pre class="brush: js">Teacher.prototype = Object.create(Person.prototype);</pre>
+ 這裡再次用好朋友 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create()</a></code> 解救。我們透過 <code>create()</code> 並搭配等同於 <code>Person.prototype</code> 的原型,建立新的 <code>prototype</code> 屬性值 (它本身就是物件,包含屬性與函式) ,並將之設定為 <code>Teacher.prototype</code> <code>的值。也就是說</code> <code>Teacher.prototype</code> 現在會繼承 <code>Person.prototype</code> 上的所有可用函式。</li>
+ <li>此外,基於我們的繼承方式,<code>Teacher()</code> <code>prototype</code> 的建構子屬性目前設定為 <code>Person()。可參閱</code> <a href="https://stackoverflow.com/questions/8453887/why-is-it-necessary-to-set-the-prototype-constructor">Stack Overflow post</a> 進一步了解原因。可先儲存自己的程式碼、在瀏覽器中載入頁面,再將下列程式碼輸入至 JavaScript 主控台以驗證:
+ <pre class="brush: js">Teacher.prototype.constructor</pre>
+ </li>
+ <li>這樣可能會產生問題,所以要設定正確。你可回到自己的原始碼並在最下方加入下列程式碼:
+ <pre class="brush: js">Teacher.prototype.constructor = Teacher;</pre>
+ </li>
+ <li>如果儲存並重新整理之後,只要輸入 <code>Teacher.prototype.constructor</code> 應該就會回傳 <code>Teacher()</code>。</li>
+</ol>
+
+<h2 id="給_Teacher()_新的_greeting()_函式">給 Teacher() 新的 greeting() 函式</h2>
+
+<p>接著必須在 <code>Teacher()</code> 建構子上定義新的 <code>greeting()</code> 函式。</p>
+
+<p>最簡單的方法就是在 <code>Teacher()</code> 的原型上定義此函式。將下列加入程式碼最底部:</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>這樣就會顯示老師的問候語,也會針對老師的性別使用合適的稱呼,可用於條件陳述式。</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();</pre>
+
+<p>這樣應該運作無虞。前 3 行的存取成員即繼承自一般 <code>Person()</code> 建構子 (類別)。最後 2 行的存取成員只能用於特定的 <code>Teacher()</code> 建構子 (類別) 之上。</p>
+
+<div class="note">
+<p><strong>注意:</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 建立繼承類別的唯一方法,但足以堪用。並可讓你了解應如何於 JavaScript 實作繼承。</p>
+
+<p>你可能也想看看某些新的 {{glossary("ECMAScript")}} 功能,可更簡潔的在 JavaScript 中繼承 (參閱 <a href="/en-US/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="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS#Object-oriented_programming_from_10000_meters">〈OOP 理論〉段落</a>中,我們也納入了 <code>Student</code> 類別並繼承了 <code>Person</code> 的所有功能,此外也提供不同的 <code>greeting()</code> 函式,且較 <code>Teacher</code> 的問候語沒那麼正式。在看了該段落中的學生問候語之後,可試著實作自己的 <code>Student()</code> 建構子,並繼承 <code>Person()</code>, 的所有功能,再實作不同的 <code>greeting()</code> 函式。</p>
+
+<div class="note">
+<p><strong>注意:</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>簡單來說,你基本上需要考量 3 種類型的屬性\函式:</p>
+
+<ol>
+ <li>已於建構子函式中定義,會交給物件實體的屬性\函式。這應該很容易處理。在你自己的程式碼中,就是透過 <code>this.x = x</code> 類別行並在建構子中定義的成員;在瀏覽器程式碼中,就是僅限物件實體可用的成員 (一般是透過 <code>new</code> 關鍵字並呼叫建構子所建立,例如 <code>var myInstance = new myConstructor()</code>)。</li>
+ <li>直接在建構子上定義,並僅能用於該建構子的屬性\函式。這類屬性\函式往往只能用於內建瀏覽器物件之上,並直接「鍊接」至建構子 (而非實例) 以利識別,例如 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></code>。</li>
+ <li>定義於建構子原型上的屬性\函式,交由所有的實例繼承,亦繼承了物件類別。這類屬性\函式包含建構子原型屬性之上定義的所有成員,例如 <code>myConstructor.prototype.x()</code>。</li>
+</ol>
+
+<p>如果你不確定到底屬於上述的哪一個,也別擔心。現在你還在學習階段,往後定會熟能生巧。</p>
+
+<h2 id="在_JavaScript_中使用繼承的時機?">在 JavaScript 中使用繼承的時機?</h2>
+
+<p>看到這裡,你心裡應該覺得很複雜。沒錯。「原型」與「繼承」可說是 JavaScript 最複雜的概念之二,但許多 JavaScript 的強大功能與彈性,均來自於其物件結構與繼承,也值得你了解運作方式。</p>
+
+<p>不論是使用 WebAPI 的多樣功能,或是你在字串、陣列等所呼叫的函式\屬性 (定義於內建瀏覽器物件之上),你都可以不斷繼承下去。</p>
+
+<p>在自己的程式碼裡,特別是剛接觸或小型專案時,你用繼承的頻率可能沒那麼高。若沒真正需要,只是「為使用而使用」繼承,老實說只是浪費時間。但隨著程式碼規模越來越大,你就會找到使用的時間。如果你發現自己開始建立類似功能的多個物件時,就可先建立通用的物件類型,來概括所有共用的功能,並在特定物件類型中繼承這些功能,既方便又有效率。</p>
+
+<div class="note">
+<p><strong>注意:</strong>基於 JavaScript 運作的方式 (如原型鍊等),物件之間的功能共享一般稱為<strong>「</strong><strong>委託 (Delegation)」</strong>,即特定物件將功能委託至通用物件類型。「委託」其實比繼承更精確一點。因為「所繼承的功能」並不會複製到「進行繼承的物件」之上,卻是保留在通用物件之中。</p>
+</div>
+
+<p>當使用繼承時,建議你不要設定太多層的繼承關係,並時時留意你所定義的函式與屬性。在開始寫程式碼時,你可能會暫時修改內建瀏覽器物件的原型,除非你真的需要,否則儘量別這麼做。太多繼承可能連你自己都搞混,而且一旦需要除錯就會痛苦萬分。</p>
+
+<p>最後,物件可說是另一種形式的程式碼再利用,如同函式或迴圈一般,且有其專屬的角色與優點。如果你正建立一堆相關變數與函式,並要全部一起追蹤、封裝,就可以透過物件。你也能以物件方式傳送整個資料集合。而且上述兩種情況均不需使用建構子或繼承就能夠達成。如果你只需要某一物件的單一實作,那麼單純使用物件就好,完全不需要繼承。</p>
+
+<h2 id="摘要">摘要</h2>
+
+<p>本文為大家溫習了 OOJS 核心理論和語法。現在你應該了解 JavaScript 物件與 OOP 的基本概念、原型及原型繼承、建立類別 (建構子) 與物件實例的方法、為類別新增功能、建立從其他類別繼承而來的子類別。</p>
+
+<p>下篇文章就要來看看該如何搭配 JavaScript Object Notation (JSON),使用 JavaScript 物件的常見資料交換格式。</p>
+
+<h2 id="另可參閱">另可參閱</h2>
+
+<ul>
+ <li><a href="http://www.objectplayground.com/">ObjectPlayground.com</a> — 互動式學習網站,讓你了解物件。</li>
+ <li><a href="https://www.amazon.com/gp/product/193398869X/">Secrets of the JavaScript Ninja</a> 的第六章 — 進階 JavaScript 概念與技術的好書。第六章講述了原型與繼承的概念。此書有紙本與線上版。</li>
+ <li><a href="https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&amp;%20object%20prototypes/README.md#you-dont-know-js-this--object-prototypes">You Don't Know JS: this &amp; Object Prototypes</a> — Kyle Simpson 絕佳 JavaScript 手冊系列的一部分。第五章特別深入講述了原型。我們透過本文為初學者提供簡易概念,但 Kyle 則說明得更深入、更精確。</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</p>
diff --git a/files/zh-tw/learn/javascript/objects/json/index.html b/files/zh-tw/learn/javascript/objects/json/index.html
new file mode 100644
index 0000000000..71a4a3776a
--- /dev/null
+++ b/files/zh-tw/learn/javascript/objects/json/index.html
@@ -0,0 +1,325 @@
+---
+title: 使用 JSON 資料
+slug: Learn/JavaScript/Objects/JSON
+tags:
+ - 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) 為將結構化資料 (structured data) 呈現為 JavaScript 物件的標準格式,常用於網站上的資料呈現、傳輸 (例如將資料從伺服器送至用戶端,以利顯示網頁)。你應該會常常遇到,因此本文將說明 JavaScript 搭配 JSON 時所應知道的觀念,包含如何在 JSON 物件中存取資料項目,並寫出你自己的 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")}} 是依照 JavaScript 物件語法的資料格式,經 <a href="https://en.wikipedia.org/wiki/Douglas_Crockford">Douglas Crockford</a> 推廣普及。雖然 JSON 是以 JavaScript 語法為基礎,但可獨立使用,且許多程式設計環境亦可讀取 (剖析) 並產生 JSON。</p>
+
+<p>JSON 可能是物件或字串。當你想從 JSON中讀取資料時,JSON可作為物件;當要跨網路傳送 JSON 時,就會是字串。這不是什麼大問題 —  JavaScript 提供全域 <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">JSON</a> 物件,其內的函式可進行切換。</p>
+
+<p>JSON 物件可儲存於其自有的檔案中,基本上就是副檔名為 <code>.json</code> 的文字檔案,以及 <code>application/json</code> 的 {{glossary("MIME type")}}。</p>
+
+<h3 id="JSON_的架構">JSON 的架構</h3>
+
+<p>我們剛提到「JSON 物件基本上就是 JavaScript 物件」,而這敘述在大多數情況下都對。如同標準的 JavaScript 物件,你當然可在 JSON 之內加入相同的基本資料類型,如字串、數字、陣列、布林值,以及其他物件,接著同樣能再建構出資料繼承,如:</p>
+
+<pre class="brush: json">{
+  "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 物件基本概念</a>〉一文中提過的,接著能以相同的  存取其內部的資料,如下:</p>
+
+<pre class="brush: js">superHeroes.hometown
+superHeroes["active"]</pre>
+
+<p>若要順著繼承往下存取資料,只要將必要的屬性名稱與陣列索引「鍊」在一起即可。舉例來說,如果要存取成員列表中的第二位英雄的第三項超能力,你必須:</p>
+
+<pre class="brush: js">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> 屬性中有 1 個陣列具備所選超級英雄的能力。我們要選第三種能力,所以用 <code>[2]</code>。</li>
+</ol>
+
+<div class="note">
+<p><strong>注意:</strong>我們在 <a href="http://mdn.github.io/learning-area/javascript/oojs/json/JSONTest.html">JSONText.html</a> 範例 (參閱<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/JSONTest.html">原始碼</a>) 的變數中,示範上述可用的 JSON。你可在自己瀏覽器的 JavaScript 主控台載入此程式碼,並存取變數中的資料。</p>
+</div>
+
+<h3 id="陣列作為_JSON">陣列作為 JSON</h3>
+
+<p>我們在上面提過「 JSON 物件基本上就是 JavaScript 物件,而這敘述在大多數情況下都對」。其中「在大多數情況下都對」的理由,就是因為陣列也可以是有效的 JSON 物件,例如:</p>
+
+<pre class="brush: json">[
+ {
+ "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="其他附註">其他附註</h3>
+
+<ul>
+ <li>JSON 是純粹的資料格式 — 僅具備屬性,而無函式。</li>
+ <li>JSON 需要雙引號,才能使用\有效。所以最安全的方法就是以雙引號撰寫之。</li>
+ <li>單一個逗號或冒號放錯位置,也會讓 JSON 檔案出錯而無法運作。你應仔細檢視所有要使用的資料 (只要產生器程式能正確運作,由電腦產生的 JSON 也就不容易出錯)。你可透過如 <a href="http://jsonlint.com/">JSONLint</a> 的應用程式檢驗 JSON。</li>
+ <li>不限於陣列或物件,只要是符合標準 JSON 物件形式的任何資料,都可以夾帶進 JSON 檔案中。因此,單一字串或數字也可能是有效的 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> 到你的本端硬碟中。後者包含某些簡易的 CSS 可塑造網頁風格;前者則提供極簡單主體 HTML:</p>
+
+<pre class="brush: html">&lt;header&gt;
+&lt;/header&gt;
+
+&lt;section&gt;
+&lt;/section&gt;</pre>
+
+<p>加上 {{HTMLElement("script")}} 元素,才能納入稍後會在此習題中寫出來的 JavaScript 程式碼。目前只有 2 行程式碼,用以取得 {{HTMLElement("header")}} 與 {{HTMLElement("section")}} 元素的參考,並將之儲存於變數之中:</p>
+
+<pre class="brush: js">var header = document.querySelector('header');
+var section = document.querySelector('section');</pre>
+
+<p>你可到 GitHub 上找到此 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>接著載入到頁面之中,並使用某些有趣的 DOM 操控 (DOM manipulation) 來顯示,如下:</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")}} API (通常稱為 <strong>XHR</strong>)。此是極好用的 JavaScript 物件,可讓網路請求透過 JavaScript (例如圖片、文字、JSON,甚至 HTML 片段) 來檢索伺幅器的資源,這也代表我們不需載入整個頁面,就能更新小部分的內容。如此可讓網頁反應速度更快;聽起來很棒吧?但可惜本文無法再深入講解更多細節。</p>
+
+<ol>
+ <li>一開始,我們先針對要在變數中檢索的 JSON 檔案,將其網址儲存起來。把下列程式碼加到你 JavaScript 程式碼的最下方:
+ <pre class="brush: js">var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';</pre>
+ </li>
+ <li>為了建立請求,我們必須透過 <code>new</code> 關鍵字,先從 <code>XMLHttpRequest</code> 建構子建立新的請求物件實例。把下列加到最後一行:
+ <pre class="brush: js">var request = new XMLHttpRequest();</pre>
+ </li>
+ <li>現在用 <code><a href="/en-US/docs/Web/API/XMLHttpRequest/open">open()</a></code> 函式開啟新的請求。加入下列程式碼:
+ <pre class="brush: js">request.open('GET', requestURL);</pre>
+
+ <p>這樣就顧到至少 2 個參數。當然也有其他參數可選擇。但這個簡易範例只需要 2 個強制參數:</p>
+
+ <ul>
+ <li>在設立網路請求時,應使用 HTTP 函式。因為這裡只要檢索簡單的資料,所以用 <code><a href="/en-US/docs/Web/HTTP/Methods/GET">GET</a></code> 就可以。</li>
+ <li>URL 提供請求目的地 — 這也就是我們剛剛儲存的 JSON 檔案網址。</li>
+ </ul>
+ </li>
+ <li>接著加入下面 2 行程式碼。我們為 JSON 設定了 <code><a href="/en-US/docs/Web/API/XMLHttpRequest/responseType">responseType</a></code>,告知伺服器應回傳 JSON 物件,再以 <code><a href="/en-US/docs/Web/API/XMLHttpRequest/send">send()</a></code> 函式傳送請求:
+ <pre class="brush: js">request.responseType = 'json';
+request.send();</pre>
+ </li>
+ <li>最後就是等待由伺服器所回傳的反應,再接著處理。把下列程式碼加入現有程式碼的最下方:
+ <pre class="brush: js">request.onload = function() {
+ var superHeroes = request.response;
+ populateHeader(superHeroes);
+ showHeroes(superHeroes);
+}</pre>
+ </li>
+</ol>
+
+<p>在這裡,我們將所獲得的響應 (可到 <code><a href="/en-US/docs/Web/API/XMLHttpRequest/response">response</a></code> 屬性中找到) 儲存到 <code>superHeroes</code> 變數之中。此變數現在會納入我們的 JSON。接著再把此 JSON 檔案送到 2 個函式呼叫。第一個函式呼叫會將正確資料填入 &lt;<code>header&gt;</code>;第二個函式呼叫則會為團隊中的各個英文建立資訊卡,再插入至 <code>&lt;section&gt;</code> 內。</p>
+
+<p>當於請求物件上觸發載入事件時,會執行一個事件處理器。我們就將程式碼包裹至此處理器之中 (參閱 <code><a href="/en-US/docs/Web/API/XMLHttpRequestEventTarget/onload">onload</a></code>) — 只要成功回傳響應,就會觸發載入事件。之所以這樣做,是為了確保當我們要以 <code>request.response</code> 進行某件事時,此 <code>request.response</code> 絕對可用。</p>
+
+<h3 id="產生標頭">產生標頭</h3>
+
+<p>現在檢索過了 JSON 資料,接著就寫出上面參照過的 2 個函式來利用 JSON 資料吧。首先將下列函式定義加到先前的程式碼中:</p>
+
+<pre class="brush: js">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>,所以在這個函式之內就要用 jsonObj 呼叫此參數。這裡先以 <code><a href="/en-US/docs/Web/API/Document/createElement">createElement()</a></code> 建立 1 組 {{HTMLElement("h1")}} 元素、將其 <code><a href="/en-US/docs/Web/API/Node/textContent">textContent</a></code> 指定為 JSON 的 <code>squadName</code> 屬性、透過 <code><a href="/en-US/docs/Web/API/Node/appendChild">appendChild()</a></code> 將之附加到標頭。接著 {{HTMLElement("p")}} 元素依樣畫葫蘆一遍:建立、設定其文字內容、附加到標頭。唯一不同之處,就是將該文字設定為 1 組串接字串 (Concatenated string),其內包含 JSON 的 <code>homeTown</code> 與 <code>formed</code> 屬性。</p>
+
+<h3 id="建立超級英雄的資訊卡片">建立超級英雄的資訊卡片</h3>
+
+<p>現在將下列函式加到程式碼底端,用以建立並顯示超級英雄的卡片:</p>
+
+<pre class="brush: js">function showHeroes(jsonObj) {
+ var heroes = jsonObj['members'];
+
+ for(i = 0; i &lt; 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(j = 0; j &lt; 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>我們先把 JSON 的 <code>members</code> 屬性儲存到新的變數中。此陣列所具備的多個物件,均包含了各個超級英雄的資訊。</p>
+
+<p>接著我們以 <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code#The_standard_for_loop">for 迴圈</a>循環陣列中的各個物件。針對每個物件都會:</p>
+
+<ol>
+ <li>建立數個新的元素:1 組 <code>&lt;article&gt;</code>、1 組 <code>&lt;h2&gt;、3 組</code> <code>&lt;p&gt;、1 組</code> <code>&lt;ul&gt;。</code></li>
+ <li>讓 &lt;h2&gt; 納入目前超級英雄的 <code>name</code>。</li>
+ <li>接著 3 個段落分別是英雄的 <code>secretIdentity</code>、<code>age、Superpowers</code>,在列表中帶出相關資訊。</li>
+ <li>另以新變數 <code>superPowers</code> 儲存 <code>powers</code> 屬性 — 其中包含 1 組陣列以列出目前英雄的超能力。</li>
+ <li>再用另一個 <code>for</code> 迴圈逐一巡過目前英雄的超能力。針對每一項超能力,我們再建立 1 組 <code>&lt;li&gt;</code> 元素,把超能力放進該元素之中,再透過 <code>appendChild()</code> 把 <code>listItem</code> 放入 <code>&lt;ul&gt;</code> 元素之內 (<code>myList</code>)。</li>
+ <li>最後就是在 <code>&lt;article&gt;</code> (<code>myArticle</code>) 之內附加 <code>&lt;h2&gt;、</code><code>&lt;p&gt;、</code><code>&lt;ul&gt;</code>;再把 <code>&lt;article&gt;</code> 附加於 <code>&lt;section&gt;</code> 之內。這附加的順序極為重要,因為這也會是 HTML 中的顯示順序。</li>
+</ol>
+
+<div class="note">
+<p><strong>注意:</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">實際執行情況</a>。)</p>
+</div>
+
+<div class="note">
+<p><strong>注意:</strong>如果你無法用我們說過的點記法 (dot-)\括弧記法 (bracket notation) 來存取 JSON,則可用新分頁或自己的文字編輯器開啟 <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 物件基礎概念</a> ,再次了解點\括弧記法。</p>
+</div>
+
+<h2 id="物件與文字交互轉換">物件與文字交互轉換</h2>
+
+<p>上述是存取 JSON 的簡易範例,因為我們設定要回傳響應的 XHR 已經是 JSON 格式。透過:</p>
+
+<pre class="brush: js">request.responseType = 'json';</pre>
+
+<p>但有時候沒這麼好運。我們有時會接收到文字字串格式的 JSON 資料,且必須將之轉換為物件。且當我們要以某種訊息傳送 JSON 資料時,也必須將之轉換為字串才能正確運作。還好,這 2 種問題在 Web 開發過程中甚為常見。內建的 <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">JSON</a> 物件很早就新增到瀏覽器之中,且包含下列 2 種函式:</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">原始碼</a>) 中看到第一個函式的運作情形。這其實跟我們先前範例所進行的事情一模一樣,不同之處在於我們設定 XHR 要回傳 JSON 為文字,接著再使用 <code>parse()</code> 轉換為實際的 JSON 物件。關鍵程式碼片段如下:</p>
+
+<pre class="brush: js">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">var myJSON = { "name" : "Chris", "age" : "38" };
+myJSON
+var myString = JSON.stringify(myJSON);
+myString</pre>
+
+<p>這樣就建立了 JSON 物件了。接著檢查內容物之後,就可透過 <code>stringify()</code> 將之轉換為字串。將回傳值儲存到新變數之中,再檢查一次即可。</p>
+
+<h2 id="摘要">摘要</h2>
+
+<p>我們透過本文簡單介紹了該如何在程式中使用 JSON、該如何建立\剖析 JSON、該如何存取其內的資料。接著就要說明物件導向 JavaScript (OOJS)。</p>
+
+<h2 id="另可參閱">另可參閱</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">JSON 物件參考頁面</a></li>
+ <li><a href="/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest 物件參考頁面</a></li>
+ <li><a href="/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest">使用 XMLHttpRequest</a></li>
+ <li><a href="/en-US/docs/Web/HTTP/Methods">HTTP 請求函式</a></li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}</p>
diff --git a/files/zh-tw/learn/javascript/objects/object-oriented_js/index.html b/files/zh-tw/learn/javascript/objects/object-oriented_js/index.html
new file mode 100644
index 0000000000..1504f5fc49
--- /dev/null
+++ b/files/zh-tw/learn/javascript/objects/object-oriented_js/index.html
@@ -0,0 +1,277 @@
+---
+title: 初學者應知道的物件導向 JavaScript
+slug: Learn/JavaScript/Objects/Object-oriented_JS
+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) 的理論,另說明 JavaScript 是如何透過建構子函式來模擬物件類別,又是如何建立物件實體 (Instance)。</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">必備條件:</th>
+ <td>基本的電腦素養、已初步了解 HTML 與 CSS、熟悉 JavaScript (參閱〈<a href="/zh-TW/docs/Learn/JavaScript/First_steps">First steps</a>〉與〈<a href="/zh-TW/docs/Learn/JavaScript/Building_blocks">Building blocks</a>〉以及 OOJS 基礎概念 (參閱〈<a href="/zh-TW/docs/Learn/JavaScript/Object-oriented/Introduction">物件基礎概念</a>〉。</td>
+ </tr>
+ <tr>
+ <th scope="row">主旨:</th>
+ <td>了解物件導向程式設計的基本理論、其與 JavaScript (幾乎所有東西都是物件) 之間的關係、應如何寫出建構子與物件實體。</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="基本物件導向程式設計">基本物件導向程式設計</h2>
+
+<p>最先,讓我們從簡單、高層次的視角來看物件導向程式設計 (Object-oriented programming;OOP) 最基本的概念。我們說簡單是因為 OOP 很容易變得複雜,就算現在就設法完整解釋,也可能讓大家越來越混亂。OOP 基本概念是:採用物件(objects)來模塑真實的實物世界:也就是在程式中的呈現是透過 objects 來塑造其模型,且\或提供簡單方式存取其「難以或不可能採用的功能」。</p>
+
+<p>物件可裝載相關的資料與程式碼,資料部分是你塑造某個模型的資訊,而程式碼部分則用是操作行為(<strong>Method</strong>)實現。Object data  -- 函式部分通常也使用 ---可工整地儲存 (正式一點應該是<strong>封裝 Encapsulated</strong>) 在物件包裹(這個包裹有特定的稱呼方式,有時候即所謂的<strong>命名空間 Namespace</strong>) ,使其能輕鬆地建構性存取。物件也常作為「資料儲存 (Datastore),促成簡易實現跨網傳送。</p>
+
+<h3 id="定義物件範本">定義物件範本</h3>
+
+<p>我們先找個簡單程式,如同學校裡用來顯示師生資訊的程式。本文只是要了解一般的 OOP 理論,並非以特定程式語言為出發點。</p>
+
+<p>我們先拿<a href="/zh-TW/docs/Learn/JavaScript/Objects/Basics">第一篇物件文章</a>中的「Person」物件類型為範例,其中定義了一個人的一般資料與功能。其實有很多資訊可助你了解一個人 (像是住址、身高、鞋子尺寸、DNA、護照號碼、明顯的人格特質等......),但我們這裡只列出了姓名、年齡、性別、興趣。我們另希望根據這些資料寫出簡介,初步了解這個人。上述這些即所謂的「<strong>抽象 (Abstraction)」</strong>。為某個複雜東西建立簡單的模型,藉以代表其最重要的概念或特質,且該模型建立方式極易於搭配我們的程式設計用途。</p>
+
+<p><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>物件實體 (Object instance)</strong> — 即該物件包含了類別中所定義的資料與功能。而「Person」類別可設定出幾個實際的人物:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13889/person-diagram.png" style="display: block; height: 219px; margin: 0px auto; width: 610px;"></p>
+
+<p>在根據類別建立物件實體時,就是執行類別的「<strong>建構子 (Constructor) 函式</strong>」所建立。而這個「根據類別來建立物件實體」的過程即稱為「<strong>實體化 (Instantiation)」</strong>。物件實體就是從類別實體化而來。</p>
+
+<h3 id="特殊類別">特殊類別</h3>
+
+<p>如果我們不要一般人物,而想建立老師與學生這類比較特定類型的人物。在 OOP 中,我們可根據其他類別建立新的類別。新的子類別則可<strong>繼承 (Inherit) </strong>其<strong>母類別</strong>的資料與程式碼特性。你可重複使用所有物件類型共有的功能,而不需再複製之。若功能需與類別有所差異,則可直接於其上定義特殊功能。</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>這樣很方便。因為老師與學生也同樣使用了如姓名、性別、年齡等的共通特性,所以只要定義這些特性 1 次即可。你也可以分別在不同的類別中定義相同特性,各個特性的定義就置於不同的命名空間中。舉例來說,學生的打招呼方式可以是「Yo, I'm [firstName]」;老師的招呼方式就正式一點,如「Hello, my name is [Prefix] [lastName]」。</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>本文後面將講解應如何將 OOP 理論實際用於 JavaScript 中。</p>
+
+<h2 id="建構子與物件實例">建構子與物件實例</h2>
+
+<p>JavaScript 使用稱為建構子函式(<strong>constructor function</strong>)的特殊函式,定義物件與功能。開發者常常會不知道到底需建立多少物件,這時建構子可讓你高效率建立所需物件,並依需要為其添加資料與函式。</p>
+
+<p>在新的物件實例透過建構子函式產生後,其核心將透過一種稱為<strong>原型鏈</strong>(Prototype chain,由原型定義,可參閱 <a href="/zh-TW/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a>)的參照鏈連在一起。</p>
+
+<p>接著就在 JS 中,透過建構子建立類別及其物件實例。首先請你先在本端磁碟中再另外複製一份前面文章提過的 <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>呼叫此函式之後即可建立新的 1 個人,另在瀏覽器的 JavaScript 主控台中測試下列程式碼:
+ <pre class="brush: js">var salva = createNewPerson('salva');
+salva.name;
+salva.greeting();</pre>
+ 目前為止沒什麼問題,但有點囉嗦。如果早知道要建立物件的話,又何必要建立新的空白物件再回傳呢?幸好 JavaScript 透過建構子函式提供了方便的捷徑。現在就來試試看!</li>
+ <li>用下列程式碼替代之前的函式:
+ <pre class="brush: js">function Person(name) {
+ this.name = name;
+ this.greeting = function() {
+ alert('Hi! I\'m ' + this.name + '.');
+ };
+}</pre>
+ </li>
+</ol>
+
+<p>建構子也就是 JavaScript 版本的「類別」之一。你可以注意到,除了無法回傳任何數值或明確建立物件之外,建構子其實已具備函式中的所有功能,並已基本定義了屬性與函式 (Method)。你也能看到這裡同樣用了「<code>this</code>」關鍵字,即不論何時建立了這裡的任一物件實例,物件的「<code>name</code>」屬性均同等於「傳送至建構子呼叫的名稱值」;且 <code>greeting()</code> 函式也會使用相同「傳送至建構子呼叫的名稱值」。</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>儲存程式碼並在瀏覽器中重新載入,試著將下列程式碼輸入到文字輸入畫面中:
+ <pre class="brush: js">person1.name
+person1.greeting()
+person2.name
+person2.greeting()</pre>
+ </li>
+</ol>
+
+<p>現在你應該能在頁面上看到兩組新物件,且各自以不同的命名空間儲存。若要存取其屬性與函式,就要以 <code>person1</code> 或 <code>person2</code> 開始呼叫。這些物件均完整封包,不致與其他功能衝突;但仍具備相同的 <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>剛剛說的「有效率」,是因為實際功能仍定義於類別中,而非物件實例之中。這情況與我們稍早談過的物件實字 (Object literal) 相反。</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,
+ 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> 陣列中列出超過 2 個以上的「興趣」,這個 bio 函式也只會有 2 個興趣。你能試著在類別定義 (建構子) 中修正這個問題嗎?你可在建構子中放入任何你喜歡的程式碼 (但可能會需要幾個 conditionals 搭配 1 個迴圈)。想想應如何根據性別以及列出的興趣 (1 或 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 repo 上提供了解答</a> (<a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">立刻觀看</a>)。先試著自己解決問題吧!</p>
+</div>
+
+<h2 id="建立物件實例的其他方法">建立物件實例的其他方法</h2>
+
+<p>目前解釋了 2 種建立物件實例的方法 — <a href="/zh-TW/docs/Learn/JavaScript/Objects/Basics#Object_basics">宣告物件實字</a>,以及使用建構子函式。</p>
+
+<p>當然還有別的方法,但我們希望你先熟悉此 2 種方法,以免你日後的 Web 旅程上會再遇到。</p>
+
+<h3 id="Object_建構子">Object() 建構子</h3>
+
+<p>首先可使用 <code><a href="/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object">Object()</a></code> 建構子建立新的物件。沒錯,即使是泛型物件 (Generic object) 也具備建構子,可用以產生空白物件。</p>
+
+<ol>
+ <li>將下列輸入瀏覽器的 JavaScript 主控台內:
+ <pre class="brush: js">var person1 = new Object();</pre>
+ </li>
+ <li>如此會在 <code>person1</code> 變數中儲存 1 組空白物件。接著可透過點 (dot-) 或括弧記法 (bracket notation) 為此物件新增屬性與函式。如下列範例:
+ <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>不過,有些人偏好建立物件實例,而不先做建構子,尤其是他們的物件不會用很多實例時。JavaScript 有個稱作 <code><a href="/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create()</a></code> 的內建函式能讓你這麼做。有了它,你就能根據現有物件,建立新的物件。</p>
+
+<ol>
+ <li>在 JavaScript 主控台裡測試:
+ <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> 的其中一個限制,就是 IE8 並不支援。因此,如果你需要支援舊版瀏覽器,建構子會比較有用。</p>
+
+<p>我們後續會再說明 <code>create()</code> 的效果。</p>
+
+<h2 id="總結">總結</h2>
+
+<p>本文簡略說明了 OO 理論,雖然還沒全部講完,至少也讓你初步了解到本文所要闡述的重點。此外,我們已經開始說明 JavaScript 與 OO 之間的關係、其與「傳統 OO」之間的差異、使用建構子於 JavaScript 中實作類別的方法,以及其他產生物件實例的方式。</p>
+
+<p>下一篇文章將說明 JavaScript 物件原型。</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="/zh-TW/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li>
+ <li><a href="/zh-TW/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li>
+ <li><a href="/zh-TW/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li>
+ <li><a href="/zh-TW/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li>
+ <li><a href="/zh-TW/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li>
+ <li><a href="/zh-TW/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li>
+ <li><a href="/zh-TW/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li>
+</ul>
diff --git a/files/zh-tw/learn/javascript/objects/object_building_practice/index.html b/files/zh-tw/learn/javascript/objects/object_building_practice/index.html
new file mode 100644
index 0000000000..4a47aa39eb
--- /dev/null
+++ b/files/zh-tw/learn/javascript/objects/object_building_practice/index.html
@@ -0,0 +1,283 @@
+---
+title: 物件建構實作
+slug: Learn/JavaScript/Objects/Object_building_practice
+tags:
+ - Canvas
+ - JavaScript
+translation_of: Learn/JavaScript/Objects/Object_building_practice
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "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="/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>親手實作物件與物件導向 (OO) 技術。</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="弄一些彈跳彩球">弄一些彈跳彩球</h2>
+
+<p>本文將帶領你實作經典的「彈跳球」展示網頁,讓你了解物件在 JavaScript 中的用處。這些小球會在畫面上四處彈跳,而且互相碰撞時變換顏色。範例成品如下:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13865/bouncing-balls.png" style="display: block; height: 614px; margin: 0px auto; width: 800px;"></p>
+
+<ol>
+</ol>
+
+<p>此範例將透過 <a href="/en-US/docs/Web/API/Canvas_API">Canvas API</a> 在畫面上繪製球體,<a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame</a> API 則是繪製整個動畫;而且你不需先了解此兩個 API。但我們希望在看完本文之後,能引起大家深入探究此兩個 API 的興趣。整個過程會利用某些花俏的物件,並讓你看到幾項有趣技術,像是球體從牆上回彈,並檢查球體是否互相碰撞 (也就是碰撞偵測)。</p>
+
+<h2 id="著手開始">著手開始</h2>
+
+<p>先複製 <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/index.html">index.html</a></code><code>、<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/style.css">style.css</a></code>、<code><a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/main.js">main.js</a></code> 檔案到你的本機磁碟中。這些檔案分別具備下列:</p>
+
+<ol>
+ <li>極簡的 HTML 文件,具備 1 個 {{HTMLElement("h1")}} 元素、1 個 {{HTMLElement("canvas")}} 元素可繪製彩球,以及其他元素可將 CSS 與 JavaScript 套用到 HTML 之上。</li>
+ <li>一些極簡單的樣式,主要可作為 <code>&lt;h1&gt; 的樣式風格與定位之用,並省去網頁邊緣的捲動棒或空白</code> (看起來更簡約)。</li>
+ <li>某些 JavaScript 可用以設定 <code>&lt;canvas&gt;</code> 元素,另有通用函式可供我們往後使用。</li>
+</ol>
+
+<p>指令碼第一部分就像:</p>
+
+<pre class="brush: js">var canvas = document.querySelector('canvas');
+
+var ctx = canvas.getContext('2d');
+
+var width = canvas.width = window.innerWidth;
+var height = canvas.height = window.innerHeight;</pre>
+
+<p>此指令碼將為 <code>&lt;canvas&gt;</code> 元素提供參照,接著於其上呼叫 <code><a href="/en-US/docs/Web/API/HTMLCanvasElement/getContext">getContext()</a></code> 函式,藉以提供能開始繪圖的內文 (Context)。所產生的變數 (<code>ctx</code>) 也就是物件,將直接呈現 canvas 的繪圖區域,讓我們繪製 2D 圖像。</p>
+
+<p>接著設定 <code>width</code> 與 <code>height</code> 共 2 個變數,也就是 canvas 元素的寬度與高度 (透過 <code>canvas.width</code> 與 <code>canvas.height</code> 屬性呈現) 即等於瀏覽器可視區的寬度與高度 (也就是網頁顯示的區域 — 可經由 {{domxref("Window.innerWidth")}} 與 {{domxref("Window.innerHeight")}} 屬性得知)。</p>
+
+<p>你會看到我們在這裡串連了多個指定式,以快速設定所有變數,而且運作無虞。</p>
+
+<p>剛開始的指令碼後半部如下:</p>
+
+<pre class="brush: js">function random(min, max) {
+ var num = Math.floor(Math.random()*(max-min)) + min;
+ return num;
+}</pre>
+
+<p>此函式共有 2 組參數 (argument),並會回傳此範圍之內的任意值。</p>
+
+<h2 id="在程式中設定球體的模型">在程式中設定球體的模型</h2>
+
+<p>我們的程式會讓一堆彩球在畫面中彈來彈去。因為這些球體的行動方式均相同,所以透過物件呈現這些彩球也合情合理。先在程式碼底部加入下列建構子:</p>
+
+<pre class="brush: js">function Ball() {
+ this.x = random(0,width);
+ this.y = random(0,height);
+ this.velX = random(-7,7);
+ this.velY = random(-7,7);
+ this.color = 'rgb(' + random(0,255) + ',' + random(0,255) + ',' + random(0,255) +')';
+ this.size = random(10,20);
+}</pre>
+
+<p>這裡我們要定義某些屬性,以利彩球能在程式中動作:</p>
+
+<ul>
+ <li><code>x</code> 與 <code>y</code> 座標 — 每顆彩球都會先有位於畫面中的隨機水平\垂直座標。範圍從 0 (最左上角) 到瀏覽器可視區的寬\高度 (最右下角) 為止。</li>
+ <li>水平與垂直速度 (<code>velX</code> 與 <code>velY</code>) — 每顆彩球均具備隨機的速度值;在我們開始彩球動畫時,這些數值就會加上 <code>x</code>/<code>y</code> 座標值,以利在各畫格(frame)中移動彩球。</li>
+ <li><code>color</code> — 彩球的顏色是隨機產生。</li>
+ <li><code>size</code> — 各彩球大小亦為隨機,從 10 到 20 像素不等。</li>
+</ul>
+
+<p>屬性講完了,那函式呢?程式中的彩球要實際運作才行。</p>
+
+<h3 id="繪製球體">繪製球體</h3>
+
+<p>先將下列 <code>draw()</code> 函式加到 <code>Ball() 的</code> <code>prototype 之中:</code></p>
+
+<pre class="brush: js">Ball.prototype.draw = function() {
+ ctx.beginPath();
+ ctx.fillStyle = this.color;
+ ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
+ ctx.fill();
+}</pre>
+
+<p>透過此函式,再呼叫我們之前定義在 2D canvas 內文(ctx)中的物件成員,就能讓球體自己在螢幕上畫出自己。此內文就像是白紙一樣,接著就用筆在紙上畫出點東西:</p>
+
+<ul>
+ <li>首先以 <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/beginPath">beginPath()</a></code> 聲明我們要在紙上畫出來的形狀。</li>
+ <li>接著用 <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle">fillStyle</a></code> 定義該形狀所要呈現的顏色 — 設定為球體的 <code>color</code> 屬性。</li>
+ <li>再用 <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/arc">arc()</a></code> 函式在紙上勾勒出弧形。相關參數為:
+ <ul>
+ <li>弧形中心的 <code>x</code> 與 <code>y</code> 位置 — 我們指定球體的 <code>x</code> 與 <code>y</code> 屬性。</li>
+ <li>弧形半徑 — 指定球體的 <code>size</code> 屬性。</li>
+ <li>最後 2 項參數則指定弧形繪製時的圓圈起、終點角度。我們這裡指定 0 度與 <code>2 * PI</code> 度,這也等於半徑繞了 360 度 (你必須在半徑中指定,有點煩)。如此構成完整的圓。如果你只設定了 <code>1 * PI,就會只有半球體</code> (即 180 度)。</li>
+ </ul>
+ </li>
+ <li>最後使用 <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/fill">fill()</a></code> 函式,基本上是用來聲稱「完成我們以 <code>beginPath()</code> 開始的繪圖路徑,再用 <code>fillStyle 中指定的色彩將之填滿</code>」。</li>
+</ul>
+
+<p>你已經可以開始測試自己的物件了。</p>
+
+<ol>
+ <li>儲存目前的程式碼,在瀏覽器中載入此 HTML 檔案。</li>
+ <li>開啟瀏覽器的 JavaScript 主控台,並在主控台開啟時重新整理網頁,讓 canvas 尺寸變更為左側較小型的可視區域。</li>
+ <li>鍵入下列程式碼以建立新的球體實例:
+ <pre class="brush: js">var testBall = new Ball();</pre>
+ </li>
+ <li>再呼叫其成員:
+ <pre class="brush: js">testBall.x
+testBall.size
+testBall.color
+testBall.draw()</pre>
+ </li>
+ <li>輸入最後一行之後,應該就能看到 canvas 上出現自己產生的球體。</li>
+</ol>
+
+<h3 id="更新球體的資料">更新球體的資料</h3>
+
+<p>現在可以繪製彩球了。但在讓球彈跳之前,我們必須先更新幾個函式。將下列程式碼加到 JavaScript 檔案底端,把 <code>update()</code> 函式加到 <code>Ball()</code> 的 <code>prototype</code> 之中:</p>
+
+<pre class="brush: js">Ball.prototype.update = function() {
+ if((this.x + this.size) &gt;= width) {
+ this.velX = -(this.velX);
+ }
+
+ if((this.x - this.size) &lt;= 0) {
+ this.velX = -(this.velX);
+ }
+
+ if((this.y + this.size) &gt;= height) {
+ this.velY = -(this.velY);
+ }
+
+ if((this.y - this.size) &lt;= 0) {
+ this.velY = -(this.velY);
+ }
+
+ this.x += this.velX;
+ this.y += this.velY;
+}</pre>
+
+<p>函式的前 4 個部分負責檢查球體是否碰到 canvas 邊緣。如果球體抵達邊緣,我們就反轉相對加速度的方向,讓球反方向行進。以球體向上 (正向 <code>velX</code>) 時為例,接著就會改變水平速度,球體也就反向運動。</p>
+
+<p>在這 4 個情境中,我們:</p>
+
+<ul>
+ <li>檢查 <code>x</code> 座標是否大於 canvas 的寬度 (球體抵達右側邊緣)。</li>
+ <li>檢查 <code>x</code> 座標是否小於 0 (球體抵達左側邊緣)。</li>
+ <li>檢查 <code>y</code> 座標是否大於 canvas 的高度 (球體抵達底部邊緣)。</li>
+ <li>檢查 <code>y</code> 座標是否小於 0 (球體抵達頂部邊緣)。</li>
+</ul>
+
+<p>在各情境中,因為 <code>x</code>/<code>y</code> 座標為球體的中心,所以我們把球體的 <code>size</code> 納入計算,但我們不要球體在回彈之前在半路上就跳出畫面之外。</p>
+
+<p>最後 2 行則是將 <code>velX</code> 與 <code>velY</code> 值分別加入 <code>x\y</code> 座標之中;每次只要呼叫此函式,球體就會依照應有的效果移動。</p>
+
+<p>到這裡沒有問題的話,就開始弄動畫吧!</p>
+
+<h2 id="球體動起來">球體動起來</h2>
+
+<p>接著來玩玩吧。我們要加更多球到 canvas 中並開始動畫效果。</p>
+
+<ol>
+ <li>首先要弄個地方儲存所有的彩球。將下方陣列加到現有程式碼底部即可:
+ <pre class="brush: js">var balls = [];</pre>
+
+ <p>所有可提供動畫效果的程式,一般都會採用動畫迴圈,可用以更新程式中的資訊,並接著在動畫的各個畫格上繪製產生的結果。這也是大部分遊戲或類似程式的基礎。</p>
+ </li>
+ <li>再將下列程式碼加到現有程式碼底部:
+ <pre class="brush: js">function loop() {
+ ctx.fillStyle = 'rgba(0,0,0,0.25)';
+ ctx.fillRect(0,0,width,height);
+
+ while(balls.length &lt; 25) {
+ var ball = new Ball();
+ balls.push(ball);
+ }
+
+ for(i = 0; i &lt; balls.length; i++) {
+ balls[i].draw();
+ balls[i].update();
+ }
+
+ requestAnimationFrame(loop);
+}</pre>
+
+ <p>我們的 <code>loop()</code> 函式可進行:</p>
+
+ <ul>
+ <li>設定 canvas 填滿色彩或是半透明的黑色。接著透<code>過 fillRect()</code> (共 4 個參數提供起始座標,以及繪製矩形的高度與寬度),跨 canvas 的寬度與高度繪製整個矩型的色彩。如此可在繪製下一個畫格之前,先覆蓋前一個已存在的畫格;否則會看到許多隻長長的蛇爬來爬去。填充顏色已設定為半透明狀態:<code>rgba(0,0,0,0.25)</code> 可讓先前的畫格微微發亮,製造出球體移動時的小尾巴效果。如果將 0.25 更改為 1,就會完全消除尾巴。你可自己測試不同的數值,找出自己喜歡的效果。</li>
+ <li>可對 <code>Ball()</code> 建立新的實作,接著將之 <code>push()</code> 到球體陣列的最後,且彩球數量必須少於 25 個。所以整個畫面最多顯示 25 個球。你可嘗試變更 <code>balls.length &lt; 25</code> 中的數值,畫面中的彩球數量也會隨著變化。依你所用電腦\瀏覽器處理效能的不同,若繪製上千個彩球就會拖慢整個動畫的速度。</li>
+ <li>迴圈將巡過 <code>balls</code> 陣列中的所有彩球,並執行各個彩球的 <code>draw()</code> 與 <code>update()</code> 函式,以於畫面中逐一繪製,接著對下個畫格的位置與速度執行必要更新。</li>
+ <li>再以 <code>requestAnimationFrame()</code> 函式執行過此函式 — 當此函式持續執行並傳送相同的函式名稱時,就會每秒執行此函式達特定次數,以產生流暢的動畫。接著重複執行此作業,也就是函式每次執行時均會呼叫自身 1 次,進而循環執行。</li>
+ </ul>
+ </li>
+ <li>最後將下列程式碼加入最底端,呼叫函式 1 次讓動畫開始運作。
+ <pre class="brush: js">loop();</pre>
+ </li>
+</ol>
+
+<p>基本就是這樣了。試著儲存並重新整理檔案,讓你的彩球開始跳動吧!</p>
+
+<h2 id="另增碰撞偵測">另增碰撞偵測</h2>
+
+<p>現在弄點有趣的東西,就把碰撞偵測 (Collision detection) 加進程式裡,讓彩球知道自己碰到其他球了。</p>
+
+<ol>
+ <li>首先將下列函式定義加進你自己定義 <code>update()</code> 函式中 (例如 <code>Ball.prototype.update</code> 區塊):
+
+ <pre class="brush: js">Ball.prototype.collisionDetect = function() {
+ for(j = 0; j &lt; balls.length; j++) {
+ if( (!(this.x === balls[j].x &amp;&amp; this.y === balls[j].y &amp;&amp; this.velX === balls[j].velX &amp;&amp; this.velY === balls[j].velY)) ) {
+ var dx = this.x - balls[j].x;
+ var dy = this.y - balls[j].y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+
+ if (distance &lt; this.size + balls[j].size) {
+ balls[j].color = this.color = 'rgb(' + random(0,255) + ',' + random(0,255) + ',' + random(0,255) +')';
+ }
+ }
+ }
+}</pre>
+
+ <p>這函式有點複雜,所以現在不瞭解如何運作的也別擔心。解釋如下:</p>
+
+ <ul>
+ <li>對每個彩球來說,我們必須檢查是否碰撞到其他球。所以要設定另一個 <code>for</code> 迴圈以循環檢視 <code>balls[]</code> 陣列中的所有彩球。</li>
+ <li>在我們的 for 迴圈中,我們立刻使用 <code>if</code> 陳述式檢查「現正透過迴圈循環檢查中」的彩球,是否即為我們目前檢查中的同一彩球。我們不需要檢查彩球是否碰撞到自己!為了達到此效果,我們檢查彩球目前的 <code>x</code>/<code>y</code> 座標與速度,是否等同於迴圈檢查的彩球。接著透過「<code>!</code>」否定檢查,所以在 if 陳述式中的程式碼,只有在彩球相異時才會執行。</li>
+ <li>接著使用一般演算法檢查 2 個球體之間的碰撞。我們基本上會檢查任 2 個球體的範圍是否重疊。另將透過〈<a href="/en-US/docs/Games/Techniques/2D_collision_detection">2D 碰撞偵測</a>〉一文進一步解釋。</li>
+ <li>如果偵測到碰撞,則隨即執行內部 <code>if</code> 陳述式的程式碼。在本範例中,我們剛設定了 2 個球體的 <code>color</code> 屬性為新的隨機色彩。但當然可以更複雜點,像是讓彩球更逼真的互相反彈,但這實作起來就更複雜了。對這類的物理模擬,開發者就必須使用如 <a href="http://wellcaffeinated.net/PhysicsJS/">PhysicsJS</a>、<a href="http://brm.io/matter-js/">matter.js</a>、<a href="http://phaser.io/">Phaser</a> 等的遊戲\物理函式庫。</li>
+ </ul>
+ </li>
+ <li>你也可以在動畫的每一畫格中呼叫此一函式。在 <code>balls[i].update();</code> 這一行下方新增下列程式碼即可:
+ <pre class="brush: js">balls[i].collisionDetect();</pre>
+ </li>
+ <li>儲存並重新整理之後,就能看到球體在碰撞時變更其色彩了!</li>
+</ol>
+
+<div class="note">
+<p><strong>注意:</strong>如果你無法讓此範例順利運作,可比較我們的<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/main-finished.js">最後版本</a> (另可參閱<a href="http://mdn.github.io/learning-area/javascript/oojs/bouncing-balls/index-finished.html">實際執行情形</a>)。</p>
+</div>
+
+<h2 id="摘要">摘要</h2>
+
+<p>希望你喜歡撰寫出隨機彩球碰撞範例,其內並包含我們前面說過的多樣物件與 OO 技術!本文應該已提供你有用的物件實作與絕佳的實際文本。</p>
+
+<p>物件實體就到這裡。接著就是你要磨練自己的物件技術了!</p>
+
+<h2 id="另可參閱">另可參閱</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/API/Canvas_API/Tutorial">Canvas 線上教學</a> — 2D canvas 初學者指南</li>
+ <li><a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></li>
+ <li><a href="/en-US/docs/Games/Techniques/2D_collision_detection">2D 碰撞偵測</a></li>
+ <li><a href="/en-US/docs/Games/Techniques/3D_collision_detection">3D 碰撞偵測</a></li>
+ <li><a href="/en-US/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript">只使用 JavaScript 的 2D 打磚塊遊戲</a> — 2D 遊戲開發初學者的絕佳線上教學</li>
+ <li><a href="/en-US/docs/Games/Tutorials/2D_breakout_game_Phaser">剖析器 (Phaser) 的 2D 打磚塊遊戲</a> — 以 JavaScript 遊戲函式庫建構 2D 遊戲的基本概念</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}</p>
diff --git a/files/zh-tw/learn/javascript/objects/object_prototypes/index.html b/files/zh-tw/learn/javascript/objects/object_prototypes/index.html
new file mode 100644
index 0000000000..9bfbc98fea
--- /dev/null
+++ b/files/zh-tw/learn/javascript/objects/object_prototypes/index.html
@@ -0,0 +1,236 @@
+---
+title: 物件原型
+slug: Learn/JavaScript/Objects/Object_prototypes
+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 的物件即透過原型 (Prototype) 機制相互繼承功能,且與典型的物件導向 (OO) 程式語言相較,其運作方式有所差異。我們將透過本文說明相異之處、解釋原型鍊 (Prototype chain) 運作的方式,並了解原型屬性是如何將函式新增至現有的建構子 (Constructor) 之中。</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>了解 JavaScript 的物件原型、原型鍊的運作方式、應如何將新的函式加入原型屬性之中。</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="「原型」架構的程式語言?">「原型」架構的程式語言?</h2>
+
+<p>常有人說 JavaScript 是<strong>原型架構的程式語言 </strong>— 各個物件均具備 1 組<strong>原型物件</strong>作為範本物件,用以繼承函式與屬性。物件的原型物件可能也具備原型物件,並繼承了其上的函式與屬性。這就是我們所謂的「<strong>原型鍊 (Prototype chain)</strong>」,同時正好說明為何 A 物件的屬性與函式是透過 B 物件的屬性與函式所定義。</p>
+
+<p>精確點說,這些屬性與函式都是透過物件的建構子函式所定義,並非物件實例本身。</p>
+
+<p>傳統的 OOP 都是先定義了類別,接著在建立物件實例之後,在類型上定義的所有屬性與函式均複製到此實例。但 JavaScript 不會複製這些屬性與函式,卻是在物件實例與其建構子之間設定連結 (原型鍊中的連結),只要順著原型鍊就能在建構子之中找到屬性與函式。</p>
+
+<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">原始碼</a>)。</p>
+
+<p>我們在此範例中定義了建構子函式:</p>
+
+<pre class="brush: js">function Person(first, last, age, gender, interests) {
+
+ // property and method definitions
+
+};</pre>
+
+<p>接著建立如下的物件實例:</p>
+
+<pre class="brush: js">var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);</pre>
+
+<p>如果你在自己的 JavaScript 主控台中鍵入「<code>person1.」,應該會看到瀏覽器根據此物件可用的成員名稱開始自動補完:</code></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="/en-US/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>person1 上呼叫了「實際上是定義於 Object 上的函式」,會發生什麼事呢?舉例來說:</code></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>注意:</strong>再次重申,在原型鍊中的函式與屬性並<strong>不是</strong>從任一物件複製到另一個物件,而是如上述的,沿著該原型鍊向上存取而得。</p>
+</div>
+
+<div class="note">
+<p><strong>注意:</strong>直接存取物件的原型物件,並沒有一定的方式。原型鍊中,項目之間的「連結」均定義於內部屬性之內,即 JavaScript 規格中的 <code>[[prototype]]</code> (可參閱 {{glossary("ECMAScript")}})。新版瀏覽器均具備所謂的「<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">__proto__</a></code> (兩邊都是 2 個底線)」屬性,其中就包含了物件的原型物件。舉例來說,你可嘗試「<code>person1.__proto__」</code>與「<code>person1.__proto__.__proto__</code>」看看程式碼中的鍊會是什麼樣子!</p>
+</div>
+
+<h2 id="原型屬性也定義所要繼承的成員">原型屬性也定義所要繼承的成員</h2>
+
+<p>所以該在哪裡定義所要繼承的屬性與函式呢?若看一下 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code> 參考頁面,你就會看到左邊列出許多屬性與函式,遠超過上方擷圖所列 <code>person1</code> 物件所繼承的成員數量。有些繼承了,有些則無?為什麼呢?</p>
+
+<p>原因在於,繼承的成員就是在 <code>prototype</code> 屬性 (你也能稱之為子命名空間 sub namespace) 中定義的成員,也就是以「<code>Object.prototype.」開頭的成員;並非只以「</code><code>Object.」開頭的成員。</code><code>prototype</code> 屬性值就是 1 個物件,基本上儲存了許多我們想「讓原型鍊上的物件一路繼承下去」的屬性與函式。</p>
+
+<p>所以如 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch">Object.prototype.watch()</a></code>、<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf">Object.prototype.valueOf()</a></code> 等等,均可用於繼承自 <code>Object()</code> 的任何物件類型,包含以建構子建立的新物件實例。</p>
+
+<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is">Object.is()</a></code>、<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></code>,及其他未於 <code>prototype</code> 內定義的成員,也就不會繼承至 1). 物件實例或 2). 從 <code>Object() 繼承而來的物件類型。</code>這些函式\屬性都只能用於 <code>Object()</code> 建構子本身。</p>
+
+<div class="note">
+<p><strong>注意:</strong>這看起來很奇怪:你怎麼能在建構子上定義函式 (Method),而且這建構子本身也是函式 (Function)?其實「Function」也屬於一個物件類型,可參閱 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function">Function()</a></code> 建構子參考以進一步了解。</p>
+</div>
+
+<ol>
+ <li>你可自行檢查現有的原型屬性。回到我們之前的範例,試著於 JavaScript 主控台中輸入:
+ <pre class="brush: js">Person.prototype</pre>
+ </li>
+ <li>輸出結果很平淡,畢竟我們並未在自定的建構子原型上定義任何東西。依預設值,建構子的 <code>prototype</code> 都是從空白開始。現在可嘗試下列:
+ <pre class="brush: js">Object.prototype</pre>
+ </li>
+</ol>
+
+<p>這樣就會看到 <code>Object</code> 的 <code>prototype</code> 屬性中所定義的許多函式,而繼承自 <code>Object</code> 的物件也能找到這些函式。</p>
+
+<p>只要試著尋找如 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code>、<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date</a></code>、<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number">Number</a></code>、<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code> 等全域物件的原型上定義的函式與屬性,就會看到 JavaScript 中的其他原型鍊繼承範例。這些物件都在其原型上定義了多個成員,因此可作為你建立字串時的範例:</p>
+
+<pre class="brush: js">var myString = 'This is my string.';</pre>
+
+<p><code>myString</code> 上立刻就有多個有用的函式,如 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">split()</a></code>、<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf">indexOf()</a></code>、<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace()</a></code> 等。</p>
+
+<div class="warning">
+<p><strong>重要:</strong><code>prototype</code> 這個屬性,是 JavaScript 中最讓人混淆的名稱之一。你可能會認為<code>this</code>屬性即指目前物件(current object)的原型物件(prototype object),但它其實不是原型 (應該是可透過 <code>__proto__</code> 存取的內部物件(internal object)才對,記得上面說過的嗎?)。<code>prototype</code>是一個物件(object),內含了你定義所應該繼承的成員。</p>
+</div>
+
+<h2 id="再次溫習_create()">再次溫習 create()</h2>
+
+<p>我們先前講過用 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create()</a></code> 函式建立新物件實例的方法。</p>
+
+<ol>
+ <li>舉例來說,你可先在前面的 JavaScript 主控台範例中試著輸入:
+ <pre class="brush: js">var person2 = Object.create(person1);</pre>
+ </li>
+ <li><code>create()</code> 實際上是透過特定的原型物件,來建立新的物件。我們在這裡將 <code>person1</code> 作為原型物件,建立了 <code>person2</code>。你可於主控台輸入下列以測試之:
+ <pre class="brush: js">person2.__proto__</pre>
+ </li>
+</ol>
+
+<p>如此將回傳 <code>person1</code> 物件。</p>
+
+<h2 id="建構子的屬性">建構子的屬性</h2>
+
+<p>每個物件實例都具備 1 個<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">建構子</a></code>屬性,指向「用以建立實例」的原始建構子函式。</p>
+
+<ol>
+ <li>舉例來說,若在主控台中輸入下列指令:
+ <pre class="brush: js">person1.constructor
+person2.constructor</pre>
+
+ <p>應該兩者都會回傳 <code>Person()</code> 建構子,因為此建構子包含這些實例的原始定義。</p>
+
+ <p>偷吃步的方法,是將圓括弧加到 <code>constructor</code> 屬性 (須包含任何必要參數) 末端,以從該建構子建立其他物件實例。畢竟建構子也是函式 (Function),所以可透過圓括弧將之觸發。你只要納入 <code>new</code> 這個關鍵字,即可將此函式作為建構子。</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="/en-US/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>
+
+<h2 id="修改原型">修改原型</h2>
+
+<p>先看看建構子的 <code>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> 範例,先在本機儲存 1 份<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">原始碼</a>的副本。在現成的 JavaScript 中加入下列程式碼,即是將新函式新增到建構子的 <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>這時應該會看到警示訊息且內含了建構子所定義的人名。這樣很有用,但如果能動態更新整個繼承鍊,且從建構子分割出來的所有物件實例都能使用此新的函式,就會更有用!</p>
+
+<p>花個 1 分鐘想想,我們的程式碼中定義了建構子,然後根據建構子建立實例物件,接著將新函式添增到建構子的原型:</p>
+
+<pre class="brush: js">function Person(first, last, age, gender, interests) {
+
+ // property and method definitions
+
+};
+
+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>但是 <code>farewell()</code> 函式仍可用於 <code>person1</code> 物件實例,其可用的功能已自動更新過。如此證明了我們之前對原型鍊的說明,也代表瀏覽器會沿著鍊往上找「尚未於物件實例上定義的函式」,而非「複製到實例中的函式」。如此可建構強大且靈活的系統。</p>
+
+<div class="note">
+<p><strong>注意:</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">即時運作</a>的情形)。</p>
+</div>
+
+<p>你很少會看到在 <code>prototype</code> 屬性上定義的屬性,因為照此範例定義的屬性彈性較低,舉例來說,你可新增如下的屬性:</p>
+
+<pre class="brush: js">Person.prototype.fullName = 'Bob Smith';</pre>
+
+<p>但因為幾乎不會有人取這名字,所以就沒什麼彈性。最好可以在 <code>name.first</code> 與 <code>name.last 之外建立 fullName:</code></p>
+
+<pre class="brush: js">Person.prototype.fullName = this.name.first + ' ' + this.name.last;</pre>
+
+<p>但因為這樣會參照全域範圍,而非函式範圍,所以也不適用。若呼叫此屬性,則將回傳 <code>undefined undefined</code>。這種模式適合我們先前於原型中定義的函式,因為該函式就是在功能範圍之內,且可成功轉移至物件實例的的範圍。因此你可能會在原型中定義常數屬性 (也就是永遠不需更改的屬性),但一般來說會比較適合在建構子中定義屬性。</p>
+
+<p>事實上,許多物件定義較常見的模式,就是在建構子中定義屬性,而在原型中定義函式。這樣一來,建構子只有屬性定義;函式則切分到不同的區塊,讓整個程式碼較清楚易讀。舉例來說:</p>
+
+<pre class="brush: js">// Constructor with property definitions
+
+function Test(a,b,c,d) {
+ // property definitions
+};
+
+// First method definition
+
+Test.prototype.x = function () { ... }
+
+// Second method definition
+
+Test.prototype.y = function () { ... }
+
+// etc.</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>本文說明了 JavaScript 物件原型,包含原型物件鍊是如何讓物件能互相繼承其特性、原型屬性的本質、原型屬性又是如何能將函式新增至建構子,以及其他相關概念。</p>
+
+<p>接著我們將讓你在自己的任 2 個自訂物件之間,實作功能的繼承。</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}</p>