diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
commit | 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 (patch) | |
tree | a9ef8ac1e1b8fe4207b6d64d3841bfb8990b6fd0 /files/zh-tw/learn/javascript/first_steps | |
parent | 074785cea106179cb3305637055ab0a009ca74f2 (diff) | |
download | translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.gz translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.bz2 translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.zip |
initial commit
Diffstat (limited to 'files/zh-tw/learn/javascript/first_steps')
10 files changed, 4011 insertions, 0 deletions
diff --git a/files/zh-tw/learn/javascript/first_steps/a_first_splash/index.html b/files/zh-tw/learn/javascript/first_steps/a_first_splash/index.html new file mode 100644 index 0000000000..38c7e4a4c4 --- /dev/null +++ b/files/zh-tw/learn/javascript/first_steps/a_first_splash/index.html @@ -0,0 +1,706 @@ +--- +title: 初次接觸Javascript +slug: Learn/JavaScript/First_steps/A_first_splash +translation_of: Learn/JavaScript/First_steps/A_first_splash +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/What_is_JavaScript", "Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps")}}</div> + +<p class="summary">目前你已經學會了一些JavaScript的理論,以及你能用它做些什麼。我們現在要透過一個完整的實際範例給你一個JavaScript基本功能的速成班。你將能一步一步地做出一個簡單的"猜數字"遊戲</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">先備知識:</th> + <td>基礎的電腦知識 , 有基礎的 HTML 跟 CSS 知識 ,<br> + 還有知道 JavaScript 是甚麼 .</td> + </tr> + <tr> + <th scope="row">目標:</th> + <td>獲得第一次寫 JavaScript 的經驗 ,<br> + 還有知道最基礎的 JavaScript 程式該怎麼寫 .</td> + </tr> + </tbody> +</table> + +<p>並不會要求你馬上就能仔細地了解所有程式碼 — 目前我們只是想介紹一些概觀,並向你介紹一些關於JavaScript(以及其他程式語言)如何運作的知識。在接下來的章節你將會更仔細地瞭解這些功能!</p> + +<div class="note"> +<p>Note: 你會在 JavaScript 看到許多跟其他程式語言一樣的特徵 — functions , loops 之類的 ,雖然程式語法看起來有差 ,但概念大部分都差不多 .</p> +</div> + +<h2 id="像程式工程師一樣思考">像程式工程師一樣思考</h2> + +<p>寫程式中最困難的事情之一,不是您需要學習的語法,而是如何應用它來解決現實世界中的問題。 您需要開始像個程式設計師一樣思考 — 這通常與檢視程式目標的說明有關,並確定實現這些功能所需的程式碼,以及如何使它們協同工作。</p> + +<p>這需要辛勤工作,程式語法經驗和練習 — 以及一點創造力。 你寫了越多程式碼,你就會越熟練。 我們不能保證你會在5分鐘內開發出“程式設計師的大腦”,但我們會給你很多機會在整個課程中練習"像程式設計師一樣思考"。</p> + +<p>考慮到這一點,讓我們看一下我們將在本文中構建的範例,並審視將其分解為具體任務的大致流程。</p> + +<h2 id="範例_—_猜數字遊戲">範例 — 猜數字遊戲</h2> + +<p>在本文中,我們將向您展示如何構建您可以在下面看到的簡單遊戲:</p> + +<div class="hidden"> +<h6 id="Top_hidden_code">Top hidden code</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title>Number guessing game</title> + <style> + html { + font-family: sans-serif; + } + + body { + width: 50%; + max-width: 800px; + min-width: 480px; + margin: 0 auto; + } + + .lastResult { + color: white; + padding: 3px; + } + </style> +</head> + +<body> + + <h1>Number guessing game</h1> + <p>We have selected a random number between 1 and 100. See if you can guess it in 10 turns or fewer. We'll tell you if your guess was too high or too low.</p> + <div class="form"> <label for="guessField">Enter a guess: </label><input type="text" id="guessField" class="guessField"> <input type="submit" value="Submit guess" class="guessSubmit"> </div> + <div class="resultParas"> + <p class="guesses"></p> + <p class="lastResult"></p> + <p class="lowOrHi"></p> + </div> + +<script> + // Your JavaScript goes here + let randomNumber = Math.floor(Math.random() * 100) + 1; + const guesses = document.querySelector('.guesses'); + const lastResult = document.querySelector('.lastResult'); + const lowOrHi = document.querySelector('.lowOrHi'); + const guessSubmit = document.querySelector('.guessSubmit'); + const guessField = document.querySelector('.guessField'); + let guessCount = 1; + let resetButton; + + function checkGuess() { + let userGuess = Number(guessField.value); + if (guessCount === 1) { + guesses.textContent = 'Previous guesses: '; + } + + guesses.textContent += userGuess + ' '; + + if (userGuess === randomNumber) { + lastResult.textContent = 'Congratulations! You got it right!'; + lastResult.style.backgroundColor = 'green'; + lowOrHi.textContent = ''; + setGameOver(); + } else if (guessCount === 10) { + lastResult.textContent = '!!!GAME OVER!!!'; + lowOrHi.textContent = ''; + setGameOver(); + } else { + lastResult.textContent = 'Wrong!'; + lastResult.style.backgroundColor = 'red'; + if(userGuess < randomNumber) { + lowOrHi.textContent='Last guess was too low!' ; + } else if(userGuess > randomNumber) { + lowOrHi.textContent = 'Last guess was too high!'; + } + } + + guessCount++; + guessField.value = ''; + } + + guessSubmit.addEventListener('click', checkGuess); + + function setGameOver() { + guessField.disabled = true; + guessSubmit.disabled = true; + resetButton = document.createElement('button'); + resetButton.textContent = 'Start new game'; + document.body.appendChild(resetButton); + resetButton.addEventListener('click', resetGame); + } + + function resetGame() { + guessCount = 1; + const resetParas = document.querySelectorAll('.resultParas p'); + for(let i = 0 ; i < resetParas.length ; i++) { + resetParas[i].textContent=''; + } + + resetButton.parentNode.removeChild(resetButton); + guessField.disabled = false; + guessSubmit.disabled = false; + guessField.value=''; + guessField.focus(); + lastResult.style.backgroundColor='white'; + randomNumber=Math.floor(Math.random() * 100) + 1; + } +</script> + +</body> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Top_hidden_code', '100%', 320, "", "", "hide-codepen-jsfiddle") }}</p> + +<p>好好玩一下遊戲再繼續吧 —— 在繼續前先與這個遊戲熟悉起來。</p> + +<p>讓我們假設你的老闆給了你以下關於創建這個遊戲的簡介:</p> + +<blockquote> +<p>我要你幫我做一個很簡單的猜數字遊戲 .<br> + 玩家要在 10 回合內猜中一個1到100之間的隨機數字 ,<br> + 每回合結束時都要告訴玩家他們猜對還是猜錯 ,<br> + 然後要是他們猜錯 , 要告訴他們數字猜的太小還是太大 ,<br> + 這個遊戲會在玩家猜對 , 或是猜超過 10 次時結束 ,<br> + 且遊戲結束時 , 要提供一個選項讓玩家可以再玩一次 .</p> +</blockquote> + +<p>當看到上面的介紹後,我們可以做的第一件事就是開始拆解,盡可能的像個程式設計師,將它拆解為簡單可執行的任務:</p> + +<ol> + <li>產生一個1到100間的隨機數字。</li> + <li>從一開始,紀錄玩家目前回合數。</li> + <li>提供玩家猜數字的方向(太大還是太小)。</li> + <li>當玩家送出第一個猜測後,將猜測記錄下來,讓玩家可以看到他們之前的猜測。</li> + <li>接著檢查數字是否猜中。</li> + <li>如果數字猜對: + <ol> + <li>顯示恭喜訊息。</li> + <li>使玩家不能再輸入更多猜測(避免把遊戲玩壞)。</li> + <li>顯示控制鈕讓玩家可以重新開始遊戲。</li> + </ol> + </li> + <li>如果數字猜錯而且玩家有剩餘回合數: + <ol> + <li>告訴玩家他猜錯了。</li> + <li>讓玩家輸入其他的猜測</li> + <li>回合數增加1。</li> + </ol> + </li> + <li>如果數字猜錯而且玩家沒有剩餘回合數: + <ol> + <li>告訴玩家遊戲結束。</li> + <li>使玩家不能再輸入更多猜測(避免把遊戲玩壞)。</li> + <li>顯示控制鈕讓玩家可以重新開始遊戲。</li> + </ol> + </li> + <li>當遊戲重新開始,確保遊戲邏輯和畫面(UI,使用這介面)全面重設,然後回到第一步。</li> +</ol> + +<p>現在,讓我們繼續向前,一路上我們檢視如何將這些步驟轉化為程式碼、建構出上面的範例與探索JavaScript的功能。</p> + +<h3 id="初步設定">初步設定</h3> + +<p>在課程開始前,我們希望你可以複製一份<a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/first-splash/number-guessing-game-start.html">number-guessing-game-start.html</a>到自己的電腦中(<a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/first-splash/number-guessing-game-start.html">see it live here</a>)。用瀏覽器與文字編輯器將檔案打開時,你會看到簡單的標題、說明段落還有輸入猜測的表單,然而表單目前還不會做任何事情。</p> + +<p>所有的程式碼都會放入置於HTML底部的{{htmlelement("script")}}元素裡:</p> + +<pre class="brush: html notranslate"><script> + + // Your JavaScript goes here + +</script> +</pre> + +<h3 id="加入變數儲存我們的資料">加入變數儲存我們的資料</h3> + +<p>我們一起開始吧。首先,在你的{{htmlelement("script")}} 元素裡加入以下幾行:</p> + +<pre class="brush: js notranslate">let randomNumber = Math.floor(Math.random() * 100) + 1; + +const guesses = document.querySelector('.guesses'); +const lastResult = document.querySelector('.lastResult'); +const lowOrHi = document.querySelector('.lowOrHi'); + +const guessSubmit = document.querySelector('.guessSubmit'); +const guessField = document.querySelector('.guessField'); + +let guessCount = 1; +let resetButton;</pre> + +<p>這一區塊的程式碼設定我們的程式中用來儲存資料的變數。簡單的來說,「變數」是「值」的容器(值可以是數字、一串文字或是其他東西)。你可以用「關鍵字」(keyword) <code>let</code>(或是<code>var</code>)後面加上變數的名字來建立變數(在<a href="https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/First_steps/Variables#The_difference_between_var_and_let">之後的文章</a>你會看到兩者的差別)。利用關鍵字 <code>const</code> 建立常數,常數(Constant)是用來儲存你不會更改的值。我們用常數儲存使用者介面的參照,使用者介面中的文字可能會改變,但是參照所指的HTML元素的不會改變。</p> + +<p>藉由等於符號(<code>=</code>)後面加上一個值,你可以指定變數或是常數的值。</p> + +<p>在我們的範例中:</p> + +<ul> + <li>第一個變數 — <code>randomNumber</code> — 被指定成一個由數學運算的1到100間的隨機數字</li> + <li>接著的三個常數,分別儲存HTML中結果段落的參照,在後面的程式碼中,參照被用來插入一些數值 (注意他們都位於一個{{htmlelement("div")}}元素裡,後者在之後我們重置遊戲時會被用來選取所有三個{{htmlelement("p")}}元素): + <pre class="brush: html notranslate"><div class="resultParas"> + <p class="guesses"></p> + <p class="lastResult"></p> + <p class="lowOrHi"></p> +</div> +</pre> + </li> + <li>接著的兩個常數,分別儲存表單中的文字輸入和送出按鈕,之後會用來控制送出玩家猜測的數字。 + <pre class="brush: html notranslate"><label for="guessField">Enter a guess: </label><input type="text" id="guessField" class="guessField"> +<input type="submit" value="Submit guess" class="guessSubmit"></pre> + </li> + <li>最後兩個變數,一個儲存回合數1,另一個儲存指向重新開始按鈕的參照 (按鈕現在還不存在,之後會加上的)。</li> +</ul> + +<div class="note"> +<p><strong>Note</strong>: 從<a href="https://developer.mozilla.org/en-US/docs/user:chrisdavidmills/variables">下一篇文章</a>開始,你會學到更多有關變數的事。</p> +</div> + +<h3 id="函式">函式</h3> + +<p>下一步,將下面這段添加到之前寫的那段程式碼:</p> + +<pre class="brush: js notranslate">function checkGuess() { + alert('I am a placeholder'); +}</pre> + +<p>函式是一段可重複利用的程式碼塊。建立一個函式便可以反複運行並避免撰寫重複的程式碼。定義函式有很多方法,在此我們先專注在一種簡單的方式。這裡我們以關鍵字 <code>function</code> 、自訂的函式名、一對括號以及一對花括號(<code>{ }</code>)建立函式。花括號中的程式碼便是我們調用函式時所要實際執行的程式碼。</p> + +<p>輸入函式名稱與括號便可以執行函式。</p> + +<p>讓我們來試試吧。儲存你的程式碼並重新整理瀏覽器畫面。進入 <a href="/zh-TW/docs/Learn/Common_questions/What_are_browser_developer_tools">開發者工具 JavaScript console</a>, 並輸入下面這行:</p> + +<pre class="brush: js notranslate">checkGuess();</pre> + +<p> 當按下 <kbd>Return</kbd>/<kbd>Enter</kbd> 時,你會看到一個警告跳窗顯示「I am a placeholder」。我們已經在程式中定義好一個函式,只要我們調用這個函式,函式便會彈出一個警告視窗。</p> + +<div class="note"> +<p><strong>Note</strong>: 你會在後續的課程中學習到更多關於函式的事。</p> +</div> + +<h3 id="運算子">運算子</h3> + +<p>JavaScript 運算子可以讓我們執行比較、數學運算、連接字符串等。</p> + +<p>儲存我們的程式碼並重整頁面,開啟 <a href="/zh-TW/docs/Learn/Common_questions/What_are_browser_developer_tools">開發者工具 JavaScript console</a> 。接下來你可以試著輸入以下的範例 —— 輸入跟每個「範例」欄位中一樣的內容,每輸入一個就按下<kbd>Return</kbd> / <kbd>Enter</kbd>, 接著看看回傳的結果。</p> + +<p>如果你不能快速打開瀏覽器開發工具, 你可以使用内嵌的應用程式中輸入以下範例:</p> + +<div class="hidden"> +<h6 id="Hidden_code">Hidden code</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>JavaScript console</title> + <style> + * { + box-sizing: border-box; + } + + html { + background-color: #0C323D; + color: #809089; + font-family: monospace; + } + + body { + max-width: 700px; + } + + p { + margin: 0; + width: 1%; + padding: 0 1%; + font-size: 16px; + line-height: 1.5; + float: left; + } + + .input p { + margin-right: 1%; + } + + .output p { + width: 100%; + } + + .input input { + width: 96%; + float: left; + border: none; + font-size: 16px; + line-height: 1.5; + font-family: monospace; + padding: 0; + background: #0C323D; + color: #809089; + } + + div { + clear: both; + } + + </style> + </head> + <body> + + + </body> + + <script> + var geval = eval; + + function createInput() { + var inputDiv = document.createElement('div'); + var inputPara = document.createElement('p'); + var inputForm = document.createElement('input'); + + inputDiv.setAttribute('class','input'); + inputPara.textContent = '>'; + inputDiv.appendChild(inputPara); + inputDiv.appendChild(inputForm); + document.body.appendChild(inputDiv); + inputDiv.focus(); + + if(document.querySelectorAll('div').length > 1) { + inputForm.focus(); + } + + inputForm.addEventListener('change', executeCode); + } + + function executeCode(e) { + try { + var result = geval(e.target.value); + } catch(e) { + var result = 'error — ' + e.message; + } + + var outputDiv = document.createElement('div'); + var outputPara = document.createElement('p'); + + outputDiv.setAttribute('class','output'); + outputPara.textContent = 'Result: ' + result; + outputDiv.appendChild(outputPara); + document.body.appendChild(outputDiv); + + e.target.disabled = true; + e.target.parentNode.style.opacity = '0.5'; + + createInput() + } + + createInput(); + + </script> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}</p> + +<p>首先讓我們看看以下的算數運算子:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">運算子</th> + <th scope="col">名稱</th> + <th scope="col">範例</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>+</code></td> + <td>加法</td> + <td><code>6 + 9</code></td> + </tr> + <tr> + <td><code>-</code></td> + <td>減法</td> + <td><code>20 - 15</code></td> + </tr> + <tr> + <td><code>*</code></td> + <td>乘法</td> + <td><code>3 * 7</code></td> + </tr> + <tr> + <td><code>/</code></td> + <td>除法</td> + <td><code>10 / 5</code></td> + </tr> + </tbody> +</table> + +<p>你也可以使用 <code>+</code> 來連接字串 (在程式設計中,這稱爲<strong>連接</strong>)。試著輸入以下幾行程式,每次一行:</p> + +<pre class="brush: js notranslate">var name = 'Bingo'; +name; +var hello = ' says hello!'; +hello; +var greeting = name + hello; +greeting;</pre> + +<p>你也可以使用一些捷徑,這些被稱爲增量賦值運算子。如果你只是簡單想將兩個字串加在一起,你可以這樣做:</p> + +<pre class="brush: js notranslate">name += ' says hello!';</pre> + +<p>相當於</p> + +<pre class="brush: js notranslate">name = name + ' says hello!';</pre> + +<p>當我們進行真假值測試時 (例如{{anch("條件", "下面")}}),我們可以使用比較運算子,如:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">運算子</th> + <th scope="col">名稱</th> + <th scope="col">範例</th> + </tr> + <tr> + <td><code>===</code></td> + <td>嚴格等於 (是否完全一樣?)</td> + <td><code>5 === 2 + 4</code></td> + </tr> + <tr> + <td><code>!==</code></td> + <td>不等於 (是否不一樣?)</td> + <td><code>'Chris' !== 'Ch' + 'ris'</code></td> + </tr> + <tr> + <td><code><</code></td> + <td>小於</td> + <td><code>10 < 6</code></td> + </tr> + <tr> + <td><code>></code></td> + <td>大於</td> + <td><code>10 > 20</code></td> + </tr> + </thead> +</table> + +<h3 id="條件">條件</h3> + +<p>回到 <code>checkGuess()</code> 函式,我們希望的結果當然不只是彈出簡單訊息而已。我們更想要知道這個函式將如何檢查玩家的猜測是否準確,並回傳正確的結果。</p> + +<p>所以現在將 <code>checkGuess()</code> 函式替換成下面這個版本:</p> + +<pre class="brush: js notranslate">function checkGuess() { + var userGuess = Number(guessField.value); + if (guessCount === 1) { + guesses.textContent = 'Previous guesses: '; + } + guesses.textContent += userGuess + ' '; + + if (userGuess === randomNumber) { + lastResult.textContent = 'Congratulations! You got it right!'; + lastResult.style.backgroundColor = 'green'; + lowOrHi.textContent = ''; + setGameOver(); + } else if (guessCount === 10) { + lastResult.textContent = '!!!GAME OVER!!!'; + setGameOver(); + } else { + lastResult.textContent = 'Wrong!'; + lastResult.style.backgroundColor = 'red'; + if(userGuess < randomNumber) { + lowOrHi.textContent = 'Last guess was too low!'; + } else if(userGuess > randomNumber) { + lowOrHi.textContent = 'Last guess was too high!'; + } + } + + guessCount++; + guessField.value = ''; + guessField.focus(); +}</pre> + +<p>哇,突然出現了很多程式碼!我們來完整地看一遍這些程式並介紹它們是如何運行的。</p> + +<ul> + <li>第一行(上面的第2行)宣告一個名為 <code>userGuess</code> 的變數,並將其值設置為在表單中文字輸入格內的當前值。我們還通過內建的 <code>Number()</code> 方法運行此值,以確保該值絕對是一個數字。</li> + <li>接下來,我們遇到第一個條件程式碼區塊(上面的第3-5行)。條件程式碼區塊允許您能基於某個條件是否為真來選擇性地執行程式碼。它看起來有點像函式,但其實並非如此。最簡單的條件區塊格式從 <code>if</code> 關鍵字開始,然後是一些括號,然後是一些花括號。在括號內包含一個比較測試。如果括號內的比較測試回傳 <code>true</code>,花括號內的程式碼則會被執行;否則不會執行,而會繼續執行接下來的程式碼。在這個情況下,我們的比較測試是檢查 <code>guessCount</code> 變數是否等於 <code>1</code>(即,這是否為玩家的第一次嘗試): + <pre class="notranslate"><code>guessCount === 1</code></pre> + 如果是,我們將 <code>guesses</code> 段落的文字內容設為 “Previous guesses: ”。</li> + <li>第6行將當前 <code>userGuess</code> 的值附加到 <code>guesses</code> 段落的尾端,並加上一個空格,讓顯示的每次猜測紀錄之間都有一個空格。</li> + <li>下一個條件區塊(上面第8-24行)做了一些檢查: + <ul> + <li>第一個 <code>if(){ }</code> 檢查用戶的猜測是否等於<code>我們</code>JavaScript頂部設置的 <code>randomNumber</code>。如果是,代表玩家猜對了,贏了遊戲,所以我們向玩家顯示一個漂亮的綠色祝賀訊息,清除 <code>lowOrHigh</code> 段落的內容,並運行一個叫做 <code>setGameOver()</code> 的函式,這個函式我們稍後再討論。</li> + <li>現在我們使用 <code>else if(){ }</code> 區塊將另一個測試連接到上一個測試的後面。這個測試檢查本次猜測是否為玩家的最後一次猜測機會。如果是,則執行與上一個條件區塊相同的操作,只是這次是遊戲結束訊息,漂亮的綠色祝賀訊息。</li> + <li>連接到此條件區塊後面的最後一個區塊(<code>else { }</code>)只會在其他兩個測試都沒有返回 <code>true</code> 時執行(即,玩家沒有猜對,但他們還有更多的猜測機會)。在這種情況下,我們告訴他們猜錯了,然後我們執行另一個條件測試以檢查猜測是高於還是低於正確答案 <code>randomNumber</code>,並顯示進一步的訊息來告訴他們要猜得更高或更低。</li> + </ul> + </li> + <li>函式中的最後三行(上面的第26-28行)讓玩家可以提交下一個猜測。我們將<code>guessCount</code>變數加1,來增加玩家已使用的猜測次數(<code>++</code>是遞增操作 - 遞增1),並將表單中文字輸入格內的文字清空並給予其焦點(顯示文字輸入游標),準備好讓玩家輸入下一個猜測。</li> +</ul> + +<h3 id="事件">事件</h3> + +<p>現在我們有了一個很好的 <code>checkGuess()</code> 函式,但它並不會做任何事情,因為我們還沒有呼叫它。我們想在按下 “Submit guess” 按鈕時呼叫它,為此,我們需要使用<strong>事件</strong>。事件是在瀏覽器中發生的操作,例如單擊按鈕,加載頁面或播放影片,以讓我們可以在這些操作發生時執行程式碼。偵聽事件發生的構造稱為<strong>事件偵聽器</strong>,偵聽事件而觸發執行的程式碼稱為<strong>事件處理器</strong>。</p> + +<p>在 <code>checkGuess()</code> 函式下面添加下行(不是指函式內部的後面,而是函式外):</p> + +<pre class="brush: js notranslate">guessSubmit.addEventListener('click', checkGuess);</pre> + +<p>這裡我們為 <code>guessSubmit</code> 按鈕添加一個事件偵聽器。這是一個函式,它接受兩個輸入值(稱為<em>參數</em>) - 我們正在監聽的事件類型字串(本例中的 <code>click</code>),以及我們想要在事件發生時運行的程式碼(在這種情況下是<code>checkGuess()</code>函式) — 請注意,在編寫 <a href="https://developer.mozilla.org/zh-TW/docs/Web/API/EventTarget/addEventListener" title="EventTarget.addEventListener() 方法能將指定的事件監聽器註冊到 EventTarget 實作物件上。EventTarget 可能是 Document 中的 Element 物件、Document 物件本身、Window 物件,或是其它支援事件的物件(如:XMLHttpRequest)。"><code>addEventListener()</code></a> 內部時我們不需要為函式加上括號。</p> + +<p>現在保存並重整頁面,現在你的範例應該可以正常執行了。現在唯一的問題是,如果你猜對了正確的答案或用完了猜測機會,那麼遊戲就會出錯,因為我們還沒有定義 <code>setGameOver()</code> — 遊戲結束後應該執行的函式。現在讓我們加上缺少的程式碼並完成範例功能。</p> + +<h3 id="完成遊戲功能">完成遊戲功能</h3> + +<p>讓我們加入 <code>setGameOver()</code> 這個函式到我們程式碼的底部並演練它。 現在,在你的 JavaScript 尾端加上這些:</p> + +<pre class="brush: js notranslate">function setGameOver() { + guessField.disabled = true; + guessSubmit.disabled = true; + resetButton = document.createElement('button'); + resetButton.textContent = 'Start new game'; + document.body.appendChild(resetButton); + resetButton.addEventListener('click', resetGame); +}</pre> + +<ul> + <li>函數中的前兩行透過將表單的文字輸入和按鈕的 <code>disabled</code> 屬性設為 <code>true</code> 來將兩者無效化。這很重要,因為如果沒有這麼做,使用者可能會在遊戲結束後繼續送出更多猜測值,這也許會把東西弄得一團糟。</li> + <li>接下來的三行會生成一個新的 {{htmlelement("button")}} 元素,將它的文字標籤設為「Start new game」後,添加到我們的HTML的最尾端。</li> + <li>最後一行則會在我們的新按鈕上設置一個事件偵聽器,來讓使用者按下按鈕時執行一個叫 <code>resetGame()</code> 的函數。</li> +</ul> + +<p>現在讓我們來定義 <code>resetGame()</code>!再次將下面這些程式碼加進你的 JavaScript 的最下方。</p> + +<pre class="brush: js notranslate">function resetGame() { + guessCount = 1; + + var resetParas = document.querySelectorAll('.resultParas p'); + for (var i = 0 ; i < resetParas.length ; i++) { + resetParas[i].textContent = ''; + } + + resetButton.parentNode.removeChild(resetButton); + + guessField.disabled = false; + guessSubmit.disabled = false; + guessField.value = ''; + guessField.focus(); + + lastResult.style.backgroundColor = 'white'; + + randomNumber = Math.floor(Math.random() * 100) + 1; +}</pre> + +<p>這段相對較常的程式碼會完全將所有東西重置到遊戲的初始狀態,讓玩家可以再玩一次。這段程式碼做了下面這些事:</p> + +<ul> + <li>將 <code>guessCount</code> 設回 1。</li> + <li>清除所有訊息段落。</li> + <li>將重置按鈕移除。</li> + <li>將表單元素有效化,清空文字輸入並給予其焦點,準備好讓玩家能夠進行新一輪的猜測。</li> + <li><code>將lastResult</code> 段落的背景顏色設回白色。</li> + <li>生成一個新的隨機數值,才不會讓玩家又猜一次重複的答案!</li> +</ul> + +<p><strong>現在,你應該有了一個完整且能正常執行的簡單遊戲了 — 恭喜你啦!</strong></p> + +<p>接下來這篇文章的工作只剩下來談談其他幾個很重要的程式功能,你應該已經看過了,只是還沒察覺罷了。</p> + +<h3 id="迴圈">迴圈</h3> + +<p>上面的程式碼中,一個我們需要仔細看看的部份是 <a href="/zh-TW/docs/Web/JavaScript/Reference/Statements/for">for</a> 迴圈。迴圈在程式設計中是一個非常重要的內容,可以讓你在滿足條件前反覆執行同一段程式碼。</p> + +<p>開始吧,打開你的 <a href="/zh-TW/docs/Learn/Common_questions/What_are_browser_developer_tools">開發者工具 JavaScript console</a>,然後輸入下面這行:</p> + +<pre class="brush: js notranslate">for (var i = 1 ; i < 21 ; i++) { console.log(i) }</pre> + +<p>看見了嗎?在你的主控台內印出了數字 1到 20。這就是迴圈的效果。一個 for 迴圈需要三個參數:</p> + +<ol> + <li><strong>起始動作:</strong>這個例子中我們從 1 開始累加,這個起始數值可以是任何你想要的值。你也可以不要使用 <code>i</code> 這個變數名稱,但習慣上我們會使用 <code>i</code> ,因為它簡單好記。 </li> + <li><strong>離開條件:</strong>這裡我們指定了 <code>i < 21</code> — 這個迴圈會一直執行直到 <code>i</code> 不再小於 21。當 <code>i</code> 達到 21,這個迴圈就會停止執行。</li> + <li><strong>增加動作:</strong>我們指定了 <code>i++</code>,「將 <code>i</code> 的值加 1」。這個迴圈會對每個 <code>i</code> 的值執行一次,直到 <code>i</code> 達到 21(如上一條所述)。這個例子中,我們簡單的透過 {{domxref("Console.log", "console.log()")}} 將每次迴圈中 <code>i</code> 的值輸出到主控台中。</li> +</ol> + +<p>現在我們來看看在猜謎遊戲中的迴圈 — 這可以在 <code>resetGame()</code> 函式中找到:</p> + +<pre class="brush: js notranslate">var resetParas = document.querySelectorAll('.resultParas p'); +for (var i = 0 ; i < resetParas.length ; i++) { + resetParas[i].textContent = ''; +}</pre> + +<p>這段程式碼透過呼叫 {{domxref("Document.querySelectorAll", "querySelectorAll()")}} 創建一個變數並存著一個在 <code><div class="resultParas"></code> 中的所有段落清單,然後使用迴圈來遍歷每個段落元素,並移除其內容。</p> + +<h3 id="稍微討論一下物件">稍微討論一下物件</h3> + +<p>在開始討論這個段落的話題前,先來做點小小修改。在你的 JavaScript 接近頂部的 <code>var resetButton</code> 下一行加上:</p> + +<pre class="brush: js notranslate">guessField.focus();</pre> + +<p>,然後存檔。</p> + +<p>這一行呼叫了 {{domxref("HTMLElement.focus", "focus()")}} 方法來在頁面讀取時,將輸入游標自動放進 {{htmlelement("input")}} 文字欄裡面,這意味著使用者在開啟頁面後就可以直接使用鍵盤來在文字欄內輸入文字,而不用先點選文字欄。這只是個小修改,可是大大的提升了使用體驗,也給了使用者清楚的提示 — 提示他們要做些什麼來遊玩這個遊戲。</p> + +<p>讓我們來分析一下究竟發生了什麼事。在JavaScript中,所有東西都是一個<strong>物件</strong>。物件是一個集合,由許多相關的功能打包成一體。你可以創建一個你自己的物件,不過這比較進階,我們現在並不會涵蓋這個內容,這些會在課程的後期提到。現在,我們只會簡要的提到一些你的瀏覽器內建的物件,他們能夠讓你做到許多有用的事。</p> + +<p>在這個例子中,我們首先創建了一個 <code>guessField</code> 變數,儲存著一個指向HTML表單中文字輸入欄的參照 — 這可以在我們定義變數的區塊中找到:</p> + +<pre class="brush: js notranslate">var guessField = document.querySelector('.guessField');</pre> + +<p>我們使用了 {{domxref("document.querySelector", "querySelector()")}} 來取得這個參照,前者是 {{domxref("document")}} 物件的方法。<code>querySelector()</code> 接受一個參數 — 一個 <a href="/zh-TW/docs/Learn/CSS/Introduction_to_CSS/Selectors">CSS 選擇器</a>, 會回傳你想要的元素參照。</p> + +<p>因為現在 <code>guessField</code> 中存著一個指向 {{htmlelement("input")}} 元素的參照,它現在可以存取這個元素的屬性(基本上就是存在物件中的變數,其中有一些可能會是常數)和方法(基本上就是存在物件中的函式)了。文字輸入欄的其中一個方法便是 <code>focus()</code>,我們便可以透過呼叫這個方法來給予其焦點:</p> + +<pre class="brush: js notranslate">guessField.focus();</pre> + +<p>沒有存著表單元素參照的變數就不會有 <code>focus()</code> 方法能使用。<br> + 例如存著一個 {{htmlelement("p")}} 元素的 <code>guesses</code> 和存著一個數值的 <code>guessCount</code>。</p> + +<h3 id="來玩玩瀏覽器物件">來玩玩瀏覽器物件</h3> + +<p>讓我們來稍微玩一點瀏覽器內建的物件吧。</p> + +<ol> + <li>首先在瀏覽器中開啟你的程式。</li> + <li>接下來,打開你的<a href="/zh-TW/docs/Learn/Common_questions/What_are_browser_developer_tools">開發者工具 JavaScript console</a>。</li> + <li>輸入 <code>guessField</code>,可以看到主控台顯示這個變數儲存著一個 {{htmlelement("input")}} 元素。你還可以發現主控台會自動幫你完成已存在的物件名稱!</li> + <li>接下來輸入: + <pre class="brush: js notranslate">guessField.value = 'Hello';</pre> + <code>value</code> 屬性儲存著現在文字輸入欄內的內容參照。現在按下 <kbd>Enter</kbd>,看看文字欄內的內容是不是變了?</li> + <li>試著輸入 <code>guesses</code> 然後按下 <kbd>Enter</kbd>,主控台會顯示這個變數儲存著一個 {{htmlelement("p")}} 元素。</li> + <li>現在輸入: + <pre class="brush: js notranslate">guesses.value</pre> + 瀏覽器會回傳 <code>undefined</code>,因為 <code>value</code> 不存在在段落元素裡面。</li> + <li>要更改段落元素中的文字,你需要的是 {{domxref("Node.textContent", "textContent")}} 屬性。試試這個: + <pre class="brush: js notranslate">guesses.textContent = 'Where is my paragraph?';</pre> + </li> + <li>現在來做些好玩的事。一行一行輸入並 <kbd>Enter</kbd>: + <pre class="brush: js notranslate">guesses.style.backgroundColor = 'yellow'; +guesses.style.fontSize = '200%'; +guesses.style.padding = '10px'; +guesses.style.boxShadow = '3px 3px 6px black';</pre> + 每個在頁面上的元素都有一個 <code>style</code> 屬性,其本身又是另一個物件,包含著許多該元素的行內 CSS 屬性。這讓我們能透過 JavaScript 來動態的為元素設置 CSS 屬性。</li> +</ol> + +<h2 id="差不多就到這了">差不多就到這了</h2> + +<p>這就是我們的範例 — 你順利地來到結尾了,做得不錯!試試你的最終成品,或試試<a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/first-splash/number-guessing-game.html">我們的版本</a>。如果你仍然有困難沒有解決,再看看<a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/first-splash/number-guessing-game.html">我們的原始碼</a>。</p> + +<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/What_is_JavaScript", "Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps")}}</p> + +<h2 id="在這個學習模組中">在這個學習模組中</h2> + +<ul> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_is_JavaScript">什麼是 JavaScript?</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/A_first_splash">和 JavaScript 的第一次接觸</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_went_wrong">什麼出錯了? JavaScript 的疑難排解(除錯)</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Variables">儲存你需要的資訊 — 變數</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Math">JavaScript 的基本運算— 數字 與 運算子</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Strings">處理文字 — JavaScript 的字串</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Useful_string_methods">有用的字串方法</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Arrays">陣列</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Silly_story_generator">附錄:笑話產生器</a></li> +</ul> diff --git a/files/zh-tw/learn/javascript/first_steps/arrays/index.html b/files/zh-tw/learn/javascript/first_steps/arrays/index.html new file mode 100644 index 0000000000..895183b811 --- /dev/null +++ b/files/zh-tw/learn/javascript/first_steps/arrays/index.html @@ -0,0 +1,571 @@ +--- +title: Arrays +slug: Learn/JavaScript/First_steps/Arrays +translation_of: Learn/JavaScript/First_steps/Arrays +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps/Silly_story_generator", "Learn/JavaScript/First_steps")}}</div> + +<p class="summary">在本單元的最後一篇文章中,我們將介紹陣列——一種在單個變數名下儲存資料項列表的簡潔方法。在這裡,我們看看為什麼這很有用,然後探討如何建立陣列,檢索、增加和刪除儲存在陣列中的項目等等。</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">先備知識:</th> + <td>基本計算機知識、基本理解 HTML 與 CSS、知道 JavaScript 是什麼。</td> + </tr> + <tr> + <th scope="row">目標:</th> + <td>理解何謂陣列並在 JavaScript 操作之。</td> + </tr> + </tbody> +</table> + +<h2 id="什麼是陣列?">什麼是陣列?</h2> + +<p>陣列通常描述為「像列表的物件」:也就是一個列表物件,裡面含有幾個數值。陣列物件能放在變數裡面,處理方式也與資料型別大致相同。不過主要差異為,陣列可以獨立存取、並高效處理裡面的數值:像是利用迴圈,對每個數值作相同處理。例如我們的陣列是一組有項目和價格的產品、我們可以用迴圈把單價印在發票上、最後在發票底下印出合計。</p> + +<p>不用陣列的話,就會需要註冊、並單獨呼叫很多獨立變數。這樣會花更多時間寫程式、效率更低、還更容易寫錯。只有十個的話還好解決,但如果有一百個,甚至一千個呢?我們會在接下來闡述之。</p> + +<p>與前幾篇文章一樣,讓我們在 JavaScript 控制台中輸入一些示例,來了解陣列的基礎知識吧。</p> + +<h3 id="建立陣列">建立陣列</h3> + +<p>陣列用方括弧包起來,每個單位會用逗號分隔起來。</p> + +<ol> + <li>來作一個購物清單的陣列吧:我們會做類似下面的事情。在主控台中輸入以下程式: + <pre class="brush: js notranslate">var shopping = ['bread', 'milk', 'cheese', 'hummus', 'noodles']; +shopping;</pre> + </li> + <li>在此,陣列的每個單位都是字串。但請記住,陣列可以儲存任何單位:字串、數字、物件、另一個變數、甚至是另一個陣列。也可以混合單位的型別:它們不一定都要是數字或字串。來試試這個: + <pre class="brush: js notranslate">var sequence = [1, 1, 2, 3, 5, 8, 13]; +var random = ['tree', 795, [0, 1, 2]];</pre> + </li> + <li>看下去之前,試著自己作幾個陣列。</li> +</ol> + +<h3 id="存取並修改陣列的單位">存取並修改陣列的單位</h3> + +<p>你可以使用括號標記法存取個別單位,同時也可以<a href="/en-US/Learn/JavaScript/First_steps/Useful_string_methods#Retrieving_a_specific_string_character">存取字串中的字母</a>。</p> + +<ol> + <li>在主控台輸入以下程式: + <pre class="brush: js notranslate">shopping[0]; +// returns "bread"</pre> + </li> + <li>也可以透過賦予陣列新數值修改該單位。試試這個: + <pre class="brush: js notranslate">shopping[0] = 'tahini'; +shopping; +// shopping 回傳 [ "tahini", "milk", "cheese", "hummus", "noodles" ]</pre> + + <div class="note"><strong>注:</strong>前面有說過,但還是提醒下:電腦從 0 開始數!</div> + </li> + <li>請注意,陣列裡面的陣列稱為多維陣列(multidimensional array)。你可以撰寫兩組方括弧,來存取陣列裡面的陣列單位。例如說,存取前述 <code>random</code> 變數內的陣列單位就可以這麼寫: + <pre class="brush: js notranslate">random[2][2];</pre> + </li> + <li>看下去之前,試著進一步使用並修改陣列。</li> +</ol> + +<h3 id="找出陣列長度">找出陣列長度</h3> + +<p>找出陣列長度(意即有幾個單位在陣列內)的方法,跟找出字串長度(含有幾個字元)的方式一樣——都是使用 {{jsxref("Array.prototype.length","length")}} 屬性。試試下方程式行:</p> + +<pre class="brush: js notranslate">shopping.length; +// should return 5</pre> + +<p>這還有其他用途,但最常見的用法是讓迴圈一直循環直到所有的單元都走過一次。 舉個例子:</p> + +<pre class="brush: js notranslate">var sequence = [1, 1, 2, 3, 5, 8, 13]; +for (var i = 0; i < sequence.length; i++) { + console.log(sequence[i]); +}</pre> + +<p>在後續的章節,你會學到更多關於迴圈的部分;簡而言之,上述程式碼的意思是:</p> + +<ol> + <li>從陣列中索引為 0 的單元開始循環。</li> + <li>當索引值等於陣列的長度時,停止循環。這個方法對任何長度的陣列都可行,但在這個例子中,迴圈會當索引等於 7 時停止循環(這樣很好,因為最後一個單元——我們希望有包含到的——是6)。</li> + <li>我們在瀏覽器 console 中用 <code><a href="/en-US/docs/Web/API/Console/log">console.log()</a></code> 將每個單元列印出來。</li> +</ol> + +<h2 id="好用的陣列方法">好用的陣列方法</h2> + +<p>在這個小節中,我們會介紹一些相當有用、有關陣列的方法。例如將字串拆分為陣列,反之亦然,以及增加新的單位到陣列中。</p> + +<h3 id="在字串與陣列之間轉換">在字串與陣列之間轉換</h3> + +<p>通常你會看到一組含有原始資料的長字串,而你可能會希望將有用的單元拆分、組成更好用的形式,對他進行操作。為了達成這個目的,我們可以使用 {{jsxref("String.prototype.split()","split()")}} 方法。它最簡單的形式是只使用一個參數,你想分離的字串位置的字元(分隔符),而後它會返回陣列中在分隔符之間的子字串。</p> + +<div class="note"> +<p><strong>Note</strong>: 好的,在技術上它屬於字串的方法,而非陣列的方法。但因為它可以很順利地對陣列進行操作,因此我們把它列在這邊。</p> +</div> + +<ol> + <li>來試試這個,看它如何運作。首先,建立一個字串在你的 console: + <pre class="brush: js notranslate">var myData = 'Manchester,London,Liverpool,Birmingham,Leeds,Carlisle';</pre> + </li> + <li>現在我們用逗點來分隔字串: + <pre class="brush: js notranslate">var myArray = myData.split(','); +myArray;</pre> + </li> + <li>最後,試著找出你新的陣列的長度,並且從中取出一些單元: + <pre class="brush: js notranslate">myArray.length; +myArray[0]; // the first item in the array +myArray[1]; // the second item in the array +myArray[myArray.length-1]; // the last item in the array</pre> + </li> + <li>相對地,你也可以用 {{jsxref("Array.prototype.join()","join()")}} 方法。試試下面這段: + <pre class="brush: js notranslate">var myNewString = myArray.join(','); +myNewString;</pre> + </li> + <li>另一個將陣列轉換為字串的方法是用 {{jsxref("Array.prototype.toString()","toString()")}} 。<code>toString()</code> 因為不需要參數而比 <code>join()</code> 更簡潔,但因此也更多限制。使用 <code>join()</code> 你可以使用特定的分隔符(試著使用其他不同的字元來執行步驟 4)。 + <pre class="brush: js notranslate">var dogNames = ['Rocket','Flash','Bella','Slugger']; +dogNames.toString(); //Rocket,Flash,Bella,Slugger</pre> + </li> +</ol> + +<h3 id="新增與移除陣列單位">新增與移除陣列單位</h3> + +<p>我們還沒談到增加與移除陣列的單位,現在來看看吧!我們使用上一個小節中的 <code>myArray</code> 陣列。如果你沒跟隨到上一個小節,那就先在你的 console 建立下面這個陣列:</p> + +<pre class="brush: js notranslate">var myArray = ['Manchester', 'London', 'Liverpool', 'Birmingham', 'Leeds', 'Carlisle'];</pre> + +<p>首先,我們可以分別使用 {{jsxref("Array.prototype.push()","push()")}} 和 {{jsxref("Array.prototype.pop()","pop()")}} 來增加或移除一個在陣列最末端的單元 。</p> + +<ol> + <li>Let's use <code>push()</code> first — note that you need to include one or more items that you want to add to the end of your array. Try this: + + <pre class="brush: js notranslate">myArray.push('Cardiff'); +myArray; +myArray.push('Bradford', 'Brighton'); +myArray; +</pre> + </li> + <li>The new length of the array is returned when the method call completes. If you wanted to store the new array length in a variable, you could do something like this: + <pre class="brush: js notranslate">var newLength = myArray.push('Bristol'); +myArray; +newLength;</pre> + </li> + <li>Removing the last item from the array is as simple as running <code>pop()</code> on it. Try this: + <pre class="brush: js notranslate">myArray.pop();</pre> + </li> + <li>The item that was removed is returned when the method call completes. To save that item in a new variable, you could do this: + <pre class="brush: js notranslate">var removedItem = myArray.pop(); +myArray; +removedItem;</pre> + </li> +</ol> + +<p>{{jsxref("Array.prototype.unshift()","unshift()")}} and {{jsxref("Array.prototype.shift()","shift()")}} work in exactly the same way as <code>push()</code> and <code>pop()</code>, respectively, except that they work on the beginning of the array, not the end.</p> + +<ol> + <li>First <code>unshift()</code> — try the following commands: + + <pre class="brush: js notranslate">myArray.unshift('Edinburgh'); +myArray;</pre> + </li> + <li>Now <code>shift()</code>; try these! + <pre class="brush: js notranslate">var removedItem = myArray.shift(); +myArray; +removedItem;</pre> + </li> +</ol> + +<h2 id="Active_learning_Printing_those_products!">Active learning: Printing those products!</h2> + +<p>Let's return to the example we described earlier — printing out product names and prices on an invoice, then totaling the prices and printing them at the bottom. In the editable example below there are comments containing numbers — each of these marks a place where you have to add something to the code. They are as follows:</p> + +<ol> + <li>Below the <code>// number 1</code> comment are a number of strings, each one containing a product name and price separated by a colon. We'd like you to turn this into an array and store it in an array called <code>products</code>.</li> + <li>On the same line as the <code>// number 2</code> comment is the beginning of a for loop. In this line we currently have <code>i <= 0</code>, which is a conditional test that causes the <a href="/en-US/Learn/JavaScript/First_steps/A_first_splash#Loops">for loop</a> to stop immediately, because it is saying "stop when <code>i</code> is no longer less than or equal to 0", and <code>i</code> starts at 0. We'd like you to replace this with a conditional test that stops the loop when <code>i</code> is no longer less than the <code>products</code> array's length.</li> + <li>Just below the <code>// number 3</code> comment we want you to write a line of code that splits the current array item (<code>name:price</code>) into two separate items, one containing just the name and one containing just the price. If you are not sure how to do this, consult the <a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods">Useful string methods</a> article for some help, or even better, look at the {{anch("Converting between strings and arrays")}} section of this article.</li> + <li>As part of the above line of code, you'll also want to convert the price from a string to a number. If you can't remember how to do this, check out the <a href="/en-US/Learn/JavaScript/First_steps/Strings#Numbers_versus_strings">first strings article</a>.</li> + <li>There is a variable called <code>total</code> that is created and given a value of 0 at the top of the code. Inside the loop (below <code>// number 4</code>) we want you to add a line that adds the current item price to that total in each iteration of the loop, so that at the end of the code the correct total is printed onto the invoice. You might need an <a href="/en-US/Learn/JavaScript/First_steps/Math#Assignment_operators">assignment operator</a> to do this.</li> + <li>We want you to change the line just below <code>// number 5</code> so that the <code>itemText</code> variable is made equal to "current item name — $current item price", for example "Shoes — $23.99" in each case, so the correct information for each item is printed on the invoice. This is just simple string concatenation, which should be familiar to you.</li> +</ol> + +<div class="hidden"> +<h6 id="Playable_code">Playable code</h6> + +<pre class="brush: html notranslate"><h2>Live output</h2> + +<div class="output" style="min-height: 150px;"> + +<ul> + +</ul> + +<p></p> + +</div> + +<h2>Editable code</h2> + +<p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> + +<textarea id="code" class="playable-code" style="height: 410px;width: 95%"> +var list = document.querySelector('.output ul'); +var totalBox = document.querySelector('.output p'); +var total = 0; +list.innerHTML = ''; +totalBox.textContent = ''; +// number 1 + 'Underpants:6.99' + 'Socks:5.99' + 'T-shirt:14.99' + 'Trousers:31.99' + 'Shoes:23.99'; + +for (var i = 0; i <= 0; i++) { // number 2 + // number 3 + + // number 4 + + // number 5 + itemText = 0; + + var listItem = document.createElement('li'); + listItem.textContent = itemText; + list.appendChild(listItem); +} + +totalBox.textContent = 'Total: $' + total.toFixed(2); +</textarea> + +<div class="playable-buttons"> + <input id="reset" type="button" value="Reset"> + <input id="solution" type="button" value="Show solution"> +</div> +</pre> + +<pre class="brush: js notranslate">var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var solution = document.getElementById('solution'); +var code = textarea.value; +var userEntry = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + userEntry = textarea.value; + solutionEntry = jsSolution; + solution.value = 'Show solution'; + updateCode(); +}); + +solution.addEventListener('click', function() { + if(solution.value === 'Show solution') { + textarea.value = solutionEntry; + solution.value = 'Hide solution'; + } else { + textarea.value = userEntry; + solution.value = 'Show solution'; + } + updateCode(); +}); + +var jsSolution = 'var list = document.querySelector(\'.output ul\');\nvar totalBox = document.querySelector(\'.output p\');\nvar total = 0;\nlist.innerHTML = \'\';\ntotalBox.textContent = \'\';\n\nvar products = [\'Underpants:6.99\',\n \'Socks:5.99\',\n \'T-shirt:14.99\',\n \'Trousers:31.99\',\n \'Shoes:23.99\'];\n\nfor(var i = 0; i < products.length; i++) {\n var subArray = products[i].split(\':\');\n var name = subArray[0];\n var price = Number(subArray[1]);\n total += price;\n itemText = name + \' — $\' + price;\n\n var listItem = document.createElement(\'li\');\n listItem.textContent = itemText;\n list.appendChild(listItem);\n}\n\ntotalBox.textContent = \'Total: $\' + total.toFixed(2);'; +var solutionEntry = jsSolution; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); + +// stop tab key tabbing out of textarea and +// make it write a tab at the caret position instead + +textarea.onkeydown = function(e){ + if (e.keyCode === 9) { + e.preventDefault(); + insertAtCaret('\t'); + } + + + if (e.keyCode === 27) { + textarea.blur(); + } +}; + +function insertAtCaret(text) { + var scrollPos = textarea.scrollTop; + var caretPos = textarea.selectionStart; + + var front = (textarea.value).substring(0, caretPos); + var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); + textarea.value = front + text + back; + caretPos = caretPos + text.length; + textarea.selectionStart = caretPos; + textarea.selectionEnd = caretPos; + textarea.focus(); + textarea.scrollTop = scrollPos; +} + +// Update the saved userCode every time the user updates the text area code + +textarea.onkeyup = function(){ + // We only want to save the state when the user code is being shown, + // not the solution, so that solution is not saved over the user code + if(solution.value === 'Show solution') { + userEntry = textarea.value; + } else { + solutionEntry = textarea.value; + } + + updateCode(); +};</pre> + + + +<pre class="brush: css notranslate">html { + font-family: sans-serif; +} + +h2 { + font-size: 16px; +} + +.a11y-label { + margin: 0; + text-align: right; + font-size: 0.7rem; + width: 98%; +} + +body { + margin: 10px; + background-color: #f5f9fa; +}</pre> +</div> + +<p>{{ EmbedLiveSample('Playable_code', '100%', 730, "", "", "hide-codepen-jsfiddle") }}</p> + +<h2 id="Active_learning_Top_5_searches">Active learning: Top 5 searches</h2> + +<p>A good use for array methods like {{jsxref("Array.prototype.push()","push()")}} and {{jsxref("Array.prototype.pop()","pop()")}} is when you are maintaining a record of currently active items in a web app. In an animated scene for example, you might have an array of objects representing the background graphics currently displayed, and you might only want 50 displayed at once, for performance or clutter reasons. As new objects are created and added to the array, older ones can be deleted from the array to maintain the desired number.</p> + +<p>In this example we're going to show a much simpler use — here we're giving you a fake search site, with a search box. The idea is that when terms are entered in the search box, the top 5 previous search terms are displayed in the list. When the number of terms goes over 5, the last term starts being deleted each time a new term is added to the top, so the 5 previous terms are always displayed.</p> + +<div class="note"> +<p><strong>Note</strong>: In a real search app, you'd probably be able to click the previous search terms to return to previous searches, and it would display actual search results! We are just keeping it simple for now.</p> +</div> + +<p>To complete the app, we need you to:</p> + +<ol> + <li>Add a line below the <code>// number 1</code> comment that adds the current value entered into the search input to the start of the array. This can be retrieved using <code>searchInput.value</code>.</li> + <li>Add a line below the <code>// number 2</code> comment that removes the value currently at the end of the array.</li> +</ol> + +<div class="hidden"> +<h6 id="Playable_code_2">Playable code 2</h6> + +<pre class="brush: html notranslate"><h2>Live output</h2> +<div class="output" style="min-height: 150px;"> + +<input type="text"><button>Search</button> + +<ul> + +</ul> + +</div> + +<h2>Editable code</h2> + +<p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> + + +<textarea id="code" class="playable-code" style="height: 370px; width: 95%"> +var list = document.querySelector('.output ul'); +var searchInput = document.querySelector('.output input'); +var searchBtn = document.querySelector('.output button'); + +list.innerHTML = ''; + +var myHistory = []; + +searchBtn.onclick = function() { + // we will only allow a term to be entered if the search input isn't empty + if (searchInput.value !== '') { + // number 1 + + // empty the list so that we don't display duplicate entries + // the display is regenerated every time a search term is entered. + list.innerHTML = ''; + + // loop through the array, and display all the search terms in the list + for (var i = 0; i < myHistory.length; i++) { + itemText = myHistory[i]; + var listItem = document.createElement('li'); + listItem.textContent = itemText; + list.appendChild(listItem); + } + + // If the array length is 5 or more, remove the oldest search term + if (myHistory.length >= 5) { + // number 2 + + } + + // empty the search input and focus it, ready for the next term to be entered + searchInput.value = ''; + searchInput.focus(); + } +} +</textarea> + +<div class="playable-buttons"> + <input id="reset" type="button" value="Reset"> + <input id="solution" type="button" value="Show solution"> +</div></pre> + + + + + +<pre class="brush: css notranslate">html { + font-family: sans-serif; +} + +h2 { + font-size: 16px; +} + +.a11y-label { + margin: 0; + text-align: right; + font-size: 0.7rem; + width: 98%; +} + +body { + margin: 10px; + background: #f5f9fa; +}</pre> + + + + + + + +<pre class="brush: js notranslate">var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var solution = document.getElementById('solution'); +var code = textarea.value; +var userEntry = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + userEntry = textarea.value; + solutionEntry = jsSolution; + solution.value = 'Show solution'; + updateCode(); +}); + +solution.addEventListener('click', function() { + if(solution.value === 'Show solution') { + textarea.value = solutionEntry; + solution.value = 'Hide solution'; + } else { + textarea.value = userEntry; + solution.value = 'Show solution'; + } + updateCode(); +}); + +var jsSolution = 'var list = document.querySelector(\'.output ul\');\nvar searchInput = document.querySelector(\'.output input\');\nvar searchBtn = document.querySelector(\'.output button\');\n\nlist.innerHTML = \'\';\n\nvar myHistory= [];\n\nsearchBtn.onclick = function() {\n if(searchInput.value !== \'\') {\n myHistory.unshift(searchInput.value);\n\n list.innerHTML = \'\';\n\n for(var i = 0; i < myHistory.length; i++) {\n itemText = myHistory[i];\n var listItem = document.createElement(\'li\');\n listItem.textContent = itemText;\n list.appendChild(listItem);\n }\n\n if(myHistory.length >= 5) {\n myHistory.pop();\n }\n\n searchInput.value = \'\';\n searchInput.focus();\n }\n}'; +var solutionEntry = jsSolution; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); + +// stop tab key tabbing out of textarea and +// make it write a tab at the caret position instead + +textarea.onkeydown = function(e){ + if (e.keyCode === 9) { + e.preventDefault(); + insertAtCaret('\t'); + } + + if (e.keyCode === 27) { + textarea.blur(); + } +}; + +function insertAtCaret(text) { + var scrollPos = textarea.scrollTop; + var caretPos = textarea.selectionStart; + + var front = (textarea.value).substring(0, caretPos); + var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); + textarea.value = front + text + back; + caretPos = caretPos + text.length; + textarea.selectionStart = caretPos; + textarea.selectionEnd = caretPos; + textarea.focus(); + textarea.scrollTop = scrollPos; +} + +// Update the saved userCode every time the user updates the text area code + +textarea.onkeyup = function(){ + // We only want to save the state when the user code is being shown, + // not the solution, so that solution is not saved over the user code + if(solution.value === 'Show solution') { + userEntry = textarea.value; + } else { + solutionEntry = textarea.value; + } + + updateCode(); +};</pre> + + + + + + +</div> + +<p>{{ EmbedLiveSample('Playable_code_2', '100%', 700, "", "", "hide-codepen-jsfiddle") }}</p> + +<h2 id="Conclusion">Conclusion</h2> + +<p>After reading through this article, we are sure you will agree that arrays seem pretty darn useful; you'll see them crop up everywhere in JavaScript, often in association with loops in order to do the same thing to every item in an array. We'll be teaching you all the useful basics there are to know about loops in the next module, but for now you should give yourself a clap and take a well-deserved break; you've worked through all the articles in this module!</p> + +<p>The only thing left to do is work through this module's assessment, which will test your understanding of the articles that came before it.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Indexed_collections">Indexed collections</a> — an advanced level guide to arrays and their cousins, typed arrays.</li> + <li>{{jsxref("Array")}} — the <code>Array</code> object reference page — for a detailed reference guide to the features discussed in this page, and many more.</li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps/Silly_story_generator", "Learn/JavaScript/First_steps")}}</p> + + + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript">What is JavaScript?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/A_first_splash">A first splash into JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong">What went wrong? Troubleshooting JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Variables">Storing the information you need — Variables</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Math">Basic math in JavaScript — numbers and operators</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings">Handling text — strings in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods">Useful string methods</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays">Arrays</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Silly_story_generator">Assessment: Silly story generator</a></li> +</ul> diff --git a/files/zh-tw/learn/javascript/first_steps/index.html b/files/zh-tw/learn/javascript/first_steps/index.html new file mode 100644 index 0000000000..418325ca8f --- /dev/null +++ b/files/zh-tw/learn/javascript/first_steps/index.html @@ -0,0 +1,71 @@ +--- +title: JavaScript 初探 +slug: Learn/JavaScript/First_steps +tags: + - JavaScript + - 初學者 + - 字串 + - 指引 + - 撰寫程式 + - 數值 + - 數學 + - 文章 + - 變數 + - 運算子 + - 陣列 +translation_of: Learn/JavaScript/First_steps +--- +<div>{{LearnSidebar}}</div> + +<p class="summary">帶領各位開始體驗撰寫 JavaScript 前,在第一個 JavaScript 單元中,我們首先來回答一些基本的問題,像是「什麼是 JavaScript 啊?」、「它長什麼樣子?」以及「它能拿來做什麼?」。之後我們會詳細討論幾個關鍵元素,諸如變量(variables)、字串(strings)、數字(numbers)和陣列(arrays)。</p> + +<h2 id="事前準備">事前準備</h2> + +<p>在開始這個教學之前,你不需要具備任何的 JavaScript 相關知識,但是你應該對 HTML 及 CSS 有一點熟悉。建議你在開始學習 JavaScript 前,先看過下列內容 :</p> + +<ul> + <li><a href="/zh-TW/docs/Learn/Getting_started_with_the_web">開始使用 Web </a> (包括 <a href="/zh-TW/docs/Learn/Getting_started_with_the_web/JavaScript_basics">JavaScript 基礎簡介</a>).</li> + <li><a href="/zh-TW/docs/Learn/HTML/Introduction_to_HTML">HTML 簡介</a>.</li> + <li><a href="/zh-TW/docs/Learn/CSS/Introduction_to_CSS">CSS 簡介</a>.</li> +</ul> + +<div class="note"> +<p><span style="font-size: 14px;"><strong>注意</strong></span>: 假如你正在使用 電腦/平板/其他裝置,你還不需要知道如何建立自己的檔案,你可以在線上程式撰寫系統來嘗試範例程式,像是 <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/First_steps/What_is_JavaScript">什麼是 JavaScript?</a></dt> + <dd>歡迎來到 MDN JavaScript 新手村教學!在第一個章節中我們將一個較高的層次看 JavaScript,回答像是「它是什麼?」、「有什麼用?」之類的問題,並且確保你能了解 JavaScript 的目的。</dd> + <dt><a href="/zh-TW/docs/Learn/JavaScript/First_steps/A_first_splash">和 JavaScript 的第一次接觸</a></dt> + <dd>現在你已經學到一些關於 JavaScript 的原理,以及可以用它來作什麼,我們將經由完整的引導,給你一個關於 JavaScript 基礎功能的速成課。這裡你將會一步一步地建立一個簡單的「猜數字」遊戲。</dd> + <dt><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_went_wrong">什麼出錯了? JavaScript 的疑難排解(除錯)</a></dt> + <dd>當你在前一章節建立的「猜數字」遊戲過程中,你可能會發現它不能運作。不要慌,這個章節的目的是提供一些提示,用來找出及修正在 JavaScript 程式裡的錯誤,讓你不會因為這些問題而煩惱。</dd> + <dt><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Variables">儲存你需要的資訊 — 變數</a></dt> + <dd>在讀過前面幾個章節後,你現在應該能由較高的層次了解 JavaScript 是什麼,它能為你做些什麼,如何與其他的網站技術一起使用,以及它的主要的特性。在本章節中,我們將深入探討真正的基礎知識,看看 JavaScript 最基本的組成 — 變數(Variables)是如何運作 。</dd> + <dt><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Math">JavaScript 的基本運算— 數字 與 運算子</a></dt> + <dd>本章的重點,我們討論 JavaScript 的數值計算 — 我們如何依我們的要求組合運算子與其它元素來操控數值。</dd> + <dt><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Strings">處理文字 — JavaScript 的字串</a></dt> + <dd>接下來我們將焦點轉到字串(strings) — 這是程式裡對一段文字的稱呼。這個章節我們將會檢視學習 JavaScript 中,所有你通常想要知道於字串事情,例如創建字串、字串跳脫(escaping)操作,以及把它們組合起來。</dd> + <dt><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Useful_string_methods">有用的字串方法</a></dt> + <dd>我們已經看過了字串的基礎知識,現在讓我們加快腳步,看看可以使用內建的方法對字串進行哪些有用的操作 ,例如:取得字串的長度、串接或分割字串、替換字串中的某個字……等等。</dd> + <dt><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Arrays">陣列</a></dt> + <dd>在這個單元的最後一個章節,我們來看看陣列 (Array) — 把一連串資料整齊地儲存在一個變數中。我們會看到為什麼它有用,然後探索如何創建一個陣列,對陣列內的項目進行檢索、新增、刪除……等操作。</dd> +</dl> + +<h2 id="測試一下">測試一下</h2> + +<p>下面的任務會測試你對於前面提到的 JavaScript 基本概念是否了解。</p> + +<dl> + <dt><a href="https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/First_steps/Silly_story_generator">傻故事產生器</a></dt> + <dd>本次測試中,你的任務是使用在這個單元所學到的知識,建立一個能隨機產生笑話的有趣程式。祝你愉快!</dd> +</dl> + +<h2 id="參考資源">參考資源</h2> + +<dl> + <dt><a class="external" href="https://learnjavascript.online/" rel="noopener">Learn JavaScript</a></dt> + <dd>對於想成為網站開發者一個很好的資源,以互動的方式學習 JavaScript ,包含短課程、互動測驗,自動評估狀況給予指引。前 40 堂課是免費,完整的課程可以在一次付費買下。</dd> +</dl> diff --git a/files/zh-tw/learn/javascript/first_steps/math/index.html b/files/zh-tw/learn/javascript/first_steps/math/index.html new file mode 100644 index 0000000000..4c7f1d4cba --- /dev/null +++ b/files/zh-tw/learn/javascript/first_steps/math/index.html @@ -0,0 +1,426 @@ +--- +title: JavaScript中的基本數學 - 數字和運算符 +slug: Learn/JavaScript/First_steps/Math +translation_of: Learn/JavaScript/First_steps/Math +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps")}}</div> + +<p class="summary">在本課程的這一點上,我們將討論JavaScript中的數學 - 我們如何使用{{Glossary("Operator","operators")}} 和其他功能來成功操縱數字來進行我們的出價。</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">先備知識:</th> + <td>電腦基礎知識,了解基本的 HTML 和 CSS ,了解 JavaScript 是什麼。</td> + </tr> + <tr> + <th scope="row">目標:</th> + <td>熟悉JavaScript中的基礎數學。</td> + </tr> + </tbody> +</table> + +<h2 id="每個人都喜歡數學">每個人都喜歡數學</h2> + +<p>好吧,也許不是。 我們中的一些人喜歡數學,我們有些人討厭數學,因為我們必須在學校學習乘法和除法,而我們中的一些人兩者皆要。 但我們都不能否認數學是生活中的一個基本組成部分,我們離不開它們。 當我們學習JavaScript(或任何其他語言)的程式時,尤其如此 - 我們所做的很多事情都依賴於處理數值數據,計算新值等等,你不會驚訝學習JavaScript 有一套功能齊全的數學函數。</p> + +<p>本文僅討論你現在需了解的基本部分。</p> + +<h3 id="數字的種類">數字的種類</h3> + +<p><font>在程式裡,即使眾所周知的十進位數字系統也比您想像的要複雜。</font><font>我們使用不同的術語來描述不同類型的十進位數字,例如:</font></p> + +<ul> + <li><strong>Integers </strong>是整數,如:10,400,或 -5。</li> + <li><strong>Floating point numbers</strong> (floats) 浮點數具有小數點跟小數位,例如12.5和56.7786543。</li> + <li><strong>Doubles</strong> 是一種特定型態的浮點數 that have greater precision than standard floating point numbers (meaning that they are accurate to a greater number of decimal places).</li> +</ul> + +<p><font>我們甚至有不同類型的號碼系統!</font><font>十進位以10為單位(表示每列使用0–9),但是也有像這些:</font></p> + +<ul> + <li><strong><font><font>二進位</font></font></strong><font><font> —計算機的最底層語言;</font><font>0和1。</font></font></li> + <li><strong><font><font>八進位</font></font></strong><font><font> —以8為</font>單位<font>,每列使用0–7。</font></font></li> + <li><strong><font><font>十六進位</font></font></strong><font><font> —以16為</font>單位<font>,在每列中使用0–9,然後使用a–f。</font></font><a href="https://translate.googleusercontent.com/translate_c?depth=1&pto=aue&rurl=translate.google.com.tw&sl=en&sp=nmt4&tl=zh-TW&u=https://developer.mozilla.org/en-US/Learn/CSS/Introduction_to_CSS/Values_and_units&usg=ALkJrhjxtle73XLvao6e9e-CZv6u2Hq68g#Hexadecimal_values"><font><font>在CSS中</font></font></a><font><font>設置</font><a href="https://translate.googleusercontent.com/translate_c?depth=1&pto=aue&rurl=translate.google.com.tw&sl=en&sp=nmt4&tl=zh-TW&u=https://developer.mozilla.org/en-US/Learn/CSS/Introduction_to_CSS/Values_and_units&usg=ALkJrhjxtle73XLvao6e9e-CZv6u2Hq68g#Hexadecimal_values"><font>顏色</font></a><font>之前,您可能已經遇到過這些數字</font><font>。</font></font></li> +</ul> + +<p><strong><font><font>在開始擔心大腦融化之前,先等等!</font></font></strong><font><font>首先,我們將在整個課程中完全使用十進位數;您很少會想到其他類型的需求,如果有的話。</font></font> </p> + +<p>第二個好消息是JavaScript只有一種數字資料類型 ,猜對了!就是{{jsxref("Number")}}。這代表無論你在JavaScript需要處理哪種數字,處理方法都是一樣的。</p> + +<div class="note"> +<p><strong>Note</strong>: 事實上, JavaScript 有第二種數字型態, {{Glossary("BigInt")}}, 用於非常、非常、非常大的整數。但這節課我只需要擔心 <code>Number</code> 的值。</p> +</div> + +<h3 id="我怎麼看都是些數字!">我怎麼看都是些數字!</h3> + +<p>讓我們來快速操作一些數字來重新認識一下我們會需要用到的基本語法。將下面的需求表輸入進你的開發者工具js控制台(<a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">developer tools JavaScript console</a>),或是簡單建立在任何你偏好的控制台。</p> + +<ol> + <li>首先,先來宣告兩個變數,並分別賦予他們初始值為整數與浮點數,然後接著打上變數名稱來確認萬事預備: + <pre class="brush: js notranslate">var myInt = 5; +var myFloat = 6.667; +myInt; +myFloat;</pre> + </li> + <li>數字的值不需要引號框起來 — 試著宣告和賦予更多初始值為數字的變數,在繼續下去之前。</li> + <li>現在,來確認Now let's check that both our original variables are of the same datatype. There is an operator called {{jsxref("Operators/typeof", "typeof")}} in JavaScript that does this. Enter the below two lines as shown: + <pre class="brush: js notranslate">typeof myInt; +typeof myFloat;</pre> + You should get <code>"number"</code> returned in both cases — this makes things a lot easier for us than if different numbers had different data types, and we had to deal with them in different ways. Phew!</li> +</ol> + +<h2 id="算術運算符">算術運算符</h2> + +<p>Arithmetic operators are the basic operators that we use to do sums:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Operator</th> + <th scope="col">Name</th> + <th scope="col">Purpose</th> + <th scope="col">Example</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>+</code></td> + <td>加法</td> + <td>Adds two numbers together.</td> + <td><code>6 + 9</code></td> + </tr> + <tr> + <td><code>-</code></td> + <td>減法</td> + <td>Subtracts the right number from the left.</td> + <td><code>20 - 15</code></td> + </tr> + <tr> + <td><code>*</code></td> + <td>乘法</td> + <td>Multiplies two numbers together.</td> + <td><code>3 * 7</code></td> + </tr> + <tr> + <td><code>/</code></td> + <td>除法</td> + <td>Divides the left number by the right.</td> + <td><code>10 / 5</code></td> + </tr> + <tr> + <td><code>%</code></td> + <td>餘數 (sometimes called modulo)</td> + <td> + <p>Returns the remainder left over after you've divided the left number into a number of integer portions equal to the right number.</p> + </td> + <td><code>8 % 3</code> (returns 2, as three goes into 8 twice, leaving 2 left over.)</td> + </tr> + <tr> + <td>**</td> + <td>指數</td> + <td>Raises a <code>base</code> number to the <code>exponent</code> power, that is, the <code>base</code> number multiplied by itself, <code>exponent</code> times. It was first Introduced in EcmaScript 2016.</td> + <td><code>5 ** 2</code> (5的2次方得 <code>25</code>,跟 <code>5 * 5</code>結果相同)</td> + </tr> + </tbody> +</table> + +<div class="note"> +<p><strong>Note</strong>: You'll sometimes see numbers involved in sums referred to as {{Glossary("Operand", "operands")}}.</p> +</div> + +<p><strong>Note</strong>: You may sometimes see exponents expressed using the older {{jsxref("Math.pow()")}} method, which works in a very similar way. For example, in <code>Math.pow(7, 3)</code>, <code>7</code> is the base and <code>3</code> is the exponent, so the result of the expression is <code>343</code>. <code>Math.pow(7, 3)</code> is equivalent to <code>7**3</code>.</p> + +<p>We probably don't need to teach you how to do basic math, but we would like to test your understanding of the syntax involved. Try entering the examples below into your <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">developer tools JavaScript console</a>, or use the simple built in console seen earlier if you'd prefer, to familiarize yourself with the syntax.</p> + +<ol> + <li>First try entering some simple examples of your own, such as + <pre class="brush: js notranslate">10 + 7 +9 * 8 +60 % 3</pre> + </li> + <li>You can also try declaring and initializing some numbers inside variables, and try using those in the sums — the variables will behave exactly like the values they hold for the purposes of the sum. For example: + <pre class="brush: js notranslate">var num1 = 10; +var num2 = 50; +9 * num1; +num2 / num1;</pre> + </li> + <li>Last for this section, try entering some more complex expressions, such as: + <pre class="brush: js notranslate">5 + 10 * 3; +num2 % 9 * num1; +num2 + num1 / 8 + 2;</pre> + </li> +</ol> + +<p>Some of this last set of sums might not give you quite the result you were expecting; the below section might well give the answer as to why.</p> + +<h3 id="Operator_precedence">Operator precedence</h3> + +<p>Let's look at the last example from above, assuming that <code>num2</code> holds the value 50 and <code>num1</code> holds the value 10 (as originally stated above):</p> + +<pre class="brush: js notranslate">num2 + num1 / 8 + 2;</pre> + +<p>As a human being, you may read this as <em>"50 plus 10 equals 60"</em>, then <em>"8 plus 2 equals 10"</em>, and finally <em>"60 divided by 10 equals 6"</em>.</p> + +<p>But the browser does <em>"10 divided by 8 equals 1.25"</em>, then <em>"50 plus 1.25 plus 2 equals 53.25"</em>.</p> + +<p>This is because of <strong>operator precedence</strong> — some operators will be applied before others when calculating the result of a sum (referred to as an expression, in programming). Operator precedence in JavaScript is the same as is taught in math classes in school — Multiply and divide are always done first, then add and subtract (the sum is always evaluated from left to right).</p> + +<p>If you want to override operator precedence, you can put parentheses round the parts that you want to be explicitly dealt with first. So to get a result of 6, we could do this:</p> + +<pre class="brush: js notranslate">(num2 + num1) / (8 + 2);</pre> + +<p>Try it and see.</p> + +<div class="note"> +<p><strong>Note</strong>: A full list of all JavaScript operators and their precedence can be found in <a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Operator_precedence">Expressions and operators</a>.</p> +</div> + +<h2 id="遞增和遞減運算符">遞增和遞減運算符</h2> + +<p>Sometimes you'll want to repeatedly add or subtract one to/from a numeric variable value. This can be conveniently done using the increment (<code>++</code>) and decrement(<code>--</code>) operators. We used <code>++</code> in our "Guess the number" game back in our <a href="/en-US/docs/Learn/JavaScript/Introduction_to_JavaScript_1/A_first_splash">first splash into JavaScript</a> article, when we added 1 to our <code>guessCount</code> variable to keep track of how many guesses the user has left after each turn.</p> + +<pre class="brush: js notranslate">guessCount++;</pre> + +<div class="note"> +<p><strong>Note</strong>: They are most commonly used in <a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration">loops</a>, which you'll learn about later on in the course. For example, say you wanted to loop through a list of prices, and add sales tax to each one. You'd use a loop to go through each value in turn and do the necessary calculation for adding the sales tax in each case. The incrementor is used to move to the next value when needed. We've actually provided a simple example showing how this is done — <a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/maths/loop.html">check it out live</a>, and <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/maths/loop.html">look at the source code</a> to see if you can spot the incrementors! We'll look at loops in detail later on in the course.</p> +</div> + +<p>Let's try playing with these in your console. For a start, note that you can't apply these directly to a number, which might seem strange, but we are assigning a variable a new updated value, not operating on the value itself. The following will return an error:</p> + +<pre class="brush: js notranslate">3++;</pre> + +<p>So, you can only increment an existing variable. Try this:</p> + +<pre class="brush: js notranslate">var num1 = 4; +num1++;</pre> + +<p>Okay, strangeness number 2! When you do this, you'll see a value of 4 returned — this is because the browser returns the current value, <em>then</em> increments the variable. You can see that it's been incremented if you return the variable value again:</p> + +<pre class="brush: js notranslate">num1;</pre> + +<p>The same is true of <code>--</code> : try the following</p> + +<pre class="brush: js notranslate">var num2 = 6; +num2--; +num2;</pre> + +<div class="note"> +<p><strong>Note</strong>: You can make the browser do it the other way round — increment/decrement the variable <em>then</em> return the value — by putting the operator at the start of the variable instead of the end. Try the above examples again, but this time use <code>++num1</code> and <code>--num2</code>.</p> +</div> + +<h2 id="賦值運算符">賦值運算符</h2> + +<p>Assignment operators are operators that assign a value to a variable. We have already used the most basic one, <code>=</code>, loads of times — it simply assigns the variable on the left the value stated on the right:</p> + +<pre class="brush: js notranslate">var x = 3; // x contains the value 3 +var y = 4; // y contains the value 4 +x = y; // x now contains the same value y contains, 4</pre> + +<p>But there are some more complex types, which provide useful shortcuts to keep your code neater and more efficient. The most common are listed below:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Operator</th> + <th scope="col">Name</th> + <th scope="col">Purpose</th> + <th scope="col">Example</th> + <th scope="col">Shortcut for</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>+=</code></td> + <td>Addition assignment</td> + <td>Adds the value on the right to the variable value on the left, then returns the new variable value</td> + <td><code>x = 3;<br> + x += 4;</code></td> + <td><code>x = 3;<br> + x = x + 4;</code></td> + </tr> + <tr> + <td><code>-=</code></td> + <td>Subtraction assignment</td> + <td>Subtracts the value on the right from the variable value on the left, and returns the new variable value</td> + <td><code>x = 6;<br> + x -= 3;</code></td> + <td><code>x = 6;<br> + x = x - 3;</code></td> + </tr> + <tr> + <td><code>*=</code></td> + <td>Multiplication assignment</td> + <td>Multiples the variable value on the left by the value on the right, and returns the new variable value</td> + <td><code>x = 2;<br> + x *= 3;</code></td> + <td><code>x = 2;<br> + x = x * 3;</code></td> + </tr> + <tr> + <td><code>/=</code></td> + <td>Division assignment</td> + <td>Divides the variable value on the left by the value on the right, and returns the new variable value</td> + <td><code>x = 10;<br> + x /= 5;</code></td> + <td><code>x = 10;<br> + x = x / 5;</code></td> + </tr> + </tbody> +</table> + +<p>Try typing some of the above examples into your console, to get an idea of how they work. In each case, see if you can guess what the value is before you type in the second line.</p> + +<p>Note that you can quite happily use other variables on the right hand side of each expression, for example:</p> + +<pre class="brush: js notranslate">var x = 3; // x contains the value 3 +var y = 4; // y contains the value 4 +x *= y; // x now contains the value 12</pre> + +<div class="note"> +<p><strong>Note</strong>: There are lots of <a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment_operators">other assignment operators available</a>, but these are the basic ones you should learn now.</p> +</div> + +<h2 id="Active_learning_sizing_a_canvas_box">Active learning: sizing a canvas box</h2> + +<p>In this exercise, you will manipulate some numbers and operators to change the size of a box. The box is drawn using a browser API called the {{domxref("Canvas API", "", "", "true")}}. There is no need to worry about how this works — just concentrate on the math for now. The width and height of the box (in pixels) are defined by the variables <code>x</code> and <code>y</code>, which are initially both given a value of 50.</p> + +<p>{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/editable_canvas.html", '100%', 620)}}</p> + +<p><strong><a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/maths/editable_canvas.html">Open in new window</a></strong></p> + +<p>In the editable code box above, there are two lines marked with a comment that we'd like you to update to make the box grow/shrink to certain sizes, using certain operators and/or values in each case. Let's try the following:</p> + +<ul> + <li>Change the line that calculates x so the box is still 50px wide, but the 50 is calculated using the numbers 43 and 7 and an arithmetic operator.</li> + <li>Change the line that calculates y so the box is 75px high, but the 75 is calculated using the numbers 25 and 3 and an arithmetic operator.</li> + <li>Change the line that calculates x so the box is 250px wide, but the 250 is calculated using two numbers and the remainder (modulo) operator.</li> + <li>Change the line that calculates y so the box is 150px high, but the 150 is calculated using three numbers and the subtraction and division operators.</li> + <li>Change the line that calculates x so the box is 200px wide, but the 200 is calculated using the number 4 and an assignment operator.</li> + <li>Change the line that calculates y so the box is 200px high, but the 200 is calculated using the numbers 50 and 3, the multiplication operator, and the addition assignment operator.</li> +</ul> + +<p>Don't worry if you totally mess the code up. You can always press the Reset button to get things working again. After you've answered all the above questions correctly, feel free to play with the code some more or create your own challenges.</p> + +<h2 id="比較運算符">比較運算符</h2> + +<p>Sometimes we will want to run true/false tests, then act accordingly depending on the result of that test — to do this we use <strong>comparison operators</strong>.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Operator</th> + <th scope="col">Name</th> + <th scope="col">Purpose</th> + <th scope="col">Example</th> + </tr> + <tr> + <td><code>===</code></td> + <td>Strict equality</td> + <td>Tests whether the left and right values are identical to one another</td> + <td><code>5 === 2 + 4</code></td> + </tr> + <tr> + <td><code>!==</code></td> + <td>Strict-non-equality</td> + <td>Tests whether the left and right values <strong>not</strong> identical to one another</td> + <td><code>5 !== 2 + 3</code></td> + </tr> + <tr> + <td><code><</code></td> + <td>Less than</td> + <td>Tests whether the left value is smaller than the right one.</td> + <td><code>10 < 6</code></td> + </tr> + <tr> + <td><code>></code></td> + <td>Greater than</td> + <td>Tests whether the left value is greater than the right one.</td> + <td><code>10 > 20</code></td> + </tr> + <tr> + <td><code><=</code></td> + <td>Less than or equal to</td> + <td>Tests whether the left value is smaller than or equal to the right one.</td> + <td><code>3 <= 2</code></td> + </tr> + <tr> + <td><code>>=</code></td> + <td>Greater than or equal to</td> + <td>Tests whether the left value is greater than or equal to the right one.</td> + <td><code>5 >= 4</code></td> + </tr> + </thead> +</table> + +<div class="note"> +<p><strong>Note</strong>: You may see some people using <code>==</code> and <code>!=</code> in their tests for equality and non-equality. These are valid operators in JavaScript, but they differ from <code>===</code>/<code>!==</code>. The former versions test whether the values are the same but not whether the values' datatypes are the same. The latter, strict versions test the equality of both the values and their datatypes. The strict versions tend to result in fewer errors, so we recommend you use them.</p> +</div> + +<p>If you try entering some of these values in a console, you'll see that they all return <code>true</code>/<code>false</code> values — those booleans we mentioned in the last article. These are very useful, as they allow us to make decisions in our code, and they are used every time we want to make a choice of some kind. For example, booleans can be used to:</p> + +<ul> + <li>Display the correct text label on a button depending on whether a feature is turned on or off</li> + <li>Display a game over message if a game is over or a victory message if the game has been won</li> + <li>Display the correct seasonal greeting depending what holiday season it is</li> + <li>Zoom a map in or out depending on what zoom level is selected</li> +</ul> + +<p>We'll look at how to code such logic when we look at conditional statements in a future article. For now, let's look at a quick example:</p> + +<pre class="brush: html notranslate"><button>Start machine</button> +<p>The machine is stopped.</p> +</pre> + +<pre class="brush: js notranslate">var btn = document.querySelector('button'); +var txt = document.querySelector('p'); + +btn.addEventListener('click', updateBtn); + +function updateBtn() { + if (btn.textContent === 'Start machine') { + btn.textContent = 'Stop machine'; + txt.textContent = 'The machine has started!'; + } else { + btn.textContent = 'Start machine'; + txt.textContent = 'The machine is stopped.'; + } +}</pre> + +<p>{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/conditional.html", '100%', 100)}}</p> + +<p><strong><a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/maths/conditional.html">Open in new window</a></strong></p> + +<p>You can see the equality operator being used just inside the <code>updateBtn()</code> function. In this case, we are not testing if two mathemetical expressions have the same value — we are testing whether the text content of a button contains a certain string — but it is still the same principle at work. If the button is currently saying "Start machine" when it is pressed, we change its label to "Stop machine", and update the label as appropriate. If the button is currently saying "Stop machine" when it is pressed, we swap the display back again.</p> + +<div class="note"> +<p><strong>Note</strong>: Such a control that swaps between two states is generally referred to as a <strong>toggle</strong>. It toggles between one state and another — light on, light off, etc.</p> +</div> + +<h2 id="Summary">Summary</h2> + +<p>In this article we have covered the fundamental information you need to know about numbers in JavaScript, for now. You'll see numbers used again and again, all the way through your JavaScript learning, so it's a good idea to get this out of the way now. If you are one of those people that doesn't enjoy math, you can take comfort in the fact that this chapter was pretty short.</p> + +<p>In the next article, we'll explore text and how JavaScript allows us to manipulate it.</p> + +<div class="note"> +<p><strong>Note</strong>: If you do enjoy math and want to read more about how it is implemented in JavaScript, you can find a lot more detail in MDN's main JavaScript section. Great places to start are our <a href="/en-US/docs/Web/JavaScript/Guide/Numbers_and_dates">Numbers and dates</a> and <a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators">Expressions and operators</a> articles.</p> +</div> + +<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps")}}</p> + +<h2 id="在這個學習模組中">在這個學習模組中</h2> + +<ul> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_is_JavaScript">什麼是 JavaScript?</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/A_first_splash">和 JavaScript 的第一次接觸</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_went_wrong">什麼出錯了? JavaScript 的疑難排解(除錯)</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Variables">儲存你需要的資訊 — 變數</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Math">JavaScript 的基本運算— 數字 與 運算子</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Strings">處理文字 — JavaScript 的字串</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Useful_string_methods">有用的字串方法</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Arrays">陣列</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Silly_story_generator">附錄:笑話產生器</a></li> +</ul> diff --git a/files/zh-tw/learn/javascript/first_steps/silly_story_generator/index.html b/files/zh-tw/learn/javascript/first_steps/silly_story_generator/index.html new file mode 100644 index 0000000000..2659623210 --- /dev/null +++ b/files/zh-tw/learn/javascript/first_steps/silly_story_generator/index.html @@ -0,0 +1,149 @@ +--- +title: 傻故事產生器 +slug: Learn/JavaScript/First_steps/Silly_story_generator +tags: + - JavaScript + - 初學者 + - 字串 + - 測試 + - 變數 + - 運算子 + - 陣列 +translation_of: Learn/JavaScript/First_steps/Silly_story_generator +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenu("Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}</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基礎的理解程度, 例如 變數, 數字, 運算子, 字串 以及陣列.</td> + </tr> + </tbody> +</table> + +<h2 id="前置作業">前置作業</h2> + +<p>在開始本測驗前,你應該:</p> + +<ul> + <li>開啟右方網頁: <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/assessment-start/index.html">grab the HTML file</a> ,將HTML範本儲存到您的本地電腦的新資料夾中,並命名為<code>index.html</code> 。範本也包含相應的CSS檔案。</li> + <li>開啟右方網頁: <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/assessment-start/raw-text.txt">page containing the raw text</a> ,並保持網頁開啟在瀏覽器的另一分頁上,以便稍後使用。</li> +</ul> + +<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 的編輯區,您也能透過<code><script></code>直接將JS語法放到 HTML檔案中。</p> +</div> + +<h2 id="任務簡介">任務簡介</h2> + +<p>透過前述網頁您已經得到初版HTML/CSS 與一些JavaScript 字串、函數;您需要再寫一些必要的JavaScript語法來將這些檔案轉變為可運作的程式,任務如下: </p> + +<ul> + <li>當 "Generate random story" (產生隨機故事)的按鈕被點擊,請產出一則傻故事</li> + <li>若在點擊產生故事按鈕前將自定義名字輸入於輸入框"Enter custom name" (譯:輸入自定義名字),則將故事中預設的名字 "Bob" 代換為自定義名字</li> + <li>若在點擊產生故事按鈕前,也點擊UK的單選按鈕,則將預設的美制重量、溫度單位轉換為英制單位</li> + <li>每點擊一次產生故事的按鈕,即產生新一則隨機傻故事(不限次數)</li> +</ul> + +<p>以下截圖為完成品的範例:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13667/assessment-1.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p> + +<p>點擊右方連結可以參考與測試完成品: <a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/assessment-finished/">have a look at the finished example</a> (請不要偷看原始碼喔!)</p> + +<h2 id="任務開始">任務開始</h2> + +<p>以下清楚地描述了完成任務需要哪些動作。</p> + +<p>基本設定:</p> + +<ol> + <li>在有<code>index.html</code>的資料夾中建立一個新檔案稱之為 <code>main.js</code></li> + <li>請在<code>index.html</code>中引用第一點建立的外部JavaScript 檔案,引用方法是在<code></body></code> tag 前插入一組 {{htmlelement("script")}}元素 ,並在opening tag上加入<code>src=" main.js"</code></li> +</ol> + +<p>初始化變數與函數:</p> + +<ol> + <li>在原始文件檔中(raw text file),請複製標題1. COMPLETE VARIABLE AND FUNCTION DEFINITIONS" 以下到第2點前的所有程式碼,並貼到<code>main.js</code>中。這給你三個變數來標記:文字輸入框 "Enter custom name" (輸入自定義名字) ,變數為 (<code>customName</code>) 與按鈕 "Generate random story"(產生隨機故事) ,變數為 (<code>randomize</code>), 以及HTML中接近body底部的 {{htmlelement("p")}} 元素,故事將會被複製進第三個變數(<code>story</code>)中。此外您還會得到一個函數稱為: <code>randomValueFromArray()</code> ,從命名中可以得知這是一個陣列,它會隨機提供一則儲存其中的故事。</li> + <li>接著讓我們查看原始文件檔中(raw text file)的第2點: "2. RAW TEXT STRINGS"。 其包含的這些字串在程式運行時會被放進來,請幫忙在<code>main.js</code>中將這些字串分別存進對應的變數裡: + <ol> + <li>將第一行超級長的字串存進變數 <code>storyText</code>中。</li> + <li>將第一組三個字串存進一陣列,並命名為<code>insertX</code>。</li> + <li>將第二組三個字串存進一陣列,並命名為<code>insertY</code>.</li> + <li>將第三組三個字串存進一陣列,並命名為<code>insertZ</code>.</li> + </ol> + </li> +</ol> + +<p>放置事件監聽器與未完善的函數:</p> + +<ol> + <li>再度回到原始文件檔中(raw text file)</li> + <li>複製第3標題,"3. EVENT LISTENER AND PARTIAL FUNCTION DEFINITION" 以下的內容,並貼到 <code>main.js</code> 檔案中的最下方,這包含: + <ul> + <li>給變數<code>randomize</code>增加一個點擊事件監聽器(clickevent listener) ,所以當產生故事的按鈕被點擊,<code>result()</code>函數會運行 。</li> + <li>增加一個部分完成的函數 <code>result()</code> ,完成測驗您需要完善這個函數。</li> + </ul> + </li> +</ol> + +<p>完善 <code>result()</code> 函數:</p> + +<ol> + <li>創造一個新變數稱為:<code>newStory</code>,讓這個變數的值等於<code>storyText</code>;我們需要這個變數以便每次產生故事按鈕被點擊時,函數都能再次運作並產生新故事,如果我們只在<code>storyText</code>之上做改變,我們只能產生一次新故事。</li> + <li>額外增加三個變數:<code>xItem</code>、<code>yItem</code> 與 <code>zItem</code>,並使這三個變數等於函數<code>randomValueFromArray()</code>中三個陣列的結果(每次會從各陣列中隨機挑出一項)。舉例,你能透過寫<code>randomValueFromArray(insertX)</code>來從<code>insertX</code>得到任一隨機字串。</li> + <li>接著我們需要將<code>newStory</code>中三個placeholders字串 <code>:insertx:</code>、<code>:inserty:</code>跟 <code>:insertz:</code>換成<code>xItem</code>、<code>yItem</code>、 <code>zItem</code>。有些字串方法在這裡特別有用,請讓字串方法的返回值等於 <code>newStory</code> ,所以之後每次 <code>newStory</code> 被呼叫時,is made equal to itself, but with substitutions made. So each time the button is pressed, these placeholders are each replaced with a random silly string. As a further hint, the method in question only replaces the first instance of the substring it finds, so you might need to make one of the calls twice.</li> + <li>Inside the first <code>if</code> block, add another string replacement method call to replace the name 'Bob' found in the <code>newStory</code> string with the <code>name</code> variable. In this block we are saying "If a value has been entered into the <code>customName</code> text input, replace Bob in the story with that custom name."</li> + <li>Inside the second <code>if</code> block, we are checking to see if the <code>uk</code> radio button has been selected. If so, we want to convert the weight and temperature values in the story from pounds and Fahrenheit into stones and centigrade. What you need to do is as follows: + <ol> + <li>Look up the formulae for converting pounds to stone, and Fahrenheit to centigrade.</li> + <li>Inside the line that defines the <code>weight</code> variable, replace 300 with a calculation that converts 300 pounds into stones. Concatenate <code>' stone'</code> onto the end of the result of the overall <code>Math.round()</code> call.</li> + <li>Inside the line that defines the <code>temperature</code> variable, replace 94 with a calculation that converts 94 Fahrenheit into centigrade. Concatenate <code>' centigrade'</code> onto the end of the result of the overall <code>Math.round()</code> call.</li> + <li>Just under the two variable definitions, add two more string replacement lines that replace '94 farenheit' with the contents of the <code>temperature</code> variable, and '300 pounds' with the contents of the <code>weight</code> variable.</li> + </ol> + </li> + <li>Finally, in the second-to-last line of the function, make the <code>textContent</code> property of the <code>story</code> variable (which references the paragraph) equal to <code>newStory</code>.</li> +</ol> + +<h2 id="Hints_and_tips">Hints and tips</h2> + +<ul> + <li>You don't need to edit the HTML in any way, except to apply the JavaScript to your HTML.</li> + <li>If you are unsure whether the JavaScript is applied to your HTML properly, try removing everything else from the JavaScript file temporarily, adding in a simple bit of JavaScript that you know will create an obvious effect, then saving and refreshing. The following for example turns the background of the {{htmlelement("html")}} element red — so the entire browser window should go red if the JavaScript is applied properly: + <pre class="brush: js notranslate">document.querySelector('html').style.backgroundColor = 'red';</pre> + </li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round">Math.round()</a> is a built-in JavaScript method that simply rounds the result of a calculation to the nearest whole number.</li> + <li>There are three instances of strings that need to be replaced. You may repeat the <code>replace()</code> method multiple times, or you can use regular expressions. For instance, <code>var text = 'I am the biggest lover, I love my love'; text.replace(/love/g,'like');</code> will replace all instances of 'love' to 'like'. Remember, Strings are immutable!</li> +</ul> + +<h2 id="測驗一下">測驗一下</h2> + +<p>如果您將這個測驗視為正規課程的一部分,建議將成果提供您的老師或指導者以利幫助您達到最好的學習效益。如果您是自學者,您可以輕鬆的透過右方網頁 <a href="https://discourse.mozilla.org/t/silly-story-generator-assessment/24686">discussion thread for this exercise</a> 得到建議,或者在<a href="https://wiki.mozilla.org/IRC">Mozilla IRC</a>上的 <a href="irc://irc.mozilla.org/mdn">#mdn</a> IRC 頻道。提醒您:第一次嘗試這個測驗時,作弊可不會得到任何收穫喔!</p> + +<p>{{PreviousMenu("Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}</p> + + + +<h2 id="相關學習模組">相關學習模組</h2> + +<ul> + <li><a href="https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/First_steps/What_is_JavaScript">什麼是 JavaScript?</a></li> + <li><a href="https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/First_steps/A_first_splash">和 JavaScript 的第一次接觸</a></li> + <li><a href="https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/First_steps/What_went_wrong">什麼出錯了? JavaScript 的疑難排解(除錯)</a></li> + <li><a href="https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/First_steps/Variables">儲存你需要的資訊 — 變數</a></li> + <li><a href="https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/First_steps/Math">JavaScript 的基本運算— 數字 與 運算子</a></li> + <li><a href="https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/First_steps/Strings">處理文字 — JavaScript 的字串</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods">Useful string methods</a> <a href="https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/First_steps/Useful_string_methods">有用的字串方法</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays">Arrays</a> <a href="https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/First_steps/Arrays">陣列</a></li> + <li><a href="https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/First_steps/Silly_story_generator">傻故事產生器</a></li> +</ul> diff --git a/files/zh-tw/learn/javascript/first_steps/strings/index.html b/files/zh-tw/learn/javascript/first_steps/strings/index.html new file mode 100644 index 0000000000..8e4a3b1f6a --- /dev/null +++ b/files/zh-tw/learn/javascript/first_steps/strings/index.html @@ -0,0 +1,352 @@ +--- +title: 處理文字 - JavaScript中的字串 +slug: Learn/JavaScript/First_steps/Strings +tags: + - JavaScript + - 初學者 + - 字串 + - 引號 + - 文章 + - 連接字串 +translation_of: Learn/JavaScript/First_steps/Strings +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps")}}</div> + +<p class="summary">接下來我們將把注意力轉向字串——這就是程式設計中調用的文字片段。在本文中,我們將介紹在學習JavaScript時您應該了解所有有關字串的常見事項,例如建立字串,跳脫字串中的引號以及將字串連接在一起。</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">先備知識:</th> + <td>基本的電腦素養、對 HTML 與 CSS 有基本的認識、對 JavaScript 有認識。</td> + </tr> + <tr> + <th scope="row">目標:</th> + <td>熟悉 JavaScript 字串的基礎。</td> + </tr> + </tbody> +</table> + +<h2 id="文字的力量">文字的力量</h2> + +<p>文字對人類而言非常重要——它關乎我們如何交流、溝通。Web 以文字為基底的媒介,它的設計讓人類可以進行交流並分享資訊,因此掌握文字如何在 Web 上呈現是很有用的。{{glossary("HTML")}} 提供文字的結構以及定義;{{glossary("CSS")}} 讓我們更精確地設定樣式;而 JavaScript 則包含許多操作字串的特性,例如:製作客製化的歡迎訊息、正確地顯示所需的文字標籤、排列所需的詞語順序等。</p> + +<p>到目前為止,所有我們課程上的編碼幾乎都包含一些字串的操作。</p> + +<h2 id="字串_—_基礎">字串 — 基礎</h2> + +<p>剛開始你會覺得字串與數字的處理方式很類似,但當你越深入就會了解到一些明顯的差異。讓我們從在 console 裡輸入一些基本的程式行來熟悉它吧!在下方,我們提供一個 Console (你也可以另開一個頁籤或視窗<a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/variables/index.html">使用他</a> ,或者使用瀏覽器的<a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">開發者工具</a>)。</p> + +<div class="hidden"> +<h6 id="Hidden_code">Hidden code</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>JavaScript console</title> + <style> + * { + box-sizing: border-box; + } + + html { + background-color: #0C323D; + color: #809089; + font-family: monospace; + } + + body { + max-width: 700px; + } + + p { + margin: 0; + width: 1%; + padding: 0 1%; + font-size: 16px; + line-height: 1.5; + float: left; + } + + .input p { + margin-right: 1%; + } + + .output p { + width: 100%; + } + + .input input { + width: 96%; + float: left; + border: none; + font-size: 16px; + line-height: 1.5; + font-family: monospace; + padding: 0; + background: #0C323D; + color: #809089; + } + + div { + clear: both; + } + + </style> + </head> + <body> + + + </body> + + <script> + var geval = eval; + function createInput() { + var inputDiv = document.createElement('div'); + var inputPara = document.createElement('p'); + var inputForm = document.createElement('input'); + + inputDiv.setAttribute('class','input'); + inputPara.textContent = '>'; + inputDiv.appendChild(inputPara); + inputDiv.appendChild(inputForm); + document.body.appendChild(inputDiv); + + if(document.querySelectorAll('div').length > 1) { + inputForm.focus(); + } + + inputForm.addEventListener('change', executeCode); + } + + function executeCode(e) { + try { + var result = geval(e.target.value); + } catch(e) { + var result = 'error — ' + e.message; + } + + var outputDiv = document.createElement('div'); + var outputPara = document.createElement('p'); + + outputDiv.setAttribute('class','output'); + outputPara.textContent = 'Result: ' + result; + outputDiv.appendChild(outputPara); + document.body.appendChild(outputDiv); + + e.target.disabled = true; + e.target.parentNode.style.opacity = '0.5'; + + createInput() + } + + createInput(); + + </script> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}</p> + +<h3 id="建立字串">建立字串</h3> + +<ol> + <li>首先,先輸入下面幾行程式碼: + <pre class="brush: js notranslate">let string = 'The revolution will not be televised.'; +string;</pre> + 就像我們對數字的操作,我們聲明一個變數,並用一個值(字串)來初始化它,而後傳回這個值。唯一的差異在於,你需要用引號包住你的值。</li> + <li>如果你沒有使用引號包住值,或缺少單一邊的引號,都會導致錯誤產生。試著輸入下面幾行程式碼: + <pre class="brush: js example-bad notranslate">let badString = This is a test; +let badString = 'This is a test; +let badString = This is a test';</pre> + 上述的程式無法運作,因為未使用引號包圍的文字都將被視為變數名稱、屬性名稱和保留字等。如果瀏覽器無法辨識它,便會產生錯誤(例如:「missing ; before statement」)。如果瀏覽器可以識別字段從哪裡開始,但無法找到字段的終點,意即缺少第二個引號,則會產生「unterminated string literal」的錯誤。如果你的程式出現了這樣的錯誤,檢查並確認自己的字串是否遺漏了任何引號。</li> + <li>如果你先定義了變數 <code>string</code> ,則以下程式碼可以正常運作。馬上來試試看: + <pre class="brush: js notranslate">let badString = string; +badString;</pre> + <code>badString</code> 會被設定跟 <code>string</code> 具有一樣的值。</li> +</ol> + +<h3 id="單引號與雙引號">單引號與雙引號</h3> + +<ol> + <li>在 JavaScript 中,你可以選擇用單引號或雙引號來包住字串。兩種方式都可行: + <pre class="brush: js notranslate">let sgl = 'Single quotes.'; +let dbl = "Double quotes"; +sgl; +dbl;</pre> + </li> + <li>兩種之間的差異非常小,取決於你個人的習慣與喜好。你可以選擇一種,並且固定使用它。交互使用兩種方式,容易造成混亂。特別是當你使用兩種不同的引號包住一個字串!這會導致錯誤回傳: + <pre class="brush: js example-bad notranslate">let badQuotes = 'What on earth?";</pre> + </li> + <li>瀏覽器會認為字串並沒有結束,沒有作為包住字串的引號,是可以出現在字串裡面的。看看下面的例子,兩種都是可行的: + <pre class="brush: js notranslate">let sglDbl = 'Would you eat a "fish supper"?'; +let dblSgl = "I'm feeling blue."; +sglDbl; +dblSgl;</pre> + </li> + <li>但是,字串中不可以再使用那個作為包住字串的引號。以下的程式行會出錯,因為瀏覽器無法判斷字串的結尾: + <pre class="brush: js example-bad notranslate">let bigmouth = 'I've got no right to take my place...';</pre> + This leads us very nicely into our next subject.</li> +</ol> + +<h3 id="字串中的跳脫字元(Escaping_characters)">字串中的跳脫字元(Escaping characters)</h3> + +<p>要修復先前出錯的那一行程式碼,我們需要解決引號的問題。跳脫字元(Escaping characters)的意思是我們需要確保它們被辨識為文字,而非程式碼本身。在 JavaScript 中,我們在字元的前面放一個反斜線解決這個問題。試試看這個:</p> + +<pre class="brush: js notranslate">let bigmouth = 'I\'ve got no right to take my place...'; +bigmouth;</pre> + +<p>這是可行的!你可以用一樣的方法跳脫其他字元,例如 <code>\"</code>。除此之外,還有一些特殊方法。更詳細的部分,請參閱<a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#Escape_notation">跳脫符號</a> 。</p> + +<h2 id="連接字串(Concatenating_strings)">連接字串(Concatenating strings)</h2> + +<ol> + <li>連接(Concatenate)是一個新潮的程式用語。在 JavaScript 中,使用加號(+)將字串連接;這也是我們做數字相加的方式。但在這個狀況下,它有不同的作用。讓我們在 console 中示範:</li> + <li> + <pre class="brush: js notranslate">let one = 'Hello, '; +let two = 'how are you?'; +let joined = one + two; +joined;</pre> + 這邊的結果是 <code>joined</code> 這個變數中,有了 「Hello, how are you?」這個值。</li> + <li>在上一個範例中,我們只連接了兩個字串。但只要你在兩個字串之間加上 <code>+</code> ,那你要連接幾個都可以。試試看這個: + <pre class="brush: js notranslate">let multiple = one + one + one + one + two; +multiple;</pre> + </li> + <li>你也可以結合變數和字串。試試看這個: + <pre class="brush: js notranslate">let response = one + 'I am fine — ' + two; +response;</pre> + </li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: 當你輸入一個字串在你的程式碼中,並用單引號或雙引號將它括起來,它稱為<strong>字串文字</strong>(<strong>string literal</strong>)。</p> +</div> + +<h3 id="Concatenation_in_context">Concatenation in context</h3> + +<p>讓我們看看實際運用連接字串的例子——以下是這堂課中稍早的範例:</p> + +<pre class="brush: html notranslate"><button>Press me</button></pre> + +<pre class="brush: js notranslate">const button = document.querySelector('button'); + +button.onclick = function() { + let name = prompt('What is your name?'); + alert('Hello ' + name + ', nice to see you!'); +}</pre> + +<p>{{ EmbedLiveSample('Concatenation_in_context', '100%', 50, "", "", "hide-codepen-jsfiddle") }}</p> + +<p>在程式第四行我們用了 {{domxref("window.prompt()", "window.prompt()")}} 這個函式,可以要求使用者透過彈出的對話框去回答問題,並將使用者輸入的文字儲存在給訂的變數內(在這個例子中就是 <code>name</code>)。接著我們在第五行用了 {{domxref("window.alert()", "window.alert()")}} 函式,顯示另一個彈出視窗,以連接的方式將兩段字串文字以及 <code>name</code> 這個變數結合成一個字串。</p> + +<h3 id="數字_vs._字串">數字 vs. 字串</h3> + +<ol> + <li>那麼我們將字串和數字連接會發生什麼事呢?讓我們在console中試試看: + <pre class="brush: js notranslate">'Front ' + 242; +</pre> + 或許你預期會跑出錯誤訊息,但看來依然正常運作。若將字串表示成數字似乎不太合理,但將數字表示成字串看來是可行的,所以瀏覽器便會巧妙地將數字轉換成字串,並將這兩個字串連接在一起。</li> + <li>你也可以用兩個數字做這個例子 — 將這兩個數字包在引號中強制將它們轉換成字串。試試看(並使用typeof這個運算子去檢查變數是數字或字串): + <pre class="brush: js notranslate">let myDate = '19' + '67'; +typeof myDate;</pre> + </li> + <li>如果你想轉換數字變數成字串,但不要更動到原本的變數;或是想轉換字串變數成數字,也不要更動到原本的變數,你可以使用以下兩種方式: + <ul> + <li>物件 {{jsxref("Number")}} 會將欲處理的變數轉換成數字(如果可行的話)。試試以下例子: + <pre class="brush: js notranslate">let myString = '123'; +let myNum = Number(myString); +typeof myNum;</pre> + </li> + <li>另一方面,也有 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString">toString()</a></code> 方法能夠讓數字轉換為相等的字串。試試看: + <pre class="brush: js notranslate">let myNum = 123; +let myString = myNum.toString(); +typeof myString;</pre> + </li> + </ul> + 這些結構在某些情況相當好用。舉例來說:如果使用者在文字表單中輸入了一個數字,這個數字將會是字串格式。而若想要把這個數字加上另一個數字,那你會希望它是數字格式(才能做數字相加),所以可以使用 <code>Number()</code> 來處理這個情況。可以看看實際案例:<a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/first-splash/number-guessing-game.html#L61">猜數字遊戲, 第61行</a>。</li> +</ol> + +<h2 id="模版字符串Template_literals">模版字符串(Template literals)</h2> + +<p>另一種你會遇上的字串語法是<strong>模版字符串(template literals)</strong> (也稱做模版字串 template strings)。這是一種更新的語法提供更彈性、簡單的方式去理解字串。</p> + +<div class="blockIndicator note"> +<p><strong>Note</strong>: 嘗試在你的瀏覽器上測試下面的範例,來看看會得到什麼結果。</p> +</div> + +<p>將標準字串轉變為模版字符串,你需要將引號 (<code>' '</code>, or <code>" "</code>) 換為重音符 (backtick characters (<code>` `</code>) ),接著來看一個簡單的例子:</p> + +<pre class="brush: js notranslate">let song = 'Fight the Youth';</pre> + +<p>轉換成模版字符串會像這樣子:</p> + +<pre class="brush: js notranslate">song = `Fight the Youth`;</pre> + +<p>如果我們想要連接字串,或是將算式的結果包含在裡面,用傳統的字串去寫會很瑣碎且麻煩:</p> + +<pre class="brush: js notranslate">let score = 9; +let highestScore = 10; +let output = 'I like the song "' + song + '". I gave it a score of ' + (score/highestScore * 100) + '%.';</pre> + +<p>模版字符串能大量簡化這串程式碼:</p> + +<pre class="brush: js notranslate">output = `I like the song "${ song }". I gave it a score of ${ score/highestScore * 100 }%.`;</pre> + +<p>全部一串都只需要包含在一對重音符號裡,不再需要切開、合起一堆字串碎片。<br> + 當你想要包含變數或者算式在字串裡時,你只需要將它放在 <em>佔位符 </em><code>${ } </code>裡。</p> + +<p>你能將複雜的算式包含在模版字符串裡,舉個例子:</p> + +<pre class="brush: js notranslate">let examScore = 45; +let examHighestScore = 70; +examReport = `You scored ${ examScore }/${ examHighestScore } (${ Math.round((examScore/examHighestScore*100)) }%). ${ examScore >= 49 ? 'Well done, you passed!' : 'Bad luck, you didn\'t pass this time.' }`; +</pre> + +<ul> + <li>前兩個佔位符非常好理解,字串裡只包含了單一值。</li> + <li>第三個計算了一個百分比的結果且四捨五入進整數。</li> + <li>第四個使用了三元運算符來檢查分數是否高於指定分數且印出一個通過或著失敗的訊息結果。</li> +</ul> + +<p>另一個可以注意的點是,如果你想要將傳統字串拆分成多行,你需要加上一個斷行字母, <code>\n</code></p> + +<pre class="brush: js notranslate">output = 'I like the song "' + song + '".\nI gave it a score of ' + (score/highestScore * 100) + '%.';</pre> + +<p>模版字符串保留了程式碼中的斷行方式,所以不再需要使用斷行字母。<br> + 這樣也能達到相同的結果:</p> + +<pre class="brush: js notranslate">output = `I like the song "${ song }". +I gave it a score of ${ score/highestScore * 100 }%.`;</pre> + +<p>我們建議你盡可能習慣使用模版字符串。現今流行的瀏覽器都能完好的支援它,只有一個地方你能發現它並不支援外: Internet Explorer。<br> + 我們有許多的例子仍然使用目前標準的字串語法,但我們未來將會加入更多模版字符串的應用。</p> + +<p>來我們的<a href="/en-US/docs/Web/JavaScript/Reference/Template_literals">Template literals</a> 相關頁面看看更多的範例與進階的特色細節。</p> + +<h2 id="測試您的技能!">測試您的技能!</h2> + +<p>你已到達文章的結尾了,但你能記得最重要的資訊嗎?<br> + 在繼續學習之前,你可以找些難一點的測驗,來檢測你有記得這些知識 — <a href="/en-US/docs/Learn/JavaScript/First_steps/Test_your_skills:_Strings">Test your skills: Strings</a>. 記住,接下來的文章也需要這些知識,所以你可能想先看看。</p> + +<h2 id="結語">結語</h2> + +<p>以上是JavaScript中基礎的字串觀念。下個文章中,我們會依循這些概念並試試一些適用於字串的內建方法,進而運用這些方法讓字串能照我們想要的方式呈現。</p> + +<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps")}}</p> + +<h2 id="在這個學習模組中">在這個學習模組中</h2> + +<ul> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_is_JavaScript">什麼是 JavaScript?</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/A_first_splash">和 JavaScript 的第一次接觸</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_went_wrong">什麼出錯了?JavaScript 的疑難排解(除錯)</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Variables">儲存你需要的資訊 — 變數</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Math">JavaScript 的基本運算— 數字 與 運算子</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Strings">處理文字 - JavaScript 的字串</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Useful_string_methods">有用的字串方法</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Arrays">陣列</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Silly_story_generator">附錄:笑話產生器</a></li> +</ul> diff --git a/files/zh-tw/learn/javascript/first_steps/useful_string_methods/index.html b/files/zh-tw/learn/javascript/first_steps/useful_string_methods/index.html new file mode 100644 index 0000000000..e5efb51e1b --- /dev/null +++ b/files/zh-tw/learn/javascript/first_steps/useful_string_methods/index.html @@ -0,0 +1,714 @@ +--- +title: 有用的字符串方法 +slug: Learn/JavaScript/First_steps/Useful_string_methods +translation_of: Learn/JavaScript/First_steps/Useful_string_methods +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}</div> + +<p class="summary">現在我們已經了解了字符串的基礎知識,讓我們開始思考我們可以使用內置方法對字符串執行哪些有用的操作,例如查找文本字符串的長度,連接和拆分字符串 ,將字符串中的一個字符替換為另一個字符,等等。</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">先備知識:</th> + <td>基礎的電腦素養、基本的HTML和CSS、以及清楚什麼是JavaScript。</td> + </tr> + <tr> + <th scope="row">目標:</th> + <td>了解字串是物件,學習使用一些能夠應用這些字串的基礎方法。</td> + </tr> + </tbody> +</table> + +<h2 id="把字串當作物件">把字串當作物件</h2> + +<p id="Useful_string_methods">我們曾經說過,現在我們重申一遍—在javascript中,一切東西都可以被當作物件。例如我們創建一個字串。</p> + +<pre class="brush: js notranslate">var string = 'This is my string';</pre> + +<p>你的變數成為一個字串的實體物件,因此它將有許多性質(properties)與功能(methods)可以使用。</p> + +<p>你的變數成為一個字串的實體物件,因此它將有許多性質(properties)與功能(methods)可以使用。你可以到 {{jsxref("String")}} 物件頁面的左方列表查看這些性質與功能!</p> + +<p><strong>好的,在你腦袋燒壞之前先別擔心!</strong>在這趟學習旅程中,關於這些大部分對於現在的你其實還不需要知道。不過有一些你可能會經常使用,我們將在這裡介紹。</p> + +<p>Let's enter some examples into a fresh console. We've provided one below (you can also <a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/variables/index.html">open this console</a> in a separate tab or window, or use the <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">browser developer console</a> if you'd prefer).</p> + +<div class="hidden"> +<h6 id="Hidden_code">Hidden code</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>JavaScript console</title> + <style> + * { + box-sizing: border-box; + } + + html { + background-color: #0C323D; + color: #809089; + font-family: monospace; + } + + body { + max-width: 700px; + } + + p { + margin: 0; + width: 1%; + padding: 0 1%; + font-size: 16px; + line-height: 1.5; + float: left; + } + + .input p { + margin-right: 1%; + } + + .output p { + width: 100%; + } + + .input input { + width: 96%; + float: left; + border: none; + font-size: 16px; + line-height: 1.5; + font-family: monospace; + padding: 0; + background: #0C323D; + color: #809089; + } + + div { + clear: both; + } + + </style> + </head> + <body> + + + </body> + + <script> + var geval = eval; + function createInput() { + var inputDiv = document.createElement('div'); + var inputPara = document.createElement('p'); + var inputForm = document.createElement('input'); + + inputDiv.setAttribute('class', 'input'); + inputPara.textContent = '>'; + inputDiv.appendChild(inputPara); + inputDiv.appendChild(inputForm); + document.body.appendChild(inputDiv); + + inputForm.addEventListener('change', executeCode); + } + + function executeCode(e) { + try { + var result = geval(e.target.value); + } catch(e) { + var result = 'error — ' + e.message; + } + + var outputDiv = document.createElement('div'); + var outputPara = document.createElement('p'); + + outputDiv.setAttribute('class','output'); + outputPara.textContent = 'Result: ' + result; + outputDiv.appendChild(outputPara); + document.body.appendChild(outputDiv); + + e.target.disabled = true; + e.target.parentNode.style.opacity = '0.5'; + + createInput() + } + + createInput(); + + </script> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}</p> + +<h3 id="找出字串的長度(length)">找出字串的長度(length)</h3> + +<p>這很簡單,你可以用 {{jsxref("String.prototype.length", "length")}} 屬性。試著輸入下面幾行:</p> + +<pre class="brush: js notranslate">var browserType = 'mozilla'; +browserType.length;</pre> + +<p>結果應該會回傳數字7,因為 "mozilla" 字元長度是7。 這在很多狀況下很好用,舉例來說:你會想知道序列的長度,這樣才能將這些序列按照長度排序,或是讓使用者知道他們輸入的名稱是否太長。</p> + +<h3 id="取得字串中的特定字元(string_character)">取得字串中的特定字元(string character)</h3> + +<p>On a related note, you can return any character inside a string by using <strong>square bracket notation</strong> — this means you include square brackets (<code>[]</code>) on the end of your variable name. Inside the square brackets you include the number of the character you want to return, so for example to retrieve the first letter you'd do this:</p> + +<pre class="brush: js notranslate">browserType[0];</pre> + +<p>記得電腦計數從0開始,不是1! 如果要在<em>任何</em>一個字串中取得最後一個字元,我們可以使用以下程式碼,結合了取得字元的技巧和上面學過的長度屬性:</p> + +<pre class="brush: js notranslate">browserType[browserType.length-1];</pre> + +<p>"mozilla" 這個詞的長度是7,但因為電腦是從0開始計數,所以最後一個位置是6,因此我們會將 <code>length-1</code> 。你也可以試試用這個方法找各序列的第一個字母,並將這些序列按字母順序排好 。</p> + +<h3 id="尋找字串中的子字串(substring)並提出子字串">尋找字串中的子字串(substring)並提出子字串</h3> + +<ol> + <li>Sometim有時候你會想搜尋是否有一個較小的字串存在於比較大的字串中(<em>我們通常會說是否有個子字串存在於字串中</em>)。這可以用 {{jsxref("String.prototype.indexOf()", "indexOf()")}} 方法,當中需要一個參數( {{glossary("parameter")}} ),也就是你想搜尋的子字串:</li> + <li> + <pre class="brush: js notranslate">browserType.indexOf('zilla');</pre> + 結果會傳回2,因為子字串 "zilla" 在 "mozilla" 中是從位置2開始的。(依然要記得電腦計數是從0開始)。這個方法可以用篩選字串,舉例來說:我們有一串網址的清單,而我們只想印出那些包含 "mozilla" 的網址。</li> +</ol> + +<ol start="2"> + <li>This can be done in another way, which is possibly even more effective. Try the following: + <pre class="brush: js notranslate">browserType.indexOf('vanilla');</pre> + This should give you a result of <code>-1</code> — this is returned when the substring, in this case 'vanilla', is not found in the main string.<br> + <br> + You could use this to find all instances of strings that <strong>don't</strong> contain the substring 'mozilla', or <strong>do,</strong> if you use the negation operator, as shown below. You could do something like this: + + <pre class="brush: js notranslate">if(browserType.indexOf('mozilla') !== -1) { + // do stuff with the string +}</pre> + </li> + <li>When you know where a substring starts inside a string, and you know at which character you want it to end, {{jsxref("String.prototype.slice()", "slice()")}} can be used to extract it. Try the following: + <pre class="brush: js notranslate">browserType.slice(0,3);</pre> + This returns "moz" — the first parameter is the character position to start extracting at, and the second parameter is the character position after the last one to be extracted. So the slice happens from the first position, up to, but not including, the last position. In this example, since the starting index is 0, the second parameter is equal to the length of the string being returned.<br> + </li> + <li>Also, if you know that you want to extract all of the remaining characters in a string after a certain character, you don't have to include the second parameter! Instead, you only need to include the character position from where you want to extract the remaining characters in a string. Try the following: + <pre class="brush: js notranslate">browserType.slice(2);</pre> + This returns "zilla" — this is because the character position of 2 is the letter z, and because you didn't include a second parameter, the substring that was returned was all of the remaining characters in the string. </li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: The second parameter of <code>slice()</code> is optional: if you don't include it, the slice ends at the end of the original string. There are other options too; study the {{jsxref("String.prototype.slice()", "slice()")}} page to see what else you can find out.</p> +</div> + +<h3 id="改變大小寫">改變大小寫</h3> + +<p>The string methods {{jsxref("String.prototype.toLowerCase()", "toLowerCase()")}} and {{jsxref("String.prototype.toUpperCase()", "toUpperCase()")}} take a string and convert all the characters to lower- or uppercase, respectively. This can be useful for example if you want to normalize all user-entered data before storing it in a database.</p> + +<p>Let's try entering the following lines to see what happens:</p> + +<pre class="brush: js notranslate">var radData = 'My NaMe Is MuD'; +radData.toLowerCase(); +radData.toUpperCase();</pre> + +<h3 id="更動部分字串">更動部分字串</h3> + +<p>You can replace one substring inside a string with another substring using the {{jsxref("String.prototype.replace()", "replace()")}} method. This works very simply at a basic level, although there are some advanced things you can do with it that we won't go into yet.</p> + +<p>It takes two parameters — the string you want to replace, and the string you want to replace it with. Try this example:</p> + +<pre class="brush: js notranslate">browserType.replace('moz','van');</pre> + +<p>Note that to actually get the updated value reflected in the <code>browserType</code> variable in a real program, you'd have to set the variable value to be the result of the operation; it doesn't just update the substring value automatically. So you'd have to actually write this: <code>browserType = browserType.replace('moz','van');</code></p> + +<h2 id="Active_learning_examples">Active learning examples</h2> + +<p>In this section we'll get you to try your hand at writing some string manipulation code. In each exercise below, we have an array of strings, and a loop that processes each value in the array and displays it in a bulleted list. You don't need to understand arrays or loops right now — these will be explained in future articles. All you need to do in each case is write the code that will output the strings in the format that we want them in.</p> + +<p>Each example comes with a "Reset" button, which you can use to reset the code if you make a mistake and can't get it working again, and a "Show solution" button you can press to see a potential answer if you get really stuck.</p> + +<h3 id="Filtering_greeting_messages">Filtering greeting messages</h3> + +<p>In the first exercise we'll start you off simple — we have an array of greeting card messages, but we want to sort them to list just the Christmas messages. We want you to fill in a conditional test inside the <code>if( ... )</code> structure, to test each string and only print it in the list if it is a Christmas message.</p> + +<ol> + <li>First think about how you could test whether the message in each case is a Christmas message. What string is present in all of those messages, and what method could you use to test whether it is present?</li> + <li>You'll then need to write a conditional test of the form <em>operand1 operator operand2</em>. Is the thing on the left equal to the thing on the right? Or in this case, does the method call on the left return the result on the right?</li> + <li>Hint: In this case it is probably more useful to test whether the method call <em>isn't</em> equal to a certain result.</li> +</ol> + +<div class="hidden"> +<h6 id="Playable_code">Playable code</h6> + +<pre class="brush: html notranslate"><h2>Live output</h2> + +<div class="output" style="min-height: 125px;"> + +<ul> + +</ul> + +</div> + +<h2>Editable code</h2> +<p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> + +<textarea id="code" class="playable-code" style="height: 290px; width: 95%"> +var list = document.querySelector('.output ul'); +list.innerHTML = ''; +var greetings = ['Happy Birthday!', + 'Merry Christmas my love', + 'A happy Christmas to all the family', + 'You\'re all I want for Christmas', + 'Get well soon']; + +for (var i = 0; i < greetings.length; i++) { + var input = greetings[i]; + // Your conditional test needs to go inside the parentheses + // in the line below, replacing what's currently there + if (greetings[i]) { + var result = input; + var listItem = document.createElement('li'); + listItem.textContent = result; + list.appendChild(listItem); + } +} +</textarea> + +<div class="playable-buttons"> + <input id="reset" type="button" value="Reset"> + <input id="solution" type="button" value="Show solution"> +</div> +</pre> + +<pre class="brush: css notranslate">html { + font-family: sans-serif; +} + +h2 { + font-size: 16px; +} + +.a11y-label { + margin: 0; + text-align: right; + font-size: 0.7rem; + width: 98%; +} + +body { + margin: 10px; + background: #f5f9fa; +}</pre> + +<pre class="brush: js notranslate">var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var solution = document.getElementById('solution'); +var code = textarea.value; +var userEntry = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + userEntry = textarea.value; + solutionEntry = jsSolution; + solution.value = 'Show solution'; + updateCode(); +}); + +solution.addEventListener('click', function() { + if(solution.value === 'Show solution') { + textarea.value = solutionEntry; + solution.value = 'Hide solution'; + } else { + textarea.value = userEntry; + solution.value = 'Show solution'; + } + updateCode(); +}); + +var jsSolution = 'var list = document.querySelector(\'.output ul\');\nlist.innerHTML = \'\';\nvar greetings = [\'Happy Birthday!\',\n \'Merry Christmas my love\',\n \'A happy Christmas to all the family\',\n \'You\\\'re all I want for Christmas\',\n \'Get well soon\'];\n\nfor(var i = 0; i < greetings.length; i++) {\n var input = greetings[i];\n if(greetings[i].indexOf(\'Christmas\') !== -1) {\n var result = input;\n var listItem = document.createElement(\'li\');\n listItem.textContent = result;\n list.appendChild(listItem);\n }\n}'; +var solutionEntry = jsSolution; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); + +// stop tab key tabbing out of textarea and +// make it write a tab at the caret position instead + +textarea.onkeydown = function(e){ + if (e.keyCode === 9) { + e.preventDefault(); + insertAtCaret('\t'); + } + + if (e.keyCode === 27) { + textarea.blur(); + } +}; + +function insertAtCaret(text) { + var scrollPos = textarea.scrollTop; + var caretPos = textarea.selectionStart; + + var front = (textarea.value).substring(0, caretPos); + var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); + textarea.value = front + text + back; + caretPos = caretPos + text.length; + textarea.selectionStart = caretPos; + textarea.selectionEnd = caretPos; + textarea.focus(); + textarea.scrollTop = scrollPos; +} + +// Update the saved userCode every time the user updates the text area code + +textarea.onkeyup = function(){ + // We only want to save the state when the user code is being shown, + // not the solution, so that solution is not saved over the user code + if(solution.value === 'Show solution') { + userEntry = textarea.value; + } else { + solutionEntry = textarea.value; + } + + updateCode(); +};</pre> +</div> + +<p>{{ EmbedLiveSample('Playable_code', '100%', 590, "", "", "hide-codepen-jsfiddle") }}</p> + +<h3 id="Fixing_capitalization">Fixing capitalization</h3> + +<p>In this exercise we have the names of cities in the United Kingdom, but the capitalization is all messed up. We want you to change them so that they are all lower case, except for a capital first letter. A good way to do this is to:</p> + +<ol> + <li>Convert the whole of the string contained in the <code>input</code> variable to lower case and store it in a new variable.</li> + <li>Grab the first letter of the string in this new variable and store it in another variable.</li> + <li>Using this latest variable as a substring, replace the first letter of the lowercase string with the first letter of the lowercase string changed to upper case. Store the result of this replace procedure in another new variable.</li> + <li>Change the value of the <code>result</code> variable to equal to the final result, not the <code>input</code>.</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: A hint — the parameters of the string methods don't have to be string literals; they can also be variables, or even variables with a method being invoked on them.</p> +</div> + +<div class="hidden"> +<h6 id="Playable_code_2">Playable code 2</h6> + +<pre class="brush: html notranslate"><h2>Live output</h2> + +<div class="output" style="min-height: 125px;"> + +<ul> + +</ul> + +</div> + +<h2>Editable code</h2> +<p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> + +<textarea id="code" class="playable-code" style="height: 250px; width: 95%"> +var list = document.querySelector('.output ul'); +list.innerHTML = ''; +var cities = ['lonDon', 'ManCHESTer', 'BiRmiNGHAM', 'liVERpoOL']; +for(var i = 0; i < cities.length; i++) { + var input = cities[i]; + // write your code just below here + + var result = input; + var listItem = document.createElement('li'); + listItem.textContent = result; + list.appendChild(listItem); +} +</textarea> + +<div class="playable-buttons"> + <input id="reset" type="button" value="Reset"> + <input id="solution" type="button" value="Show solution"> +</div> +</pre> + +<pre class="brush: css notranslate">html { + font-family: sans-serif; +} + +h2 { + font-size: 16px; +} + +.a11y-label { + margin: 0; + text-align: right; + font-size: 0.7rem; + width: 98%; +} + +body { + margin: 10px; + background: #f5f9fa; +}</pre> + +<pre class="brush: js notranslate">var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var solution = document.getElementById('solution'); +var code = textarea.value; +var userEntry = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + userEntry = textarea.value; + solutionEntry = jsSolution; + solution.value = 'Show solution'; + updateCode(); +}); + +solution.addEventListener('click', function() { + if(solution.value === 'Show solution') { + textarea.value = solutionEntry; + solution.value = 'Hide solution'; + } else { + textarea.value = userEntry; + solution.value = 'Show solution'; + } + updateCode(); +}); + +var jsSolution = 'var list = document.querySelector(\'.output ul\');\nlist.innerHTML = \'\';\nvar cities = [\'lonDon\', \'ManCHESTer\', \'BiRmiNGHAM\', \'liVERpoOL\'];\n\nfor(var i = 0; i < cities.length; i++) {\n var input = cities[i];\n var lower = input.toLowerCase();\n var firstLetter = lower.slice(0,1);\n var capitalized = lower.replace(firstLetter,firstLetter.toUpperCase());\n var result = capitalized;\n var listItem = document.createElement(\'li\');\n listItem.textContent = result;\n list.appendChild(listItem);\n\n}'; +var solutionEntry = jsSolution; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); + +// stop tab key tabbing out of textarea and +// make it write a tab at the caret position instead + +textarea.onkeydown = function(e){ + if (e.keyCode === 9) { + e.preventDefault(); + insertAtCaret('\t'); + } + + if (e.keyCode === 27) { + textarea.blur(); + } +}; + +function insertAtCaret(text) { + var scrollPos = textarea.scrollTop; + var caretPos = textarea.selectionStart; + + var front = (textarea.value).substring(0, caretPos); + var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); + textarea.value = front + text + back; + caretPos = caretPos + text.length; + textarea.selectionStart = caretPos; + textarea.selectionEnd = caretPos; + textarea.focus(); + textarea.scrollTop = scrollPos; +} + +// Update the saved userCode every time the user updates the text area code + +textarea.onkeyup = function(){ + // We only want to save the state when the user code is being shown, + // not the solution, so that solution is not saved over the user code + if(solution.value === 'Show solution') { + userEntry = textarea.value; + } else { + solutionEntry = textarea.value; + } + + updateCode(); +};</pre> +</div> + +<p>{{ EmbedLiveSample('Playable_code_2', '100%', 550, "", "", "hide-codepen-jsfiddle") }}</p> + +<h3 id="Making_new_strings_from_old_parts">Making new strings from old parts</h3> + +<p>In this last exercise, the array contains a bunch of strings containing information about train stations in the North of England. The strings are data items that contain the three-letter station code, followed by some machine-readable data, followed by a semicolon, followed by the human-readable station name. For example:</p> + +<pre class="notranslate">MAN675847583748sjt567654;Manchester Piccadilly</pre> + +<p>We want to extract the station code and name, and put them together in a string with the following structure:</p> + +<pre class="notranslate">MAN: Manchester Piccadilly</pre> + +<p>We'd recommend doing it like this:</p> + +<ol> + <li>Extract the three-letter station code and store it in a new variable.</li> + <li>Find the character index number of the semicolon.</li> + <li>Extract the human-readable station name using the semicolon character index number as a reference point, and store it in a new variable.</li> + <li>Concatenate the two new variables and a string literal to make the final string.</li> + <li>Change the value of the <code>result</code> variable to equal to the final string, not the <code>input</code>.</li> +</ol> + +<div class="hidden"> +<h6 id="Playable_code_3">Playable code 3</h6> + +<pre class="brush: html notranslate"><h2>Live output</h2> + +<div class="output" style="min-height: 125px;"> + +<ul> + +</ul> + +</div> + +<h2>Editable code</h2> +<p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> + +<textarea id="code" class="playable-code" style="height: 285px; width: 95%"> +var list = document.querySelector('.output ul'); +list.innerHTML = ''; +var stations = ['MAN675847583748sjt567654;Manchester Piccadilly', + 'GNF576746573fhdg4737dh4;Greenfield', + 'LIV5hg65hd737456236dch46dg4;Liverpool Lime Street', + 'SYB4f65hf75f736463;Stalybridge', + 'HUD5767ghtyfyr4536dh45dg45dg3;Huddersfield']; + +for (var i = 0; i < stations.length; i++) { + var input = stations[i]; + // write your code just below here + + var result = input; + var listItem = document.createElement('li'); + listItem.textContent = result; + list.appendChild(listItem); +} +</textarea> + +<div class="playable-buttons"> + <input id="reset" type="button" value="Reset"> + <input id="solution" type="button" value="Show solution"> +</div> +</pre> + +<pre class="brush: css notranslate">html { + font-family: sans-serif; +} + +h2 { + font-size: 16px; +} + +.a11y-label { + margin: 0; + text-align: right; + font-size: 0.7rem; + width: 98%; +} + +body { + margin: 10px; + background: #f5f9fa; +} +</pre> + +<pre class="brush: js notranslate">var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var solution = document.getElementById('solution'); +var code = textarea.value; +var userEntry = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + userEntry = textarea.value; + solutionEntry = jsSolution; + solution.value = 'Show solution'; + updateCode(); +}); + +solution.addEventListener('click', function() { + if(solution.value === 'Show solution') { + textarea.value = solutionEntry; + solution.value = 'Hide solution'; + } else { + textarea.value = userEntry; + solution.value = 'Show solution'; + } + updateCode(); +}); + +var jsSolution = 'var list = document.querySelector(\'.output ul\');\nlist.innerHTML = \'\';\nvar stations = [\'MAN675847583748sjt567654;Manchester Piccadilly\',\n \'GNF576746573fhdg4737dh4;Greenfield\',\n \'LIV5hg65hd737456236dch46dg4;Liverpool Lime Street\',\n \'SYB4f65hf75f736463;Stalybridge\',\n \'HUD5767ghtyfyr4536dh45dg45dg3;Huddersfield\'];\n\nfor(var i = 0; i < stations.length; i++) {\n var input = stations[i];\n var code = input.slice(0,3);\n var semiC = input.indexOf(\';\');\n var name = input.slice(semiC + 1);\n var result = code + \': \' + name;\n var listItem = document.createElement(\'li\');\n listItem.textContent = result;\n list.appendChild(listItem);\n}'; +var solutionEntry = jsSolution; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); + +// stop tab key tabbing out of textarea and +// make it write a tab at the caret position instead + +textarea.onkeydown = function(e){ + if (e.keyCode === 9) { + e.preventDefault(); + insertAtCaret('\t'); + } + + if (e.keyCode === 27) { + textarea.blur(); + } +}; + +function insertAtCaret(text) { + var scrollPos = textarea.scrollTop; + var caretPos = textarea.selectionStart; + + var front = (textarea.value).substring(0, caretPos); + var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); + textarea.value = front + text + back; + caretPos = caretPos + text.length; + textarea.selectionStart = caretPos; + textarea.selectionEnd = caretPos; + textarea.focus(); + textarea.scrollTop = scrollPos; +} + +// Update the saved userCode every time the user updates the text area code + +textarea.onkeyup = function(){ + // We only want to save the state when the user code is being shown, + // not the solution, so that solution is not saved over the user code + if(solution.value === 'Show solution') { + userEntry = textarea.value; + } else { + solutionEntry = textarea.value; + } + + updateCode(); +};</pre> +</div> + +<p>{{ EmbedLiveSample('Playable_code_3', '100%', 585, "", "", "hide-codepen-jsfiddle") }}</p> + +<h2 id="結語">結語</h2> + +<p>不可否認當網站在跟人們互相溝通時,處理文字和句子在程式設計中是相當重要的,尤其是在 JavaScript 中。這篇文章已經傳授你如何去處理字串的方法,應該對以後深入了解其他更複雜主題的你會很有幫助。接下來,我們將會看看最後一個近期內我們需要關注的主要的資料型態 — 陣列。</p> + +<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}</p> + +<h2 id="在這個學習模組中">在這個學習模組中</h2> + +<ul> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_is_JavaScript">什麼是 JavaScript?</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/A_first_splash">和 JavaScript 的第一次接觸</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_went_wrong">什麼出錯了? JavaScript 的疑難排解(除錯)</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Variables">儲存你需要的資訊 — 變數</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Math">JavaScript 的基本運算— 數字 與 運算子</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Strings">處理文字 — JavaScript 的字串</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Useful_string_methods">有用的字串方法</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Arrays">陣列</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Silly_story_generator">附錄:笑話產生器</a></li> +</ul> diff --git a/files/zh-tw/learn/javascript/first_steps/variables/index.html b/files/zh-tw/learn/javascript/first_steps/variables/index.html new file mode 100644 index 0000000000..1fce3a98fe --- /dev/null +++ b/files/zh-tw/learn/javascript/first_steps/variables/index.html @@ -0,0 +1,344 @@ +--- +title: 存儲您需要的資訊 - 變數 +slug: Learn/JavaScript/First_steps/Variables +tags: + - JavaScript + - 變數 + - 陣列 +translation_of: Learn/JavaScript/First_steps/Variables +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps")}}</div> + +<p class="summary">閱讀完最後幾篇文章之後,您現在應該知道 JavaScript 是什麼,它可以為您做什麼,如何將它與其他 Web 技術一起使用,以及它的主要功能從高層看起來如何。 在本文中,我們將深入了解真正的基礎知識,了解如何使用 JavaScript 的大多數基本構建塊 - 變數。</p> + +<table class="learn-box"> + <tbody> + <tr> + <th scope="row">必備知識:</th> + <td>電腦基礎知識,了解基本的 HTML 和 CSS ,了解 JavaScript 是什麼。</td> + </tr> + <tr> + <th scope="row">目標:</th> + <td>熟悉 JavaScript 變數的基本知識。</td> + </tr> + </tbody> +</table> + +<h2 id="您需要的工具">您需要的工具</h2> + +<p>在此篇文章中,您將被要求輸入程式碼行來測試您對內容的理解。如果您使用的是網頁瀏覽器,最適合輸入代碼的地方便是 JavaScript 主控台, (請參閱<a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">什麼是瀏覽器開發工具</a>這篇文章以取得更多關於此工具的資訊).</p> + +<h2 id="什麼是變量/變數_variable_?">什麼是變量/變數 (variable) ?</h2> + +<p>變量是值的容器,就像我們可能在總和中使用的數字,或者我們可能用作句子一部分的字符串。 但關於變量的一個特殊之處在於它們包含的值可以改變。 我們來看一個簡單的例子:</p> + +<pre class="brush: html notranslate"><button>請按我</button> +</pre> + +<pre class="brush: js notranslate">const button = document.querySelector('button'); + +button.onclick = function() { + let name = prompt('你叫什麼名字?'); + alert('你好 ' + name + ', 很高興認識你!'); +} +</pre> + +<p>{{ EmbedLiveSample('什麼是變量/變數_variable_?','100%', 50, "", "", "hide-codepen-jsfiddle") }}</p> + +<p>在此示例中,按下按鈕會運行幾行代碼。 第一行在屏幕上彈出一個框,要求讀者輸入其名稱,然後將值存儲在變量中。 第二行顯示歡迎消息,其中包含從變量值中獲取的名稱。</p> + +<p>要理解為什麼這麼有用,讓我們考慮如何在不使用變量的情況下編寫此示例。 它最終會看起來像這樣:</p> + +<pre class="example-bad notranslate">let name = prompt('What is your name?'); + +if (name === 'Adam') { + alert('Hello Adam, nice to see you!'); +} else if (name === 'Alan') { + alert('Hello Alan, nice to see you!'); +} else if (name === 'Bella') { + alert('Hello Bella, nice to see you!'); +} else if (name === 'Bianca') { + alert('Hello Bianca, nice to see you!'); +} else if (name === 'Chris') { + alert('Hello Chris, nice to see you!'); +} + +// ... 等等 ... +</pre> + +<p><font>你可能暫時還沒有完全理解這些代碼和語法,但是你應該能夠理解到</font> — <font>如果我們沒有變量,我們就不得不寫大量的代碼去檢查輸入的名字,然後顯示相應名稱的消息 。這樣做顯然是低效率(雖然例子中只有5種選擇,但代碼卻相對地長)和不可行的</font> — <font>你沒有辦法列舉出所有可能的名字。</font></p> + +<p>使用變量才是明智的。隨著您對 JavaScript 越來越了解,您會開始習慣使用變量。</p> + +<p><font>變量的另一個特性就是它們能夠存儲任何的東西</font> — <font>不只是字符串和數字。變量可以存儲更複雜的數據,甚至是函數。</font><font>你將在後續的內容中體驗到這些用法。</font></p> + +<div class="note"> +<p><strong><font><font>提示</font></font></strong>:變量是用來儲存數值的,而變量和數值是兩個不同的概念。變量不是數值本身,它們僅僅是一個用於儲存數值的容器。你可以把變量想像成一個個用來裝東西的紙皮箱。</p> +</div> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13506/boxes.png" style="display: block; height: 436px; margin: 0px auto; width: 1052px;"></p> + +<h2 id="定義變量_Declaring_a_variable">定義<font><font>變量 (Declaring a variable)</font></font></h2> + +<p><font>要想使用變量,你需要做的第一步就是創建它</font> — <font>更準確的說,是</font>定義<font>一個變量。</font>定義<font>一個變量的語法是在關鍵字</font> <code>var</code> 或 <code>let</code> <font>之後加上變量的名字:</font></p> + +<pre class="brush: js notranslate">let myName; +let myAge; +</pre> + +<p><font><font>在這裡我們</font></font>定義<font><font>了兩個變量 </font></font><code>myName</code><font><font> 和 </font></font><code>myAge</code><font><font>。那麼現在嘗試輸入這些代碼到你的瀏覽器終端。之後,嘗試使用您自己選擇的名稱來創建一兩個變量。</font></font></p> + +<div class="note"> +<p><strong>提示</strong>:<font><font>在 JavaScript 中,所有代碼指令都會以分號結尾( </font></font><code>;</code><font><font>)- 如果忘記加分號,你的單行代碼可能正常執行,但是在執行多行代碼的時候就可能出錯。所以,最好是養成主動以分號作為代碼結尾的習慣。</font></font></p> +</div> + +<p><font>你可以輸入變量的名稱,來驗證這個變量的數值是否在執行環境(</font>execution environment)<font>中已經存在。例如,</font></p> + +<pre class="brush: js notranslate">myName; +myAge; +</pre> + +<p><font><font>以上這兩個變量並沒有數值,他們是空的容器。當你輸入變量名並按輸入鍵後,你會得到一個 </font></font><code>undefined</code><font><font> (</font></font>沒有定義的值<font><font>)的返回值。如果</font>變量<font>並不存在的話,你就會得到一個錯誤信息。請嘗試輸入:</font></font></p> + +<pre class="brush: js notranslate">scoobyDoo;</pre> + +<div class="note"> +<p><strong><font><font>提示:</font></font></strong><font><font>千萬不要把兩個概念弄混淆了,「一個變量<strong>存在,但是沒有數值</strong>」和「一個變量<strong>並不存在</strong>」— 他們完全是兩回事。在前面你看到的盒子的類比中,不存在意味著沒有可以存放變量的「盒子」。</font><font>沒有定義的值意味著<strong>有</strong>一個「盒子」,但是它裡面沒有任何數值。</font></font></p> +</div> + +<h2 id="初始化變量_Initializing_a_variable">初始化變量 (Initializing a variable)</h2> + +<p>一旦你定義了一個變量,你就能夠初始化它來儲存數值。方法如下:在變量名之後跟上一個等號 (<code>=</code>),然後是數值。例如:</p> + +<pre class="brush: js notranslate">myName = 'Chris'; +myAge = 37;</pre> + +<p>Try going back to the console now and typing in these lines. You should see the value you've assigned to the variable returned in the console to confirm it, in each case. Again, you can return your variable values by simply typing their name into the console — try these again:</p> + +<pre class="brush: js notranslate">myName; +myAge;</pre> + +<p>你可以同時定義並初始化變量,像是:</p> + +<pre class="brush: js notranslate">let myDog = 'Rover';</pre> + +<p>This is probably what you'll do most of the time, as it is quicker than doing the two actions on two separate lines.</p> + +<h2 id="比較var和let的不同_The_difference_between_var_and_let">比較var和let的不同 (The difference between var and let)</h2> + +<p>此刻你或許會思考「為什麼我們需要兩種方法來定義變數??<font><font>」</font></font>「為甚麼要有<code>var</code>和<code>let</code>??<font><font>」</font></font></p> + +<p>原因有些歷史淵源。在Javascript剛被創造的時候,只有<code>var</code>可以使用。在大部分的情況下都很正常,但是<code>var</code>的運作方式有些問題 — 它的設計有時會令人困惑甚至惹惱人。所以<code>let</code>在現代版本中的Javascript被創造出來,一個與<code>var</code>工作原理有些不同的創建變數的關鍵字,修復了<code>var</code>的種種問題。</p> + +<p>以下將介紹幾個簡單的分別。我們現在不會一一講解全部的不同,但是當你慢慢深入Javascript,你將會開始發現它們的(如果你真的很想現在知道,歡迎看看我們的<a href="/zh-TW/docs/Web/JavaScript/Reference/Statements/let">let 介紹頁</a>)。</p> + +<p>如下,假設你需要宣告、初始化一個變數<code>myName</code>,即使你是初始化之後才宣告也是可行的:</p> + +<pre class="brush: js notranslate">myName = 'Chris'; + +function logName() { + console.log(myName); +} + +logName(); + +var myName;</pre> + +<div class="note"> +<p><strong>Note</strong>: This won't work when typing individual lines into a JavaScript console, just when running multiple lines of JavaScript in a web document.</p> +</div> + +<p>This works because of <strong>hoisting</strong> — read <a href="/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting">var hoisting</a> for more detail on the subject.</p> + +<p>Hoisting no longer works with <code>let</code>. If we changed <code>var</code> to <code>let</code> in the above example, it would fail with an error. This is a good thing — declaring a variable after you initialize it makes for confusing, harder to understand code.</p> + +<p>Secondly, when you use <code>var</code>, you can declare the same variable as many times as you like, but with <code>let</code> you can't. The following would work:</p> + +<pre class="brush: js notranslate">var myName = 'Chris'; +var myName = 'Bob';</pre> + +<p>But the following would throw an error on the second line:</p> + +<pre class="brush: js notranslate">let myName = 'Chris'; +let myName = 'Bob';</pre> + +<p>You'd have to do this instead:</p> + +<pre class="brush: js notranslate">let myName = 'Chris'; +myName = 'Bob';</pre> + +<p>Again, this is a sensible language decision. There is no reason to redeclare variables — it just makes things more confusing.</p> + +<p>For these reasons and more, we recommend that you use <code>let</code> as much as possible in your code, rather than <code>var</code>. There is no reason to use <code>var</code>, unless you need to support old versions of Internet Explorer with your code (it doesn't support <code>let</code> until version 11; the modern Windows Edge browser supports <code>let</code> just fine).</p> + +<div class="note"> +<p><strong>Note</strong>: We are currently in the process of updating the course to use <code>let</code> rather than <code>var</code>. Bear with us!</p> +</div> + +<h2 id="Updating_a_variable">Updating a variable</h2> + +<p>Once a variable has been initialized with a value, you can change (or update) that value by simply giving it a different value. Try entering the following lines into your console:</p> + +<pre class="brush: js notranslate">myName = 'Bob'; +myAge = 40;</pre> + +<h3 id="變數命名規則悄悄話">變數命名規則悄悄話</h3> + +<p>You can call a variable pretty much anything you like, but there are limitations. Generally, you should stick to just using Latin characters (0-9, a-z, A-Z) and the underscore character.</p> + +<ul> + <li>You shouldn't use other characters because they may cause errors or be hard to understand for an international audience.</li> + <li>Don't use underscores at the start of variable names — this is used in certain JavaScript constructs to mean specific things, so may get confusing.</li> + <li>Don't use numbers at the start of variables. This isn't allowed and will cause an error.</li> + <li>A safe convention to stick to is so-called <a href="https://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms">"lower camel case"</a>, where you stick together multiple words, using lower case for the whole first word and then capitalize subsequent words. We've been using this for our variable names in the article so far.</li> + <li>Make variable names intuitive, so they describe the data they contain. Don't just use single letters/numbers, or big long phrases.</li> + <li>Variables are case sensitive — so <code>myage</code> is a different variable to <code>myAge</code>.</li> + <li>One last point — you also need to avoid using JavaScript reserved words as your variable names — by this, we mean the words that make up the actual syntax of JavaScript! So, you can't use words like <code>var</code>, <code>function</code>, <code>let</code>, and <code>for</code> as variable names. Browsers will recognize them as different code items, and so you'll get errors.</li> +</ul> + +<div class="note"> +<p><strong>Note</strong>: You can find a fairly complete list of reserved keywords to avoid at <a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords">Lexical grammar — keywords</a>.</p> +</div> + +<p>良好的命名範例:</p> + +<pre class="example-good notranslate">age +myAge +init +initialColor +finalOutputValue +audio1 +audio2</pre> + +<p>不好的命名範例:</p> + +<pre class="example-bad notranslate">1 +a +_12 +myage +MYAGE +var +Document +skjfndskjfnbdskjfb +thisisareallylongstupidvariablenameman</pre> + +<p>Error-prone name examples:</p> + +<pre class="example-invalid notranslate">var +Document +</pre> + +<p>Try creating a few more variables now, with the above guidance in mind.</p> + +<h2 id="變數資料類型">變數資料類型</h2> + +<p>There are a few different types of data we can store in variables. In this section we'll describe these in brief, then in future articles, you'll learn about them in more detail.</p> + +<p>So far we've looked at the first two, but there are others.</p> + +<h3 id="Numbers_數字">Numbers 數字</h3> + +<p>You can store numbers in variables, either whole numbers like 30 (also called integers) or decimal numbers like 2.456 (also called floats or floating point numbers). You don't need to declare variable types in JavaScript, unlike some other programming languages. When you give a variable a number value, you don't include quotes:</p> + +<pre class="brush: js notranslate">let myAge = 17;</pre> + +<h3 id="Strings_字串">Strings 字串</h3> + +<p>Strings are pieces of text. When you give a variable a string value, you need to wrap it in single or double quote marks, otherwise, JavaScript will try to interpret it as another variable name.</p> + +<pre class="brush: js notranslate">let dolphinGoodbye = 'So long and thanks for all the fish';</pre> + +<h3 id="Booleans_布林值">Booleans 布林值</h3> + +<p>Booleans are true/false values — they can have two values, <code>true</code> or <code>false</code>. These are generally used to test a condition, after which code is run as appropriate. So for example, a simple case would be:</p> + +<pre class="brush: js notranslate">let iAmAlive = true;</pre> + +<p>Whereas in reality it would be used more like this:</p> + +<pre class="brush: js notranslate">let test = 6 < 3;</pre> + +<p>This is using the "less than" operator (<code><</code>) to test whether 6 is less than 3. As you might expect, it will return <code>false</code>, because 6 is not less than 3! You will learn a lot more about such operators later on in the course.</p> + +<h3 id="Arrays_陣列">Arrays 陣列</h3> + +<p>An array is a single object that 它包含多個用方括號括起來並用逗號分隔的值。Try entering the following lines into your console:</p> + +<pre class="brush: js notranslate">let myNameArray = ['Chris', 'Bob', 'Jim']; +let myNumberArray = [10, 15, 40];</pre> + +<p>Once these arrays are defined, you can access each value by their location within the array. Try these lines:</p> + +<pre class="brush: js notranslate">myNameArray[0]; // should return 'Chris' +myNumberArray[2]; // should return 40</pre> + +<p>The square brackets specify an index value corresponding to the position of the value you want returned. You might have noticed that arrays in JavaScript are zero-indexed: the first element is at index 0.</p> + +<p>You'll learn a lot more about arrays in <a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays">a future article</a>.</p> + +<h3 id="Objects_物件">Objects 物件</h3> + +<p>在編程中,物件是對真實生活物件進行建模的代碼結構。 您可以擁有一個代表停車場的簡單物件,其中包含有關其寬度和長度的信息,或者您可以擁有一個代表一個人的物件,並用物件紀錄其姓名、身高、體重、慣用語言,如何跟他打招呼等的資訊。</p> + +<p>請試著在你的console中輸入以下指令:</p> + +<pre class="brush: js notranslate">let dog = { name : 'Spot', breed : 'Dalmatian' };</pre> + +<p>取得物件中儲存的資料可以使用以下語法:</p> + +<pre class="brush: js notranslate">dog.name</pre> + +<p>We won't be looking at objects any more for now — you can learn more about those in <a href="/en-US/docs/Learn/JavaScript/Objects">a future module</a>.</p> + +<h2 id="動態型別">動態型別</h2> + +<p>JavaScript 是一個"動態型別語言",意思是不像其他強型別程式語言,在JavaScript 宣告變數時你不用指定指定資料類型(數字、字串或陣列等等)。</p> + +<p>For example, if you declare a variable and give it a value enclosed in quotes, the browser will treat the variable as a string:</p> + +<pre class="brush: js notranslate">let myString = 'Hello';</pre> + +<p>It will still be a string, even if it contains numbers, so be careful:</p> + +<pre class="brush: js notranslate">let myNumber = '500'; // oops, this is still a string +typeof myNumber; +myNumber = 500; // much better — now this is a number +typeof myNumber;</pre> + +<p>Try entering the four lines above into your console one by one, and see what the results are. You'll notice that we are using a special operator called <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/typeof">typeof</a></code> — this returns the data type of the variable you pass into it. The first time it is called, it should return <code>string</code>, as at that point the <code>myNumber</code> variable contains a string, <code>'500'</code>. Have a look and see what it returns the second time you call it.</p> + +<h2 id="JavaScript中的常數">JavaScript中的常數</h2> + +<p>許多程式語言都有常數的概念:一經宣告就不改變的值。設定常數有許多原因,例如若引入第三方腳本而改動變數值,將會造成許多問題而且很難除錯。</p> + +<p>一開始JavaScript是沒有常數的,直到今日我們才有了關鍵字 <code>const</code>,讓我們儲存不能改變的值:</p> + +<pre class="brush: js notranslate">const daysInWeek = 7<span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="objectBox objectBox-number">; +const hoursInDay = 24;</span></span></span></span></pre> + +<p><span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="objectBox objectBox-number"><code>const</code> works in exactly the same way as <code>let</code>, except that you can't give a <code>const</code> a new value. In the following example, the second line would throw an error:</span></span></span></span></p> + +<pre class="brush: js notranslate">const daysInWeek = 7<span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="objectBox objectBox-number">; +daysInWeek = 8;</span></span></span></span></pre> + +<h2 id="Summary">Summary</h2> + +<p>By now you should know a reasonable amount about JavaScript variables and how to create them. In the next article, we'll focus on numbers in more detail, looking at how to do basic math in JavaScript.</p> + +<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps/Maths", "Learn/JavaScript/First_steps")}}</p> + +<h2 id="在這個學習模組中">在這個學習模組中</h2> + +<ul> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_is_JavaScript">什麼是 JavaScript?</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/A_first_splash">和 JavaScript 的第一次接觸</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_went_wrong">什麼出錯了? JavaScript 的疑難排解(除錯)</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Variables">儲存你需要的資訊 — 變數</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Math">JavaScript 的基本運算— 數字 與 運算子</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Strings">處理文字 — JavaScript 的字串</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Useful_string_methods">有用的字串方法</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Arrays">陣列</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Silly_story_generator">附錄:笑話產生器</a></li> +</ul> diff --git a/files/zh-tw/learn/javascript/first_steps/what_is_javascript/index.html b/files/zh-tw/learn/javascript/first_steps/what_is_javascript/index.html new file mode 100644 index 0000000000..c610e17dd8 --- /dev/null +++ b/files/zh-tw/learn/javascript/first_steps/what_is_javascript/index.html @@ -0,0 +1,425 @@ +--- +title: JavaScript 是什麼? +slug: Learn/JavaScript/First_steps/What_is_JavaScript +tags: + - API + - JavaScript + - 學習 + - 撰寫程式 + - 新手 + - 核心觀念 + - 瀏覽器 + - 註解 +translation_of: Learn/JavaScript/First_steps/What_is_JavaScript +--- +<div>{{LearnSidebar}}</div> + +<div>{{NextMenu("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps")}}</div> + +<p class="summary">歡迎來到 MDN 的 JavaScript 初學者課程!我們將在這個章節綜觀 JavaScript ,回答一些像是「它什麼?」和「可以使用它作什麼?」之的問題,並確保你了解 JavaScript 的特性。</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">先備條件:</th> + <td>基本的電腦知識,基本了解 HTML 和 CSS 技術。</td> + </tr> + <tr> + <th scope="row">學習目標:</th> + <td>了解 JavaScript 的本質、功能、以及它如何構成網站的一部分</td> + </tr> + </tbody> +</table> + +<h2 id="高層次的定義">高層次的定義</h2> + +<p>JavaScript 是一種腳本,也能稱它為程式語言,可以讓你在網頁中實現出複雜的功能。當網頁不只呈現靜態的內容,另外提供了像是:內容即時更新、地圖交動、繪製 2D/3D 圖形,影片播放控制……等,你就可以大膽地認為 JavaScript 已經參與其中。它是標準網頁技術蛋糕的第三層,而其他兩層(<a href="/zh-TW/docs/Learn/HTML">HTML</a> 和 <a href="/zh-TW/docs/Learn/CSS">CSS</a>)我們在其他學習單元中有更多詳細的介紹。</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13502/cake.png" style="display: block; margin: 0 auto;"></p> + +<ul> + <li>{{glossary("HTML")}} 是一種標記語言,我們使用它組織網頁裡的內容並給予定義, 例如:定義段落、標題、資料表格,或是在頁面嵌入圖片和影片。.</li> + <li>{{glossary("CSS")}} 是一種樣式規則的語言,用來幫我們的 HTML 內容上套用樣式,例如:設置背景顏色、字型,或讓內容以多欄的方式呈現。</li> + <li>{{glossary("JavaScript")}} 是一種腳本語言,它使你能夠動態的更新內容、控制多媒體、動畫……幾乎所有事。(好吧,不是所有事情,但神奇的是你可以通過短短幾行 JavaScript 程式碼實現。)</li> +</ul> + +<p>這三層很好的構建在一起。讓我們以一個簡單的文字為例。我們可以使用 HTML 標記來表示它的結構和意圖:</p> + +<pre class="brush: html notranslate"><p>Player 1: Chris</p></pre> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13422/just-html.png" style="height: 28px; width: 108px;"></p> + +<p>然後我們可以加一些 CSS ,讓它看起來更好:</p> + +<pre class="brush: css notranslate">p { + font-family: 'helvetica neue', helvetica, sans-serif; + letter-spacing: 1px; + text-transform: uppercase; + text-align: center; + border: 2px solid rgba(0,0,200,0.6); + background: rgba(0,0,200,0.3); + color: rgba(0,0,200,0.6); + box-shadow: 1px 1px 2px rgba(0,0,200,0.4); + border-radius: 10px; + padding: 3px 10px; + display: inline-block; + cursor:pointer; +}</pre> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13424/html-and-css.png" style="height: 48px; width: 187px;"></p> + +<p>最後,我們可以加一些 JavaScript 來作出互動的行為:</p> + +<pre class="brush: js notranslate">const para = document.querySelector('p'); + +para.addEventListener('click', updateName); + +function updateName() { + let name = prompt('輸入新的名字'); + para.textContent = 'Player 1: ' + name; +} +</pre> + +<p>{{ EmbedLiveSample('高層次的定義', '100%', 80, "", "", "hide-codepen-jsfiddle") }}</p> + +<p>試試點擊這最後版本的文字,看看會發生什麼事情(你同樣也可以在 GitHub 找到這個範例,來查看<a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/javascript-label.html">原始碼</a>或<a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/what-is-js/javascript-label.html">在線上執行</a>)!</p> + +<p>JavaScript 能做到更多,讓我們更深入地探索。</p> + +<h2 id="它究竟可以做什麼呢">它究竟可以做什麼呢?</h2> + +<p>JavaScript 語言的核心包含了很多常用的程式功能供你使用,如:</p> + +<ul> + <li>將有用的值存儲在變數中。例如上述例子,我們要求輸入一個新名字,然後將該名字存在名為<code>name</code>的變數裡。</li> + <li>對文本片段的操作(在程式裡稱作"字串")。在上述例子中,我們拿了字串 "Player 1: " 並將其與 <code>name</code> 變數連接來創造完整文本標籤,如:''Player 1: Chris"。</li> + <li>執行程式碼,回應網頁上發生的某些事件。在上述例子中,我們使用 {{Event("click")}} 事件,當按鈕被點擊時,便執行更新文本標籤的程式碼。 </li> + <li>以及其他更多更多的功能!</li> +</ul> + +<p>然而,更令人興奮的是那些基於用戶端的 JavaScript 語言構建的功能。也就是所謂的 <strong>應用程式介面</strong>(<strong>API</strong>),提供 JavaScript 程式額外的超能力。</p> + +<p>API 是預先製作完成的程式模組,支援開發者實現困難或無法實現的功能。在程式設計中就如同在建築房子的時候使用系統傢俱,拿預先裁好的板子用螺絲鎖上來組合成書架,相比從頭自己設計,找合適木材,切成正確的形狀和尺寸,再找到合適的螺絲最後組裝書架而言更簡單。</p> + +<p>他們通常分為兩類。</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13508/browser.png" style="display: block; height: 511px; margin: 0px auto; width: 815px;"></p> + +<p><strong>瀏覽器 API(Browser APIs)</strong>內建在你的瀏覽器中,能夠依本地的電腦環境輸出資料或實現複雜的功能。舉例而言:</p> + +<ul> + <li>{{domxref("Document_Object_Model","DOM (文件物件模型) API")}} 讓你能操作 HTML和 CSS,像是建立、移除或改變 HTML 元素,或動態地將新樣式套用到頁面…等等。每當你看到彈出視窗,或有新的內容出現在畫面上(就像上面的範例所展示的),那就是 DOM 在動作。</li> + <li>{{domxref("Geolocation","Geolocations(地理位置) API")}} 可以取得位置資訊。這就是 <a href="https://www.google.com/maps">Google Maps</a> 取得你的位置並標示在地圖上所透過的方式。</li> + <li>{{domxref("Canvas_API","Canvas")}} 和 {{domxref("WebGL_API","WebGL")}} API 可以讓你在網頁創造 2D 動畫及 3D 圖像。人們正使用這些技術來作一些令人驚奇的事,參見 <a href="https://www.chromeexperiments.com/">Chrome Experiments</a> 及 <a href="http://webglsamples.org/">webglsamples</a>.</li> + <li><a href="https://developer.mozilla.org/zh-TW/Apps/Fundamentals/Audio_and_video_delivery">Audio 和 Video API</a> 像 {{domxref("HTMLMediaElement")}} 和 {{domxref("WebRTC API", "WebRTC")}} 一樣讓你可以使用多媒體做真正有趣的事情,例如在網頁中播放音樂或影片,或由網路攝影機頡取你的影像顯示在另一個人電腦裡(試試我們的<a href="http://chrisdavidmills.github.io/snapshot/">簡單例子</a>來了解)。</li> +</ul> + +<div class="note"> +<p><strong>注意</strong>:上面的許多範例無法在舊版的瀏覽器上運作。使用現代的瀏覽器像是 Firefox、Chrome、Edge 或 Opera 來嘗試執行你的程式總是比較好的。當你接近要交付作為產品的程式(也就是實際的用戶將要使用的時候),就需要思考關於<a href="/zn-TW/docs/Learn/Tools_and_testing/Cross_browser_testing">跨瀏覽器測試</a>的事情。</p> +</div> + +<p><strong>第三方 API</strong> 預設不內建在瀏覽器裡,你通常由網路上取得他們的程式碼與資訊。例如:</p> + +<ul> + <li><a href="https://dev.twitter.com/overview/documentation">Twitter API</a> 能讓你做很多事,像是顯示最新的Twitter貼文在你的網站上。</li> + <li><a href="https://developers.google.com/maps/">Google Maps API</a> 能讓你在自己的網站中嵌入訂製的地圖或其他相關功能。</li> +</ul> + +<div class="note"> +<p><strong>注意</strong>: 我們不會在此涵蓋這些進階的APIs。你可以在我們的 <a href="/zh-TW/docs/Learn/JavaScript/Client-side_web_APIs">客戶端網頁 API 單元</a>找到更多資訊。</p> +</div> + +<p>那裡也有很多的東西。然而不要一頭熱陷進去。你不會在學習 JavaScript 24 小時後,就能開發出下一個 Facebook、Google 地圖或 Instagram 之類的產品出來。有許多的基礎的東西得先了解,這也是你在這裡的原因,讓我們繼續吧!</p> + +<h2 id="JavaScript_在你的頁面做了些什麼?">JavaScript 在你的頁面做了些什麼?</h2> + +<p>這裡我們開始看一些程式碼,探索當 JavaScript 在你的頁面上執行時,發生了哪些事情。</p> + +<p>簡單回顧一下當瀏覽器載入一個網站時會發生的事情(第一次是在我們的<a href="/zh-TW/Learn/CSS/Introduction_to_CSS/How_CSS_works#How_does_CSS_actually_work">CSS 如何工作</a>章節中提到)。當瀏覽器載入一個網頁,就是在執行環境(瀏覽器分頁)中執行程式碼(HTML,CSS 和 JavaScript)。就像是工廠收集原料(程式碼)並且產出商品(網頁呈現的結果)。</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13504/execution.png" style="display: block; margin: 0 auto;"></p> + +<p>透過 DOM API (上面提到的)動態調整 HTML 與 CSS 進行改變網頁呈現,在 JavaScript 是很常見的使用方式。要注意的是,檔案中的程式碼通常會以出現在頁面上的順序來執行。如果 JavaScript 比準備操作的 HTML 、 CSS 更早被載入,就可能會發生錯誤。你將會在這個章節的後段學到一些解決問題的方法,它在<a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_is_JavaScript#Script_loading_strategies">腳本載入策略</a>的部分。</p> + +<h3 id="瀏覽器安全性">瀏覽器安全性</h3> + +<p>瀏覽器的每個分頁有獨立的空間來執行程式碼(技術上稱「執行環境excution environments」),這表示在絕大部分的情形之下,每個分頁的程式碼是獨立運行的,不能直接影響其它分頁(或網站)裡的程式。這是一個好的安全措施,少了它,有心人會開始寫程式來偷取網站的資料,或是作其它不好的事情。</p> + +<div class="note"> +<p><strong>注意</strong>:是有一些安全的方式能在不同的網頁、分頁之間傳遞程式和資料,不過這些進階的技術不會在涵蓋在這個單元中。</p> +</div> + +<h3 id="JavaScript_的執行順序">JavaScript 的執行順序</h3> + +<p>當瀏覽器遇到一段 JavaScript 程式碼,通常會由上到下執行。這意味著你需要注意東西擺放的順序。為了說明,讓我們回到我們曾看過的第一個範例:</p> + +<pre class="brush: js notranslate">const para = document.querySelector('p'); + +para.addEventListener('click', updateName); + +function updateName() { + let name = prompt('輸入新的名字'); + para.textContent = 'Player 1: ' + name; +}</pre> + +<p>這裡我們選擇了一個文字段落(第 1 行),然後加上事件偵聽器,所以當段落被點擊的時候,<code>updateName()</code> 程式區塊(5 到 8 行 )會被執行。<code>updateName()</code> 程式區塊(這種可以重複使用的程式區塊被稱為「函數 function」)會向使用者要一個新的名字,然後將插到段落中,更新顯示的內容。</p> + +<p>如果你交換前兩行的程式碼,它將不再正常運作。取而代之的,<a href="/zh-TW/docs/Learn/Common_questions/What_are_browser_developer_tools">瀏覽器開發主控台</a>會回報一個錯誤訊息:「<code>TypeError: para is undefined</code>」,意思是 <code>para</code> 物件尚不存在,所以我們在它上頭增加事件偵聽器。</p> + +<div class="note"> +<p><strong>注意</strong>: 這是一個很常見的錯誤,在你嘗試對物件進行操作之前,你需要注意它們已經存在。</p> +</div> + +<h3 id="直譯式與編譯式程式語言">直譯式與編譯式程式語言</h3> + +<p>你可能在程式相關的文章中看過<strong>直譯式</strong> (<strong>interpreted</strong> )與<strong>編譯式 (compiled)</strong>這兩個詞。在直譯式程式語言中,程式碼由上到下執行,而且執行的結果是立即回應得到的。在瀏覽器執行前,你不需要將程式轉換為其它的形式。程式碼的內容是以對程式人員友善的形式並直接能夠運作。</p> + +<p>另一方面,編譯式程式語言需要在電腦執行之前轉換(編譯)成另一種形式。例如: C/C++ 在被電腦執行之前要編譯為組合語言。被執行的程式是一種二進位的格式,由程式原始碼產生出來。</p> + +<p>JavaScript 是一個輕量的直接程式語言。網頁瀏覽器收到文字格式的 JavaScript 程式碼,並直接執行。以技術的角度來看,大多數現代的 JavaScript 直譯器實際上會使用一種稱為<strong>即時編譯(just-in-time compiling)</strong>的技術來提升執行表現。 JavaScript 被使用時,原始程式會被編譯成更快的二進位格式,讓它們能更有效率的運行。然而, JavaScript 仍然被認為是一種直譯式的程式語言,因為編譯動作是在程式運作時,而不是事先完成。</p> + +<p>兩種語言都有各自的優點,但是我們不在此時討論這個議題。</p> + +<h3 id="伺服器端與用戶端程式">伺服器端與用戶端程式</h3> + +<p>你也有可能聽過<strong>伺服器端</strong>與<strong>客戶端</strong>程式,尤其在網站開發的領域。客戶端程式在使用者的電腦中運作,當瀏覽網頁的時候,頁面中的客戶端程式被下載,接著被瀏覽器執行與顯示結果。在這個單元中,我們只談論<strong>客戶端 JavaScript</strong>。</p> + +<p>另一方面,伺服器端的程式在伺服器上執行,接著產出的結果被瀏覽器下載後顯示。受歡迎的伺服器端網頁語言,包括 PHP、Python、Ruby 和 ASP.NET 以及… JavaScript!JavaScript 也能夠作為伺服器端程式語言,流行的 Node.js 環境就是一例。你可以在我們的<a href="/zh-TW/docs/Learn/Server-side">動態網站—伺服器端網站程式設計</a>主題中找到更多資訊。</p> + +<h3 id="動態與靜態程式">動態與靜態程式</h3> + +<p><strong>動態</strong>一詞被用於描述用戶端 JavaScript 和伺服器端程的式語言,用來描述具有在不同的狀況下更新網頁/網頁應用程式來顯示不同東西,依需要來產生新內容的能力。是根據要求生成新內容的能力。伺服器端程式在伺服器上動態產生的新內容,可能是來自資料庫中取出的數據,而用戶端 JavaScript 在收到由伺服器端要回來的資料,在瀏覽器內動態產生新的內容(如 HTML 表格)後加入頁面中呈現出來。在兩個情境中詞義稍微不同,但是相關的,兩種方法(伺服器端和用戶端)通常可以協同工作。</p> + +<p>一個沒有動態更新內容能力的網頁被稱為<strong>靜態</strong>,它在任何時候都只顯示一樣的內容。</p> + +<h2 id="如何在網頁中增加_JavaScript_?">如何在網頁中增加 JavaScript ?</h2> + +<p>在 HTML 頁面中使用 JavaScript 與 CSS 的方法類似。在 HTML 中 CSS 藉著{{htmlelement("link")}} 元素引入外部樣式(stylesheets)以及 {{htmlelement("style")}} 元素定義內部樣式。JavaScript 在 HTML中只需要一個朋友 — {{htmlelement("script")}} 元素。讓我們了解它是如何運作。</p> + +<h3 id="內部的_JavaScript">內部的 JavaScript</h3> + +<ol> + <li>首先,下載一份 <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/apply-javascript.html">apply-javascript.html 範例</a>儲存在自己的電腦上合適的目錄裡。</li> + <li>用瀏覽器與文字編輯器打開範例。你會看到 HTML 建立了一個簡單的網頁,包含一個可點擊的按鈕。</li> + <li>接著,切換到文字編輯器,在標頭區加入下面的文字,就放在 <code></head></code> 結尾標籤前: + <pre class="brush: html notranslate"><script> + + // JavaScript 將放在這裡 + +</script></pre> + </li> + <li>現在,我們將在我們的 {{htmlelement("script")}} 元素中加入一些 JavaScript 程式,讓網頁能做些有趣的事,接者在「// JavaScript 將放在這裡」那行後面: + <pre class="brush: js line-numbers language-js notranslate"><code class="language-js">document<span class="punctuation token">.</span><span class="function token">addEventListener</span><span class="punctuation token">(</span><span class="string token">"DOMContentLoaded"</span><span class="punctuation token">,</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">function</span> <span class="function token">createParagraph</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">let</span> para <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">createElement</span><span class="punctuation token">(</span><span class="string token">'p'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + para<span class="punctuation token">.</span>textContent <span class="operator token">=</span> <span class="string token">'You clicked the button!'</span><span class="punctuation token">;</span> + document<span class="punctuation token">.</span>body<span class="punctuation token">.</span><span class="function token">appendChild</span><span class="punctuation token">(</span>para<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="keyword token">const</span> buttons <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">querySelectorAll</span><span class="punctuation token">(</span><span class="string token">'button'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">for</span><span class="punctuation token">(</span><span class="keyword token">let</span> i <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> i <span class="operator token"><</span> buttons<span class="punctuation token">.</span>length <span class="punctuation token">;</span> i<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + buttons<span class="punctuation token">[</span>i<span class="punctuation token">]</span><span class="punctuation token">.</span><span class="function token">addEventListener</span><span class="punctuation token">(</span><span class="string token">'click'</span><span class="punctuation token">,</span> createParagraph<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + </li> + <li>儲存你的檔案並且重新整理網頁,現在你會發現每次點擊按鈕,都會在下方產生一個新的文字段落。</li> +</ol> + +<div class="note"> +<p><strong>注意</strong>: 如果你的版本不能正常運作,重新按照步驟再操作一次,檢查每一步都正確。你下載的範例是 <code>.html</code> 結尾的檔名?你加入的 {{htmlelement("script")}} 元素在 <code></head></code> 標籤的前面?你輸入的 JavaScript 與上面提供的一模一樣? <strong>JavaScript 程式大小寫,而且很挑剔,所以你輸入的語法要一模一樣,不然可能會無法運作。</strong></p> +</div> + +<div class="note"> +<p><strong>注意</strong>: GitHub上有完整版本的範例在 <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/apply-javascript-internal.html">apply-javascript-internal.html</a>(<a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/what-is-js/apply-javascript-internal.html">看線上版本</a>)。</p> +</div> + +<h3 id="外部的_JavaScript">外部的 JavaScript</h3> + +<p>內部 JavaScript 目前運作得很好,但如果我們想把 JavaScript 放在外部檔案,應該怎麼做?讓我們現在來探索。</p> + +<ol> + <li>首先,建立一個新的檔案,和 HTML 檔案放在相同的目錄下,命名為 <code>script.js</code> ,確定這個檔案是以 .js 為副檔名, 因為這就是它被識別為 JavaScript 的原因。</li> + <li>將 {{htmlelement("script")}} 元素(包含裡面的程式)換成下面的樣子: + <pre class="brush: html notranslate"><script src="script.js" async></script></pre> + </li> + <li>在 <code>script.js</code> 中,加入下面的程式碼: + <pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">createParagraph</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">let</span> para <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">createElement</span><span class="punctuation token">(</span><span class="string token">'p'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + para<span class="punctuation token">.</span>textContent <span class="operator token">=</span> <span class="string token">'You clicked the button!'</span><span class="punctuation token">;</span> + document<span class="punctuation token">.</span>body<span class="punctuation token">.</span><span class="function token">appendChild</span><span class="punctuation token">(</span>para<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="keyword token">const</span> buttons <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">querySelectorAll</span><span class="punctuation token">(</span><span class="string token">'button'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +<span class="keyword token">for</span><span class="punctuation token">(</span><span class="keyword token">let</span> i <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> i <span class="operator token"><</span> buttons<span class="punctuation token">.</span>length <span class="punctuation token">;</span> i<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + buttons<span class="punctuation token">[</span>i<span class="punctuation token">]</span><span class="punctuation token">.</span><span class="function token">addEventListener</span><span class="punctuation token">(</span><span class="string token">'click'</span><span class="punctuation token">,</span> createParagraph<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + </li> + <li>儲存檔案並在你的瀏覽器執行重新整理,你應該會看到一樣的結果!雖然是一樣的結果,但現在我們是由外部的檔案來引入 JavaScript 程式。就組織程式碼,讓程式可以在多個 HTML 間重複被使用而言,這通常是好的作法。另外,因為少了一大堆程式碼在裡頭,也能夠讓 HTML 檔案更容易被閱讀。</li> +</ol> + +<div class="note"> +<p><strong>注意</strong>: 你可以在 GitHub 上找到這個版本的 <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/apply-javascript-external.html">apply-javascript-external.html</a> 與 <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/script.js">script.js</a> (<a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/what-is-js/apply-javascript-external.html">看線上版本</a>)。</p> +</div> + +<h3 id="行內的_JavaScript">行內的 JavaScript</h3> + +<p>注意,有時候你會遇到一些 JavaScript 程式混在HTML語法之中。它可能會看起來像這樣:</p> + +<pre class="brush: js example-bad notranslate">function createParagraph() { + var para = document.createElement('p'); + para.textContent = 'You clicked the button!'; + document.body.appendChild(para); +}</pre> + +<pre class="brush: html example-bad notranslate"><button onclick="createParagraph()">Click me!</button></pre> + +<p>你可以在底下試試這個段程式的作用。</p> + +<p>{{ EmbedLiveSample('行內的_JavaScript', '100%', 150, "", "", "hide-codepen-jsfiddle") }}</p> + +<p>這個範例與前面兩個有完全相同的功能,除了 {{htmlelement("button")}} 元素中包含了一個行內 <code>onclick</code> 處理程序,當按鈕按下時執行。</p> + +<p><strong>然而,請不要這樣做。</strong>用 JavaScript 汙染你的 HTML 是一種不好的作法,而且沒有效率,因為你必須在每個你希望 JavaScript 作用的地方加入 <code>onclick="createParagraph()"</code> 屬性。</p> + +<p>使用單純 JavaScript 的結構,讓你可以用一個指令選擇所有的按鈕。在我們前面的範例中,使用下面的程式碼達到這個目的:</p> + +<pre class="notranslate">var buttons = document.querySelectorAll('button'); + +for (var i = 0; i < buttons.length ; i++) { + buttons[i].addEventListener('click', createParagraph); +}</pre> + +<p>這或許看起來比 <code>onclick</code> 屬性還長一點,但是能套用在全部的按鈕上,無論頁面上有多少按鈕,也不管未來新增或移除多少個(按鈕)。這段 JavaScript 程式都不需要改變。</p> + +<div class="note"> +<p><strong>注意</strong>: 試著編輯你自己版本的 <code>apply-javascript.html</code> ,在裡面多添加一點按鈕。當你重新載入網頁,你應該會發現所有按鈕,按下去的時候都會建立一的段落。很簡潔吧!</p> +</div> + +<h3 id="腳本載入策略Script_loading_strategies">腳本載入策略(Script loading strategies)</h3> + +<p>在正確的時機載入腳本涉及一些要注意的東西。並不如它看起來的簡單!其中一個常見的問題是,所有的 HTML 是根據出現順序載入。假如你使用 JavaScript 操作頁面中的元素(精確地來說是 <a href="/zh-TW/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents#The_document_object_model">DOM 元素</a>),如果 JavaScript 在這些 HTML 操作對象前被讀取及解析,你的程式將無法運作。</p> + +<p>上面的範例中,內部和外部 JavaScript 範例裡的程式碼都放在 HTML 的 head 區域,在 body 區被載入前就先被解析。這樣會造成一些問題,所以我們載入與執行在文件(HTML檔)的開頭,是HTML <code>body</code> 還沒解析之前。這可能會產生錯誤,所以我們使用一些模式來處理它。</p> + +<p>在內部程式的範例中,你可以看到以下這樣結構的程式碼:</p> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js">document<span class="punctuation token">.</span><span class="function token">addEventListener</span><span class="punctuation token">(</span><span class="string token">"DOMContentLoaded"</span><span class="punctuation token">,</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="operator token">...</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>這是一個事件偵聽器,它偵聽瀏覽器的「DOMContentLoaded」事件,它是在 HTML body 部分已經完全載入與解析發出。區塊內(... 的部分)的 JavaScript 直到事件被發出後才會執行,這樣子問題就被避開了。(你將會在這個課程中<a href="/zh-TW/docs/Learn/JavaScript/Building_blocks/Events">學習到什麼是事件</a>)</p> + +<p>在外部程式的範例中,我們使用比較現代的 JavaScript 特性來解決這個問題,<code>defer</code> 屬性,它告訴瀏覽器碰到這種 <code><script></code> 標籤時,繼續下載後面其他的 HTML 內容。</p> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="operator token"><</span>script src<span class="operator token">=</span><span class="string token">"script.js"</span> defer<span class="operator token">></span><span class="operator token"><</span><span class="operator token">/</span>script<span class="operator token">></span></code></pre> + +<p>在這個例子中,腳本(JavaScript 程式)與 HTML 會同時載入,所以程式將正確地執行。</p> + +<div class="note"> +<p><strong>注意</strong>: 在外部程式的範例裡,我們不需要使用 <code>DOMContentLoaded</code> 事件因為 <code>defer</code> 為我們解決問題了。而在內部程式的範例裡我們沒用 <code>defer</code> 屬性,是因為 <code>defer</code> 屬性只能用於外部的腳本。</p> +</div> + +<p>這個問題有另一個舊式的解決方法,就是將 <code>script</code> 元素放在 <code>body</code> 元素的底部(剛好在 <code></body></code> 的前面),如此它就會在所有 HTML 被解析完之後才被載入。這個方法的問題在於腳本的載入與解析工作會被完成擋住,一直到所有 HTML 載入完成。在擁有許多 JavaScript 的大型網站中,這樣會導致嚴重的效能問題,拖慢你的網站。</p> + +<h4 id="async_和_defer">async 和 defer</h4> + +<p>實際上,有兩個方法可以閃過上述腳本被擋到的問題:<code>async</code> 與 <code>defer</code>(前面看到的)。來看看兩者的區別。</p> + +<p>使用 <code>async</code> 屬性(如下所示)所載入的腳本,在下載的同時不會讓網頁的渲染被阻塞(停住),並且在下載完成後馬上執行。它並不保證腳本會按照任何特定的順序執行,只保證不去妨礙網頁中其他部分顯示工作。<code>async</code> 的最佳使用情境,是當網頁中的腳本間彼此獨立,因而不依賴彼此運行的狀況下。</p> + +<p>例如你有以下的 <code>script</code> 元素</p> + +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">async</span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>js/vendor/jquery.js<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span> + +<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">async</span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>js/script2.js<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span> + +<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">async</span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>js/script3.js<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span></code></pre> + +<p>你不能將元素的順序視為腳本載入順序。 <code>jquery.js</code> 可能會在 <code>script2.js</code> 與 <code>script3.js</code> 的之前或之後載入,在這個情況下,在腳本中依賴 <code>jquery</code> 的函數將會發生錯誤,因為被執行到的時候 <code>jquery</code> 還沒被定義(載入且解析完畢)。</p> + +<p>當有許多非立即要使用的腳本,而你只希望它們能盡快被載入完畢,就應該使用 <code>async</code> 。例如:你有一些遊戲內容的檔案需要載入,它將在遊戲開始後被用到。但是現在你只是需要顯示遊戲介紹、一些選單以及遊戲大廳,不希望等到所有內容都下載完成之後才顯示。</p> + +<p>使用 <code>defer</code> 屬性(如下所示)所載入的腳本,會在腳本與內容都下載完成後,依照出現順序被執行。</p> + +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">defer</span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>js/vendor/jquery.js<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span> + +<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">defer</span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>js/script2.js<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span> + +<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">defer</span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>js/script3.js<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span></code></pre> + +<p>全部具有 <code>defer</code> 屬性的腳本會依據出現的順序載入。因此在第二個範例中,我們可以肯定 <code>jquery.js</code> 會在 <code>script2.js</code> 與 <code>script3.js</code> 之前被載入, <code>script2.js</code> 會在 <code>script3.js</code> 之前載入。在網頁的所有內容被載入完成之前,它是不會被執行的。當你的程式依賴著某些元素存在時(如:要調整頁面上一到多個元素),這個屬性很有用。</p> + +<p>總結一下:</p> + +<ul> + <li><code>async</code> 和 <code>defer</code> 屬性都是用來告訴瀏覽器使用獨立線程(行程)來下載腳本,同一時間頁面的其它部分(如 DOM 元件之類)也在下載,因此頁面的載入不會因為腳本被影響。</li> + <li>如果你的腳本應該立即被執行,而且不依賴其它腳本先被載入,就用 <code>async</code> 。</li> + <li>如果你的腳本依賴其他腳本先被解析或 DOM 已經存在,就用 <code>defer</code> 來載入它們,並根據你想要瀏覽器執行的順序安排 <code><script></code> 元素的次序。</li> +</ul> + +<h2 id="註解">註解</h2> + +<p>如同 HTML 和 CSS,在 JavaScript 的程式碼中也可以撰寫註解,它會被瀏覽器忽略,僅用來提供你的開發伙伴,說明程式是如何運作(或是自己,當六個月後回來看程式碼,忘記曾經做過了什麼)。註解非常有用,你應該常常使用它,尤其是在大型應用程式裡。註解有兩種形式:</p> + +<ul> + <li>單行註解,寫在兩個(正)斜線「//」之後,例如: + <pre class="brush: js notranslate">// 我是一個註解</pre> + </li> + <li>多行註解,寫在 /* 和 */ 之間的文字,例如: + <pre class="brush: js notranslate">/* + 我也是 + 一個註解 +*/</pre> + </li> +</ul> + +<p>舉例來說,我們可以在前面範例的 JavaScript 裡加入註解,像是:</p> + +<pre class="brush: js notranslate">// 函數:建立一個段落元素並加到 HTML body 的尾端 + +function createParagraph() { + var para = document.createElement('p'); + para.textContent = 'You clicked the button!'; + document.body.appendChild(para); +} + +/* + 1. 找出頁面上所有按鈕,並把它們放到陣列中 + 2. 使用迴圈,對每個按鈕偵聽 click 事件 + + 當任何按鈕被按下,執行 createParagraph() 函數 +*/ + +var buttons = document.querySelectorAll('button'); + +for (var i = 0; i < buttons.length ; i++) { + buttons[i].addEventListener('click', createParagraph); +}</pre> + +<div class="blockIndicator note"> +<p><strong>注意:一般而言,多寫註解比少寫來得好。但是要注意,如果你發現加了許多註解在說明變數的用途(那麼你的變數命名可能需要更直觀,更帶有意義),或是解釋非常簡單的操作(也許你的程式碼太過於複雜)。</strong></p> +</div> + +<h2 id="總結">總結</h2> + +<p>所以你已經踏出在 JavaScript 世界中的第一步。我們從理論開始,逐漸熟悉使用 JavaScript 的原因,以及你可以用它做些什麼。過程中你看到了一些程式碼範例,學到如何將 JavaScript 與你網站的其它東西放在一起。</p> + +<p>JavaScript 目前可能看起來有一點嚇人,然而不用擔心,在本課程我們會透過簡單的步驟,帶著你建立觀念並繼續向前。 在下一章節,我們將會<a href="/zh-TW/docs/Learn/JavaScript/Introduction_to_JavaScript_1/A_first_splash">投入更實用的知識</a>,帶你直接入門並建立你自己的 JavaScript 作品。</p> + +<h2 id="在這個學習模組中">在這個學習模組中</h2> + +<ul> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_is_JavaScript">什麼是JavaScript?</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/A_first_splash">初次接觸Javascript</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_went_wrong">什麼出錯了? JavaScript 的疑難排解(除錯)</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Variables">儲存你需要的資訊 — 變數</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Math">JavaScript 的基本運算— 數字 與 運算子</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Strings">處理文字 — JavaScript 的字串</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Useful_string_methods">有用的字串方法</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Arrays">陣列</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Silly_story_generator">附錄:笑話產生器</a></li> +</ul> + +<p>{{NextMenu("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps")}}</p> diff --git a/files/zh-tw/learn/javascript/first_steps/what_went_wrong/index.html b/files/zh-tw/learn/javascript/first_steps/what_went_wrong/index.html new file mode 100644 index 0000000000..5eec96717b --- /dev/null +++ b/files/zh-tw/learn/javascript/first_steps/what_went_wrong/index.html @@ -0,0 +1,253 @@ +--- +title: 出了什麼問題?JavaScript 疑難排解 +slug: Learn/JavaScript/First_steps/What_went_wrong +translation_of: Learn/JavaScript/First_steps/What_went_wrong +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps")}}</div> + +<p class="summary">當你在練習撰寫上一節的"猜數字"遊戲時,你可能會發現它無法運作。不用擔心,本文將會把你從快被拔光的頭髮中拯救出來,並且給你一些小提示,讓你知道怎麼找出及修正 Javascript 的程式運行錯誤。</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">先備:</th> + <td>基本電腦能力,基本html及css理解以及了解JavaScript是什麼</td> + </tr> + <tr> + <th scope="row">目標:</th> + <td>獲得開始解決簡單編碼問題的能力及信心</td> + </tr> + </tbody> +</table> + +<h2 id="錯誤類型">錯誤類型</h2> + +<p>一般來說,當你的編碼有錯誤時,主要有兩種類型</p> + +<ul> + <li><strong>語法錯誤</strong>: 在編碼中有一些拼字錯誤導致程序完全或部分沒有正常運作。在這個狀況下,通常你會獲得一些錯誤訊息。只要對工具熟悉以及了解錯誤訊息的意思,這種錯誤通常很好修正!</li> + <li><strong>邏輯錯誤</strong>: 這種錯誤代表程式碼的語法正確,但程式完成的部分不是開發者想做的?,意即程式碼執行成功,但返回錯誤的結果。這種錯誤通常比<strong>語法錯誤</strong>還要難修正,因為並沒有錯誤訊息讓我們可以很直接地知道程式碼的問題。</li> +</ul> + +<p>好的,但事情並沒有那麼單純——當你越深入,就會發現更多不同的因素。但上述的分類已經足夠應付初期的工程師職涯了。接著,我們將更深入來討論這兩個類型。</p> + +<h2 id="一個錯誤範例">一個錯誤範例</h2> + +<p>讓我們從剛剛的猜數字遊戲開始 — 在這個版本中,我們將故意引入一些錯誤以便從中學習。前往 Github 下載一份 <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/troubleshooting/number-game-errors.html">number-game-errors.html</a> (或運行線上版 <a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/troubleshooting/number-game-errors.html">running live here</a>).</p> + +<ol> + <li>首先,在編輯器與瀏覽器分別開啟你剛下載檔案。</li> + <li>試著玩遊戲——你會注意到當你按下按鈕「Submit guess」時,它沒有任何反應!</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: 你也許是想修復你自己寫的遊戲中的錯誤!這是件好事,但我們還是建議你在學習這篇文章時先使用我們的版本,這樣你才可以學到我們接下來要教的技巧。在這之後再回去修正你自己的遊戲也不遲!</p> +</div> + +<p>現在,先讓我們來看看開發者主控台有沒有提示我們任何錯誤,然後試著修正他們。你會在接下來的段落中學到如何修正這些錯誤。</p> + +<h2 id="修復語法錯誤">修復語法錯誤</h2> + +<p>在前篇文章中我們讓你在 <a href="/zh-TW/docs/Learn/Common_questions/What_are_browser_developer_tools" rel="nofollow">開發者工具 JavaScript console</a> 中輸入了一些JavaScript 指令(如果你不記得怎麼打開這個東西,點選前面的連結複習一下)。更重要的是,主控台在瀏覽器的 JavaScript引擎讀取到有語法錯誤的 JavaScript 時會提示一些錯誤訊息。現在讓我們來看看:</p> + +<ol> + <li>切換到你開啟了 <code>number-game-errors.html</code> 的分頁,然後打開你的 JavaScript 主控台。你應該會看到如下的幾行錯誤訊息:<img alt="" src="https://mdn.mozillademos.org/files/13496/not-a-function.png" style="display: block; margin: 0 auto;"></li> + <li>這是一個非常容易追尋的錯誤,而且瀏覽器還給你了不少有用的資訊來幫助你(這張截圖是 Firefox 的,但其他瀏覽器也會提示相似的錯誤訊息)。從左到右,我們可以看到: + <ul> + <li>一個紅色的 "X" 代表這是一個錯誤訊息。</li> + <li>一條錯誤訊息提示你什麼東西出錯了:"TypeError: guessSubmit.addeventListener is not a function(TypeError: guessSubmit.addeventListener 並不是一個函式)"</li> + <li>一個 "Learn More" 連結連向一個解釋這個錯誤並包含大量詳細資訊的 MDN 頁面。</li> + <li>出錯的 JavaScript 檔案名稱,連結連向開發者工具的除錯器。點下這個連結,你就能看到出錯的那行程式被高亮顯示出來。</li> + <li>在該 JavaScript 檔案中錯誤的行號,還有錯誤發生在該行第幾個字元。在這個例子中,是第 86 行的第 3 個字元。</li> + </ul> + </li> + <li>如果我們在編輯器中檢視第 86 行,我們會看到: + <pre class="brush: js notranslate">guessSubmit.addeventListener('click', checkGuess);</pre> + </li> + <li>主控台提示的錯誤訊息寫著 "guessSubmit.addeventListener is not a function(guessSubmit.addeventListener 並不是一個函式)",所以我們大概是哪裡拼錯字了。如果你並不確定一個函式的正確名稱如何拼寫,打開 MDN 確認看看是個不錯的選擇。最佳做法是在你喜歡的搜尋引擎搜尋 "mdn <em>關鍵字</em>"。為了節省時間,這裡提供你一個捷徑:<code><a href="/zh-TW/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code>。</li> + <li>回來看看這個頁面,我們明顯是把函式名稱給拼錯了!記住,JavaScript 是會區分大小寫的,所以任何些微的拼寫錯誤甚至是大小寫錯誤都會造成錯誤發生。把<code>addeventListener</code> 改成<code>addEventListener</code> 問題就解決了。現在將你的程式碼修正吧。</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: 看看這個 <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Not_a_function">TypeError: "x" is not a function</a> 連結來了解更多有關這類錯誤的資訊。</p> +</div> + +<h3 id="語法錯誤:第二回合">語法錯誤:第二回合</h3> + +<ol> + <li>將你的頁面存檔並重整,你現在應該會看到剛剛的錯誤消失了。</li> + <li>現在試著輸入一個猜測並按下 Submit guess 按鈕,你會發現... 另一個錯誤!<img alt="" src="https://mdn.mozillademos.org/files/13498/variable-is-null.png" style="display: block; margin: 0 auto;"></li> + <li>這次的錯誤是 "TypeError: lowOrHi is null(TypeError: lowOrHi 為 null)",在第 78 行的位置。 + <div class="note"><strong>Note</strong>: <code><a href="/zh-TW/docs/Glossary/Null">Null</a></code> 是一個特別的值,代表著「空」、「什麼都沒有」。<code>lowOrHi</code> 被宣告為一個變數,但並沒有被賦予任何有意義的值 — 他既沒有變數型態,也沒有值。</div> + + <div class="note"><strong>Note</strong>: 這個錯誤並沒有在頁面載入完成後就發生,因為這個錯誤發生在一個函式中(在 <code>checkGuess() { ... }</code> 區塊中)。在之後詳細介紹函式的文章中,你會學到在函式中的程式碼與在函式外的程式碼其實是執行在不同範疇中的。在我們的這個情況裡,有錯誤的程式碼在 <code>checkGuess()</code> 在 86 行被執行前都並沒有執行,也因此錯誤並沒有在頁面一載入就發生。</div> + </li> + <li>看看第 78 行,你會看到: + <pre class="brush: js notranslate">lowOrHi.textContent = 'Last guess was too high!';</pre> + </li> + <li>這行試著將 <code>lowOrHi</code> 的 <code>textContent</code> 屬性設為一個字串。但是這行沒有執行成功,因為 <code>lowOrHi</code> 並沒有存著它應該要存著的值。讓我們來看看為什麼 — 試試在程式碼中搜尋其他 <code>lowOrHi</code> 有出現的地方。在第 48 行你會看到: + <pre class="brush: js notranslate">var lowOrHi = document.querySelector('lowOrHi');</pre> + </li> + <li>這行程式碼試著將一個 HTML 元素的參照存起來。讓我們檢查一下在這行程式碼執行後,變數中的值是否為 <code>null</code>。在第 49 行加上: + <pre class="brush: js notranslate">console.log(lowOrHi);</pre> + + <div class="note"> + <p><strong>Note</strong>: <code><a href="/zh-TW/docs/Web/API/Console/log">console.log()</a></code> 是一個非常好用的除錯功能,它能夠將值印出至主控台中。所以這行程式碼會在第 48 行賦值給 <code>lowOrHi</code> 後,將它的值印出至主控台中。</p> + </div> + </li> + <li>存檔並重整,你應該會在主控台中看到 <code>console.log()</code> 輸出的結果。<img alt="" src="https://mdn.mozillademos.org/files/13494/console-log-output.png" style="display: block; margin: 0 auto;">在這個時間點,<code>lowOrHi</code> 的值是 <code>null</code>。所以很明顯的,第 48 行一定出了什麼問題。</li> + <li>讓我們思考一下發生了什麼問題。第 48 行呼叫了 <code><a href="/zh-TW/docs/Web/API/Document/querySelector">document.querySelector()</a></code> 方法來透過 CSS 選擇器取得一個 HTML 元素參照。打開我們的網頁看看我們想要取得的段落元素: + <pre class="brush: js notranslate"><p class="lowOrHi"></p></pre> + </li> + <li>所以我們需要的是一個開頭是小數點 (.) 的 class 選擇器,但傳進第48 行 <code>querySelector()</code> 方法的選擇器並沒有開頭的小數點。這也許就是問題所在了!試著將第 48 行的 <code>lowOrHi</code> 改成 <code>.lowOrHi</code>。</li> + <li>再次存檔並重整,你的 <code>console.log()</code> 現在應該會輸出我們想要的 <code><p></code> 元素了。呼!又修好了另一個錯誤!你現在可以把你的 <code>console.log()</code> 那行移除了,或是你想要留著之後查看 — 取決於你。</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: 看看這個 <a href="/zh-TW/docs/Web/JavaScript/Reference/Errors/Unexpected_type">TypeError: "x" is (not) "y"</a> 連結來了解更多有關這類錯誤的資訊。</p> +</div> + +<h3 id="語法錯誤:第三回合">語法錯誤:第三回合</h3> + +<ol> + <li>現在如果你試著再次玩這個遊戲應該會相當順利,直到該讓遊戲結束的時機點才會發生錯誤:無論是猜對還是10次用完。</li> + <li>此時console提供錯誤訊息跟一開始一樣: "TypeError: resetButton.addeventListener is not a function"! 然而此次錯誤來自第94行。查看第94行後,我們可以輕易發現依舊是屬性大小寫問題,一樣把<code>addeventListener</code> 改成 <code>.addEventListener</code>就沒問題了。</li> +</ol> + +<h2 id="邏輯錯誤">邏輯錯誤</h2> + +<p>到這邊為止遊戲應該可以進行得很順利,然而玩幾次下來無疑地你會發現「隨機」數字總是0或1,這可不是我們想要的!</p> + +<ol> + <li>搜尋位於44行的變數<code>randomNumber</code>,其內容是設定遊戲一開始的隨機數字: + + <pre class="brush: js notranslate">var randomNumber = Math.floor(Math.random()) + 1;</pre> + </li> + <li>另一個開始新回合時產生隨機數字的變數則在113行左右: + <pre class="brush: js notranslate">randomNumber = Math.floor(Math.random()) + 1;</pre> + </li> + <li>為了測試問題是否出在這兩段程式碼,我們需要再次邀請<code>console.log()</code> 好朋友,將之分別放到44、113行的程式碼下一行: + <pre class="brush: js notranslate">console.log(randomNumber);</pre> + </li> + <li>儲存程式碼並更新頁面,然後再試玩幾次,你會看到<code>randomNumber</code> 在console中總是等於1,這就是問題所在。</li> +</ol> + +<h3 id="修正小錯誤">修正小錯誤</h3> + +<p>為了修正這個錯誤,我們得先了解它是怎麼運作的。首先,我們呼叫<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random">Math.random()</a></code>以產生一個介於0到1的隨機小數,例如: 0.5675493843</p> + +<pre class="brush: js notranslate">Math.random()</pre> + +<p>接著,我們將<code>Math.random()</code> 產生的隨機小數傳進<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor">Math.floor()</a></code>,函式會回傳小於等於所給數字的最大整數,然後為這個整數值加1:</p> + +<pre class="notranslate">Math.floor(Math.random()) + 1</pre> + +<p><font face="Arial, x-locale-body, sans-serif"><span style="background-color: #ffffff;">由於</span></font><code>Math.floor</code>是無條件捨去取整數(地板值),所以一個介於0到1的隨機小數永遠只會得到0,幫這個小數加1的話又會永遠只得到1。所以進位前我們先幫隨機小數乘上100 ,如此一來我們就能得到介於0到99的隨機數字了:</p> + +<pre class="brush: js notranslate">Math.floor(Math.random()*100);</pre> + +<p>別忘了還要加上1,數字範圍才能成功介於1到100:</p> + +<pre class="brush: js notranslate">Math.floor(Math.random()*100) + 1;</pre> + +<p>試著自己動手更新這兩行程式碼吧,儲存並更新頁面後你應該能看到遊戲如預期般進行!</p> + +<h2 id="其他常見錯誤">其他常見錯誤</h2> + +<p>還有些初學者非常容易忽略的小問題,這小節讓我們來概覽一下:</p> + +<h3 id="語法錯誤:語句缺少「_」_(SyntaxError_missing_before_statement)">語法錯誤:語句缺少「 ; 」<br> + (SyntaxError: missing ; before statement)</h3> + +<p>這個錯誤是指每行程式碼結束時必須加上英文輸入法的分號<code>;</code>(請注意不要打成中文輸入法),分號被遺忘的錯誤有時不太容易發現,此外另舉一例:如果我們改動下方變數<code>checkGuess()</code> 中的程式碼:</p> + +<pre class="brush: js notranslate">var userGuess = Number(guessField.value);</pre> + +<p>改成</p> + +<pre class="brush: js notranslate">var userGuess === Number(guessField.value);</pre> + +<p>此時程式碼會回報錯誤,因為瀏覽器會認為你想設定不同的東西;我們需要確保自己沒有誤用、混用指派運算子(<code>=</code>):用於賦予變數值跟嚴格比較運算子(<code>===</code>):用於比較兩個值是否完全相等,並回覆<code>true</code>/<code>false</code>布林值。</p> + +<div class="note"> +<p><strong>Note</strong>: 更多細節請參考右方關於<em>缺少分號的語法錯誤</em>文章頁面: <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Missing_semicolon_before_statement">SyntaxError: missing ; before statement</a> 。</p> +</div> + +<h3 id="無論輸入什麼,程序總是顯示「你贏了」">無論輸入什麼,程序總是顯示「你贏了」</h3> + +<p>還有另一種混用指派運算子(<code>=</code>)與嚴格比較運算子(<code>===</code>)的狀況,舉例如果我們將變數 <code>checkGuess()</code>中的嚴格比較運算子(<code>===</code>)</p> + +<pre class="brush: js notranslate">if (userGuess === randomNumber) {</pre> + +<p>改成指派運算子(<code>=</code>)</p> + +<pre class="brush: js notranslate">if (userGuess = randomNumber) {</pre> + +<p>這個檢查就失效了,程式會永遠回傳 <code>true</code>而勝利並結束遊戲。請小心!</p> + +<h3 id="語法錯誤:參數列表後面缺少「」_(SyntaxError_missing_after_argument_list)">語法錯誤:參數列表後面缺少「)」 <br> + (SyntaxError: missing ) after argument list)</h3> + +<p>給完函數或方法參數時別忘了放上<code>)</code>右括號(請注意不要打成中文輸入法)。</p> + +<div class="note"> +<p><strong>Note</strong>: 更多細節請參考右方關於<em>缺少右括號的語法錯誤</em>文章頁面:<a href="/en-US/docs/Web/JavaScript/Reference/Errors/Missing_parenthesis_after_argument_list">SyntaxError: missing ) after argument list</a> 。</p> +</div> + +<h3 id="語法錯誤:屬性ID後缺少「」_SyntaxError_missing_after_property_id">語法錯誤:屬性ID後缺少「:」<br> + SyntaxError: missing : after property id</h3> + +<p>This error usually relates to an incorrectly formed JavaScript object, but in this case we managed to get it by changing</p> + +<pre class="brush: js notranslate">function checkGuess() {</pre> + +<p>to</p> + +<pre class="brush: js notranslate">function checkGuess( {</pre> + +<p>This has caused the browser to think that we are trying to pass the contents of the function into the function as an argument. Be careful with those parentheses!</p> + +<h3 id="語法錯誤:「」缺少SyntaxError_missing_after_function_body">語法錯誤:「}」缺少SyntaxError: missing } after function body</h3> + +<p>This is easy — it generally means that you've missed one of your curly braces from a function or conditional structure. We got this error by deleting one of the closing curly braces near the bottom of the <code>checkGuess()</code> function.</p> + +<h3 id="SyntaxError_expected_expression_got_string_or_SyntaxError_unterminated_string_literal">SyntaxError: expected expression, got '<em>string</em>' or SyntaxError: unterminated string literal</h3> + +<p>These errors generally mean that you've missed off a string value's opening or closing quote mark. In the first error above, <em>string</em> would be replaced with the unexpected character(s) that the browser found instead of a quote mark at the start of a string. The second error means that the string has not been ended with a quote mark.</p> + +<p>For all of these errors, think about how we tackled the examples we looked at in the walkthrough. When an error arises, look at the line number you are given, go to that line and see if you can spot what's wrong. Bear in mind that the error is not necessarily going to be on that line, and also that the error might not be caused by the exact same problem we cited above!</p> + +<div class="note"> +<p><strong>Note</strong>: See our <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Unexpected_token">SyntaxError: Unexpected token</a> and <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Unterminated_string_literal">SyntaxError: unterminated string literal</a> reference pages for more details about these errors.</p> +</div> + +<h2 id="小結">小結</h2> + +<p>So there we have it, the basics of figuring out errors in simple JavaScript programs. It won't always be that simple to work out what's wrong in your code, but at least this will save you a few hours of sleep and allow you to progress a bit faster when things don't turn out right earlier on in your learning journey.</p> + +<h2 id="See_also">See also</h2> + +<div> +<ul> + <li>There are many other types of errors that aren't listed here; we are compiling a reference that explains what they mean in detail — see the <a href="/en-US/docs/Web/JavaScript/Reference/Errors">JavaScript error reference</a>.</li> + <li>If you come across any errors in your code that you aren't sure how to fix after reading this article, you can get help! Ask on the <a class="external external-icon" href="https://discourse.mozilla-community.org/t/learning-web-development-marking-guides-and-questions/16294">Learning Area Discourse thread</a>, or in the <a href="irc://irc.mozilla.org/mdn">#mdn</a> IRC channel on <a class="external external-icon" href="https://wiki.mozilla.org/IRC">Mozilla IRC</a>. Tell us what your error is, and we'll try to help you. A listing of your code would be useful as well.</li> +</ul> +</div> + +<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps")}}</p> + +<h2 id="在這個學習模組中">在這個學習模組中</h2> + +<ul> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_is_JavaScript">什麼是JavaScript?</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/A_first_splash">初次接觸Javascript</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/What_went_wrong">什麼出錯了? JavaScript 的疑難排解(除錯)</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Variables">儲存你需要的資訊 — 變數</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Math">JavaScript 的基本運算— 數字 與 運算子</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Strings">處理文字 — JavaScript 的字串</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Useful_string_methods">有用的字串方法</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Arrays">陣列</a></li> + <li><a href="/zh-TW/docs/Learn/JavaScript/First_steps/Silly_story_generator">附錄:笑話產生器</a></li> +</ul> |