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/building_blocks/functions | |
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/building_blocks/functions')
-rw-r--r-- | files/zh-tw/learn/javascript/building_blocks/functions/index.html | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/files/zh-tw/learn/javascript/building_blocks/functions/index.html b/files/zh-tw/learn/javascript/building_blocks/functions/index.html new file mode 100644 index 0000000000..719180656f --- /dev/null +++ b/files/zh-tw/learn/javascript/building_blocks/functions/index.html @@ -0,0 +1,396 @@ +--- +title: 函數 - 可重複使用的代碼塊 +slug: Learn/JavaScript/Building_blocks/Functions +translation_of: Learn/JavaScript/Building_blocks/Functions +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Looping_code","Learn/JavaScript/Building_blocks/Build_your_own_function", "Learn/JavaScript/Building_blocks")}}</div> + +<p class="summary">編碼中的另一個基本概念是函數,它允許您存儲一段代碼,該代碼在定義的塊內執行單個任務,然後在需要時使用一個簡短命令調用該代碼 - 而不必輸入相同的代碼 代碼多次。 在本文中,我們將探索函數背後的基本概念,例如基本語法,如何調用和定義它們,範圍和參數。</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisites:</th> + <td>Basic computer literacy, a basic understanding of HTML and CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript first steps</a>.</td> + </tr> + <tr> + <th scope="row">Objective:</th> + <td>To understand the fundamental concepts behind JavaScript functions.</td> + </tr> + </tbody> +</table> + +<h2 id="Where_do_I_find_functions">Where do I find functions?</h2> + +<p>In JavaScript, you'll find functions everywhere. In fact, we've been using functions all the way through the course so far; we've just not been talking about them very much. Now is the time, however, for us to start talking about functions explicitly, and really exploring their syntax.</p> + +<p>Pretty much anytime you make use of a JavaScript structure that features a pair of parentheses — <code>()</code> — and you're <strong>not</strong> using a common built-in language structure like a <a href="/en-US/Learn/JavaScript/Building_blocks/Looping_code#The_standard_for_loop">for loop</a>, <a href="/en-US/Learn/JavaScript/Building_blocks/Looping_code#while_and_do_..._while">while or do...while loop</a>, or <a href="/en-US/Learn/JavaScript/Building_blocks/conditionals#if_..._else_statements">if...else statement</a>, you are making use of a function.</p> + +<h2 id="Built-in_browser_functions">Built-in browser functions</h2> + +<p>We've made use of functions built in to the browser a lot in this course. Every time we manipulated a text string, for example:</p> + +<pre class="brush: js">var myText = 'I am a string'; +var newString = myText.replace('string', 'sausage'); +console.log(newString); +// the replace() string function takes a string, +// replaces one substring with another, and returns +// a new string with the replacement made</pre> + +<p>Or every time we manipulated an array:</p> + +<pre class="brush: js">var myArray = ['I', 'love', 'chocolate', 'frogs']; +var madeAString = myArray.join(' '); +console.log(madeAString); +// the join() function takes an array, joins +// all the array items together into a single +// string, and returns this new string</pre> + +<p>Or every time we generated a random number:</p> + +<pre class="brush: js">var myNumber = Math.random(); +// the random() function generates a random +// number between 0 and 1, and returns that +// number</pre> + +<p>...we were using a function!</p> + +<div class="note"> +<p><strong>Note</strong>: Feel free to enter these lines into your browser's JavaScript console to re-familiarize yourself with their functionality, if needed.</p> +</div> + +<p>The JavaScript language has many built-in functions to allow you to do useful things without having to write all that code yourself. In fact, some of the code you are calling when you <strong>invoke</strong> (a fancy word for run, or execute) a built in browser function couldn't be written in JavaScript — many of these functions are calling parts of the background browser code, which is written largely in low-level system languages like C++, not web languages like JavaScript.</p> + +<p>Bear in mind that some built-in browser functions are not part of the core JavaScript language — some are defined as part of browser APIs, which build on top of the default language to provide even more functionality (refer to <a href="/en-US/Learn/JavaScript/First_steps/What_is_JavaScript#So_what_can_it_really_do">this early section of our course</a> for more descriptions). We'll look at using browser APIs in more detail in a later module.</p> + +<h2 id="Functions_versus_methods">Functions versus methods</h2> + +<p>One thing we need to clear up before we move on — technically speaking, built in browser functions are not functions — they are <strong>methods</strong>. This sounds a bit scary and confusing, but don't worry — the words function and method are largely interchangeable, at least for our purposes, at this stage in your learning.</p> + +<p>The distinction is that methods are functions defined inside objects. Built-in browser functions (methods) and variables (which are called <strong>properties</strong>) are stored inside structured objects, to make the code more efficient and easier to handle.</p> + +<p>You don't need to learn about the inner workings of structured JavaScript objects yet — you can wait until our later module that will teach you all about the inner workings of objects, and how to create your own. For now, we just wanted to clear up any possible confusion of method versus function — you are likely to meet both terms as you look at the available related resources across the Web.</p> + +<h2 id="Custom_functions">Custom functions</h2> + +<p>You've also seen a lot of <strong>custom functions</strong> in the course so far — functions defined in your code, not inside the browser. Anytime you saw a custom name with parentheses straight after it, you were using a custom function. In our <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/random-canvas-circles.html">random-canvas-circles.html</a> example (see also the full <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/random-canvas-circles.html">source code</a>) from our <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">loops article</a>, we included a custom <code>draw()</code> function that looked like this:</p> + +<pre class="brush: js">function draw() { + ctx.clearRect(0,0,WIDTH,HEIGHT); + for (var i = 0; i < 100; i++) { + ctx.beginPath(); + ctx.fillStyle = 'rgba(255,0,0,0.5)'; + ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); + ctx.fill(); + } +}</pre> + +<p>This function draws 100 random circles inside an {{htmlelement("canvas")}} element. Every time we want to do that, we can just invoke the function with this</p> + +<pre class="brush: js">draw();</pre> + +<p>rather than having to write all that code out again every time we want to repeat it. And functions can contain whatever code you like — you can even call other functions from inside functions. The above function for example calls the <code>random()</code> function three times, which is defined by the following code:</p> + +<pre class="brush: js">function random(number) { + return Math.floor(Math.random()*number); +}</pre> + +<p>We needed this function because the browser's built-in <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random">Math.random()</a> function only generates a random decimal number between 0 and 1. We wanted a random whole number between 0 and a specified number.</p> + +<h2 id="Invoking_functions">Invoking functions</h2> + +<p>You are probably clear on this by now, but just in case ... to actually use a function after it has been defined, you've got to run — or invoke — it. This is done by including the name of the function in the code somewhere, followed by parentheses.</p> + +<pre class="brush: js">function myFunction() { + alert('hello'); +} + +myFunction() +// calls the function once</pre> + +<h2 id="Anonymous_functions">Anonymous functions</h2> + +<p>You may see functions defined and invoked in slightly different ways. So far we have just created a function like so:</p> + +<pre class="brush: js">function myFunction() { + alert('hello'); +}</pre> + +<p>But you can also create a function that doesn't have a name:</p> + +<pre class="brush: js">function() { + alert('hello'); +}</pre> + +<p>This is called an <strong>anonymous function</strong> — it has no name! It also won't do anything on its own. You generally use an anonymous function along with an event handler, for example the following would run the code inside the function whenever the associated button is clicked:</p> + +<pre class="brush: js">var myButton = document.querySelector('button'); + +myButton.onclick = function() { + alert('hello'); +}</pre> + +<p>The above example would require there to be a {{htmlelement("button")}} element available on the page to select and click. You've already seen this structure a few times throughout the course, and you'll learn more about and see it in use in the next article.</p> + +<p>You can also assign an anonymous function to be the value of a variable, for example:</p> + +<pre class="brush: js">var myGreeting = function() { + alert('hello'); +}</pre> + +<p>This function could now be invoked using:</p> + +<pre class="brush: js">myGreeting();</pre> + +<p>This effectively gives the function a name; you can also assign the function to be the value of multiple variables, for example:</p> + +<pre class="brush: js">var anotherGreeting = function() { + alert('hello'); +}</pre> + +<p>This function could now be invoked using either of</p> + +<pre class="brush: js">myGreeting(); +anotherGreeting();</pre> + +<p>But this would just be confusing, so don't do it! When creating functions, it is better to just stick to this form:</p> + +<pre class="brush: js">function myGreeting() { + alert('hello'); +}</pre> + +<p>You will mainly use anonymous functions to just run a load of code in response to an event firing — like a button being clicked — using an event handler. Again, this looks something like this:</p> + +<pre class="brush: js">myButton.onclick = function() { + alert('hello'); + // I can put as much code + // inside here as I want +}</pre> + +<h2 id="Function_parameters">Function parameters</h2> + +<p>Some functions require <strong>parameters</strong> to be specified when you are invoking them — these are values that need to be included inside the function parentheses, which it needs to do its job properly.</p> + +<div class="note"> +<p><strong>Note</strong>: Parameters are sometimes called arguments, properties, or even attributes.</p> +</div> + +<p>As an example, the browser's built-in <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random">Math.random()</a> function doesn't require any parameters. When called, it always returns a random number between 0 and 1:</p> + +<pre class="brush: js">var myNumber = Math.random();</pre> + +<p>The browser's built-in string <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace()</a> function however needs two parameters — the substring to find in the main string, and the substring to replace that string with:</p> + +<pre class="brush: js">var myText = 'I am a string'; +var newString = myText.replace('string', 'sausage');</pre> + +<div class="note"> +<p><strong>Note</strong>: When you need to specify multiple parameters, they are separated by commas.</p> +</div> + +<p>It should also be noted that sometimes parameters are optional — you don't have to specify them. If you don't, the function will generally adopt some kind of default behavior. As an example, the array <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join">join()</a> function's parameter is optional:</p> + +<pre class="brush: js">var myArray = ['I', 'love', 'chocolate', 'frogs']; +var madeAString = myArray.join(' '); +// returns 'I love chocolate frogs' +var madeAString = myArray.join(); +// returns 'I,love,chocolate,frogs'</pre> + +<p>If no parameter is included to specify a joining/delimiting character, a comma is used by default.</p> + +<h2 id="Function_scope_and_conflicts">Function scope and conflicts</h2> + +<p>Let's talk a bit about {{glossary("scope")}} — a very important concept when dealing with functions. When you create a function, the variables and other things defined inside the function are inside their own separate <strong>scope</strong>, meaning that they are locked away in their own separate compartments, unreachable from inside other functions or from code outside the functions.</p> + +<p>The top level outside all your functions is called the <strong>global scope</strong>. Values defined in the global scope are accessible from everywhere in the code.</p> + +<p>JavaScript is set up like this for various reasons — but mainly because of security and organization. Sometimes you don't want variables to be accessible from everywhere in the code — external scripts that you call in from elsewhere could start to mess with your code and cause problems because they happen to be using the same variable names as other parts of the code, causing conflicts. This might be done maliciously, or just by accident.</p> + +<p>For example, say you have an HTML file that is calling in two external JavaScript files, and both of them have a variable and a function defined that use the same name:</p> + +<pre class="brush: html"><!-- Excerpt from my HTML --> +<script src="first.js"></script> +<script src="second.js"></script> +<script> + greeting(); +</script></pre> + +<pre class="brush: js">// first.js +var name = 'Chris'; +function greeting() { + alert('Hello ' + name + ': welcome to our company.'); +}</pre> + +<pre class="brush: js">// second.js +var name = 'Zaptec'; +function greeting() { + alert('Our company is called ' + name + '.'); +}</pre> + +<p>Both functions you want to call are called <code>greeting()</code>, but you can only ever access the <code>second.js</code> file's <code>greeting()</code> function — it is applied to the HTML later on in the source code, so its variable and function overwrite the ones in <code>first.js</code>.</p> + +<div class="note"> +<p><strong>Note</strong>: You can see this example <a href="http://mdn.github.io/learning-area/javascript/building-blocks/functions/conflict.html">running live on GitHub</a> (see also the <a href="https://github.com/mdn/learning-area/tree/master/javascript/building-blocks/functions">source code</a>).</p> +</div> + +<p>Keeping parts of your code locked away in functions avoids such problems, and is considered best practice.</p> + +<p>It is a bit like a zoo. The lions, zebras, tigers, and penguins are kept in their own enclosures, and only have access to the things inside their enclosures — in the same manner as the function scopes. If they were able to get into other enclosures, problems would occur. At best, different animals would feel really uncomfortable inside unfamiliar habitats — a lion or tiger would feel terrible inside the penguins' watery, icy domain. At worst, the lions and tigers might try to eat the penguins!</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14079/MDN-mozilla-zoo.png" style="display: block; margin: 0 auto;"></p> + +<p>The zoo keeper is like the global scope — he or she has the keys to access every enclosure, to restock food, tend to sick animals, etc.</p> + +<h3 id="Active_learning_Playing_with_scope">Active learning: Playing with scope</h3> + +<p>Let's look at a real example to demonstrate scoping.</p> + +<ol> + <li>First, make a local copy of our <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-scope.html">function-scope.html</a> example. This contains two functions called <code>a()</code> and <code>b()</code>, and three variables — <code>x</code>, <code>y</code>, and <code>z</code> — two of which are defined inside the functions, and one in the global scope. It also contains a third function called <code>output()</code>, which takes a single parameter and outputs it in a paragraph on the page.</li> + <li>Open the example up in a browser and in your text editor.</li> + <li>Open the JavaScript console in your browser developer tools. In the JavaScript console, enter the following command: + <pre class="brush: js">output(x);</pre> + You should see the value of variable <code>x</code> output to the screen.</li> + <li>Now try entering the following in your console + <pre class="brush: js">output(y); +output(z);</pre> + Both of these should return an error along the lines of "<a href="/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined">ReferenceError: y is not defined</a>". Why is that? Because of function scope — <code>y</code> and <code>z</code> are locked inside the <code>a()</code> and <code>b()</code> functions, so <code>output()</code> can't access them when called from the global scope.</li> + <li>However, what about when it's called from inside another function? Try editing <code>a()</code> and <code>b()</code> so they look like this: + <pre class="brush: js">function a() { + var y = 2; + output(y); +} + +function b() { + var z = 3; + output(z); +}</pre> + Save the code and reload it in your browser, then try calling the <code>a()</code> and <code>b()</code> functions from the JavaScript console: + + <pre class="brush: js">a(); +b();</pre> + You should see the <code>y</code> and <code>z</code> values output in the page. This works fine, as the <code>output()</code> function is being called inside the other functions — in the same scope as the variables it is printing are defined in, in each case. <code>output()</code> itself is available from anywhere, as it is defined in the global scope.</li> + <li>Now try updating your code like this: + <pre class="brush: js">function a() { + var y = 2; + output(x); +} + +function b() { + var z = 3; + output(x); +}</pre> + Save and reload again, and try this again in your JavaScript console: + + <pre class="brush: js">a(); +b();</pre> + Both the <code>a()</code> and <code>b()</code> call should output the value of x — 1. These work fine because even though the <code>output()</code> calls are not in the same scope as <code>x</code> is defined in, <code>x</code> is a global variable so is available inside all code, everywhere.</li> + <li>Finally, try updating your code like this: + <pre class="brush: js">function a() { + var y = 2; + output(z); +} + +function b() { + var z = 3; + output(y); +}</pre> + Save and reload again, and try this again in your JavaScript console: + + <pre class="brush: js">a(); +b();</pre> + This time the <code>a()</code> and <code>b()</code> calls will both return that annoying "<a href="/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined">ReferenceError: z is not defined</a>" error — this is because the <code>output()</code> calls and the variables they are trying to print are not defined inside the same function scopes — the variables are effectively invisible to those function calls.</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: The same scoping rules do not apply to loop (e.g. <code>for() { ... }</code>) and conditional blocks (e.g. <code>if() { ... }</code>) — they look very similar, but they are not the same thing! Take care not to get these confused.</p> +</div> + +<div class="note"> +<p><strong>Note</strong>: The <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined">ReferenceError: "x" is not defined</a> error is one of the most common you'll encounter. If you get this error and you are sure that you have defined the variable in question, check what scope it is in.</p> +</div> + +<ul> +</ul> + +<h3 id="Functions_inside_functions">Functions inside functions</h3> + +<p>Keep in mind that you can call a function from anywhere, even inside another function. This is often used as a way to keep code tidy — if you have a big complex function, it is easier to understand if you break it down into several sub-functions:</p> + +<pre class="brush: js">function myBigFunction() { + var myValue; + + subFunction1(); + subFunction2(); + subFunction3(); +} + +function subFunction1() { + console.log(myValue); +} + +function subFunction2() { + console.log(myValue); +} + +function subFunction3() { + console.log(myValue); +} +</pre> + +<p>Just make sure that the values being used inside the function are properly in scope. The example above would throw an error <code>ReferenceError: myValue is not defined</code>, because although the <code>myValue</code> variable is defined in the same scope as the function calls, it is not defined inside the function definitions — the actual code that is run when the functions are called. To make this work, you'd have to pass the value into the function as a parameter, like this:</p> + +<pre class="brush: js">function myBigFunction() { + var myValue = 1; + + subFunction1(myValue); + subFunction2(myValue); + subFunction3(myValue); +} + +function subFunction1(value) { + console.log(value); +} + +function subFunction2(value) { + console.log(value); +} + +function subFunction3(value) { + console.log(value); +}</pre> + +<h2 id="Conclusion">Conclusion</h2> + +<p>This article has explored the fundamental concepts behind functions, paving the way for the next one in which we get practical and take you through the steps to building up your own custom function.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Functions">Functions detailed guide</a> — covers some advanced features not included here.</li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions">Functions reference</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters">Default parameters</a>, <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">Arrow functions</a> — advanced concept references</li> +</ul> + +<ul> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Looping_code","Learn/JavaScript/Building_blocks/Build_your_own_function", "Learn/JavaScript/Building_blocks")}}</p> + +<p> </p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> + +<p> </p> |