Functions — reusable blocks of code

Another essential concept in coding is 函数 , which allow you to store a piece of code that does a single task inside a defined block, and then call that code whenever you need it using a single short command — rather than having to type out the same code multiple times. In this article we'll explore fundamental concepts behind functions such as basic syntax, how to invoke and define them, scope, and parameters.

Prerequisites: Basic computer literacy, a basic understanding of HTML and CSS, JavaScript 第一步 .
Objective: To understand the fundamental concepts behind JavaScript functions.

Where do I find functions?

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.

Pretty much anytime you make use of a JavaScript structure that features a pair of parentheses — () — and you're not using a common built-in language structure like a for 循环 , while or do...while loop ,或 if...else statement , you are making use of a function.

Built-in browser functions

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:

const myText = 'I am a string';
const newString = myText.replace('string', 'sausage');
console.log(newString);
// the replace() string function takes a source string,
// and a target string and replaces the source string,
// with the target string, and returns the newly formed string

						

Or every time we manipulated an array:

const myArray = ['I', 'love', 'chocolate', 'frogs'];
const 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

						

Or every time we generated a random number:

const myNumber = Math.random();
// the random() function generates a random number between
// 0 and up to but not including 1, and returns that number

						

...we were using a function!

注意: Feel free to enter these lines into your browser's JavaScript console to re-familiarize yourself with their functionality, if needed.

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 invoke (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.

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 this early section of our course for more descriptions). We'll look at using browser APIs in more detail in a later module.

Functions versus methods

Programmers call 函数 that are part of objects  方法 . 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.

The built-in code we've made use of so far come in both forms: 函数 and 方法。 You can check the full list of the built-in functions, as well as the built-in objects and their corresponding methods  here .

You've also seen a lot of custom functions 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 random-canvas-circles.html example (see also the full 源代码 ) from our loops article , we included a custom draw() function that looked like this:

function draw() {
  ctx.clearRect(0,0,WIDTH,HEIGHT);
  for (let 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();
  }
}

						

This function draws 100 random circles inside a  <canvas> element. Every time we want to do that, we can just invoke the function with this:

draw();

						

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 random() function three times, which is defined by the following code:

function random(number) {
  return Math.floor(Math.random()*number);
}

						

We needed this function because the browser's built-in Math.random() function only generates a random decimal number between 0 and 1. We wanted a random whole number between 0 and a specified number.

Invoking functions

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.

function myFunction() {
  alert('hello');
}
myFunction();
// calls the function once

						

注意: This form of creating a function is also known as 函数声明 . It is always hoisted, so you can call function above function definition and it will work fine.

函数参数

Some functions require 参数 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.

注意: Parameters are sometimes called arguments, properties, or even attributes.

As an example, the browser's built-in Math.random() function doesn't require any parameters. When called, it always returns a random number between 0 and 1:

const myNumber = Math.random();

						

The browser's built-in string replace() function however needs two parameters — the substring to find in the main string, and the substring to replace that string with:

const myText = 'I am a string';
const newString = myText.replace('string', 'sausage');

						

注意: When you need to specify multiple parameters, they are separated by commas.

可选参数

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 join() function's parameter is optional:

const myArray = ['I', 'love', 'chocolate', 'frogs'];
const madeAString = myArray.join(' ');
console.log(madeAString);
// returns 'I love chocolate frogs'
const madeAnotherString = myArray.join();
console.log(madeAnotherString);
// returns 'I,love,chocolate,frogs'

						

If no parameter is included to specify a joining/delimiting character, a comma is used by default.

默认参数

If you're writing a function and want to support optional parameters, you can specify default values by adding = after the name of the parameter, followed by the default value:

function hello(name='Chris') {
  console.log(`Hello ${name}!`);
}
hello('Ari'); // Hello Ari!
hello();      // Hello Chris!

						

Anonymous functions and arrow functions

So far we have just created a function like so:

function myFunction() {
  alert('hello');
}

						

But you can also create a function that doesn't have a name:

function() {
  alert('hello');
}

						

This is called an anonymous function , because it has no name. You'll often see anonymous functions when a function expects to receive another function as a parameter. In this case the function parameter is often passed as an anonymous function.

注意: This form of creating a function is also known as 函数表达式 . Unlike function declaration, function expressions are not hoisted.

Anonymous function example

For example, let's say you want to run some code when the user types into a text box. To do this you can call the addEventListener() function of the text box. This function expects you to pass it (at least) two parameters:

  • the name of the event to listen for, which in this case is "keydown"
  • a function to run when the event happens.

When the user presses a key, the browser will call the function you provided, and will pass it a parameter containing information about this event, including the particular key that the user pressed:

function logKey(event) {
  console.log(`You pressed "${event.key}".`);
}
textBox.addEventListener('keydown', logKey);

						

Instead of defining a separate logKey() function, you can pass an anonymous function into addEventListener() :

textBox.addEventListener('keydown', function(event) {
  console.log(`You pressed "${event.key}".`);
});

						

箭头函数

If you pass an anonymous function like this, there's an alternative form you can use, called a arrow function . Instead of function(event) , you write (event) => :

textBox.addEventListener('keydown', (event) => {
  console.log(`You pressed "${event.key}".`);
});

						

If the function only has one line in the curly brackets, you omit the curly brackets:

textBox.addEventListener('keydown', (event) => console.log(`You pressed "${event.key}".`));

						

If the function only takes one parameter, you can also omit the brackets around the parameter:

textBox.addEventListener('keydown', event => console.log(`You pressed "${event.key}".`));

						

Finally, if your function needs to return a value, and contains only one line, you can also omit the return statement. In the following example we're using the map() 方法为 数组 to double every value in the original array:

const originals = [1, 2, 3];
const doubled = originals.map(item => item * 2);
console.log(doubled); // [2, 4, 6]

						

map() method takes each item in the array in turn, passing it into the given function. It then takes the value returned by that function and adds it to a new array.

So in the example above, item => item * 2 is the arrow function equivalent of:

function doubleItem(item) {
  return item * 2;
}

						

We recommend that you use arrow functions, as they can make your code shorter and more readable. To learn more, see the section on arrow functions in the JavaScript guide , and our reference page on arrow functions .

注意: There are some subtle differences between arrow functions and normal functions. They're outside the scope of this introductory guide, and are unlikely to make a difference in the cases we've discussed here. To learn more, see the arrow function reference documentation .

Arrow function live sample

Here's a complete working example of the "keydown" example we discussed above:

The HTML:

<input id="textBox" type="text"></input>
<div id="output"></div>

						

The JavaScript:

const textBox = document.querySelector("#textBox");
const output = document.querySelector("#output");
textBox.addEventListener('keydown', event => output.textContent = `You pressed "${event.key}".`);

						

The result - try typing into the text box and see the output:

Function scope and conflicts

Let's talk a bit about 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 scope , meaning that they are locked away in their own separate compartments, unreachable from code outside the functions.

The top level outside all your functions is called the global scope . Values defined in the global scope are accessible from everywhere in the code.

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.

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:

<!-- Excerpt from my HTML -->
<script src="first.js"></script>
<script src="second.js"></script>
<script>
  greeting();
</script>

						
// first.js
const name = 'Chris';
function greeting() {
  alert(`Hello ${name}: welcome to our company.`);
}

						
// second.js
const name = 'Zaptec';
function greeting() {
  alert(`Our company is called ${name}.`);
}

						

Both functions you want to call are called greeting() , but you can only ever access the first.js 文件的 greeting() function (the second one is ignored). In addition, an error results when attempting (in the second.js file) to assign a new value to the  名称 variable — because it was already declared with const , and so can’t be reassigned.

注意: You can see this example running live on GitHub (see also the 源代码 ).

Keeping parts of your code locked away in functions avoids such problems, and is considered the best practice.

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!

The zoo keeper is like the global scope — they have the keys to access every enclosure, to restock food, tend to sick animals, etc.

Active learning: Playing with scope

Let's look at a real example to demonstrate scoping.

  1. First, make a local copy of our function-scope.html example. This contains two functions called a() and b() , and three variables — x , y ,和 z — two of which are defined inside the functions, and one in the global scope. It also contains a third function called output() , which takes a single parameter and outputs it in a paragraph on the page.
  2. Open the example up in a browser and in your text editor.
  3. Open the JavaScript console in your browser developer tools. In the JavaScript console, enter the following command:
    output(x);
    
    								
    You should see the value of variable x printed to the browser viewport.
  4. Now try entering the following in your console
    output(y);
    output(z);
    
    								
    Both of these should throw an error into the console along the lines of " ReferenceError: y is not defined ". Why is that? Because of function scope — y and z are locked inside the a() and b() functions, so output() can't access them when called from the global scope.
  5. However, what about when it's called from inside another function? Try editing a() and b() so they look like this:
    function a() {
      const y = 2;
      output(y);
    }
    function b() {
      const z = 3;
      output(z);
    }
    
    								
    Save the code and reload it in your browser, then try calling the a() and b() functions from the JavaScript console:
    a();
    b();
    
    								
    You should see the y and z values printed in the browser viewport. This works fine, as the output() function is being called inside the other functions — in the same scope as the variables it is printing are defined in, in each case. output() itself is available from anywhere, as it is defined in the global scope.
  6. Now try updating your code like this:
    function a() {
      const y = 2;
      output(x);
    }
    function b() {
      const z = 3;
      output(x);
    }
    
    								
  7. Save and reload again, and try this again in your JavaScript console:
    a();
    b();
    
    								
    两者 a() and b() call should print the value of x to the browser viewport. These work fine because even though the output() calls are not in the same scope as x is defined in, x is a global variable so is available inside all code, everywhere.
  8. Finally, try updating your code like this:
    function a() {
      const y = 2;
      output(z);
    }
    function b() {
      const z = 3;
      output(y);
    }
    
    								
  9. Save and reload again, and try this again in your JavaScript console:
    a();
    b();
    
    								
    This time the a() and b() calls will throw that annoying ReferenceError: variable name is not defined error into the console — this is because the output() calls and the variables they are trying to print are not in the same function scopes — the variables are effectively invisible to those function calls.

注意: The same scoping rules do not apply to loop (e.g. for() { ... } ) and conditional blocks (e.g. if() { ... } ) — they look very similar, but they are not the same thing! Take care not to get these confused.

注意: ReferenceError: "x" is not defined 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.

Functions inside functions

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:

function myBigFunction() {
  const myValue;
  subFunction1();
  subFunction2();
  subFunction3();
}
function subFunction1() {
  console.log(myValue);
}
function subFunction2() {
  console.log(myValue);
}
function subFunction3() {
  console.log(myValue);
}

						

Just make sure that the values being used inside the function are properly in scope. The example above would throw an error ReferenceError: myValue is not defined , because although the myValue 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:

function myBigFunction() {
  const 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);
}

						

Test your skills!

You've reached the end of this article, but can you remember the most important information? You can find some further tests to verify that you've retained this information before you move on — see Test your skills: Functions . These tests require skills that are covered in the next two articles, so you might want to read those first before trying it.

结论

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.

另请参阅

In this module

发现此页面有问题吗?

最后修改: , 由 MDN 贡献者

  1. Complete beginners start here!
  2. Web 快速入门
    1. Getting started with the Web overview
    2. 安装基本软件
    3. What will your website look like?
    4. 处理文件
    5. HTML 基础
    6. CSS 基础
    7. JavaScript 基础
    8. 发布您的网站
    9. How the Web works
  3. HTML — Structuring the Web
  4. HTML 介绍
    1. Introduction to HTML overview
    2. Getting started with HTML
    3. What's in the head? Metadata in HTML
    4. HTML text fundamentals
    5. Creating hyperlinks
    6. Advanced text formatting
    7. Document and website structure
    8. Debugging HTML
    9. Assessment: Marking up a letter
    10. Assessment: Structuring a page of content
  5. 多媒体和嵌入
    1. Multimedia and embedding overview
    2. Images in HTML
    3. Video and audio content
    4. From object to iframe — other embedding technologies
    5. Adding vector graphics to the Web
    6. Responsive images
    7. Assessment: Mozilla splash page
  6. HTML 表格
    1. HTML tables overview
    2. HTML table basics
    3. HTML Table advanced features and accessibility
    4. Assessment: Structuring planet data
  7. CSS — Styling the Web
  8. CSS 第一步
    1. CSS first steps overview
    2. What is CSS?
    3. Getting started with CSS
    4. How CSS is structured
    5. How CSS works
    6. Using your new knowledge
  9. CSS 构建块
    1. CSS building blocks overview
    2. Cascade and inheritance
    3. CSS 选择器
    4. The box model
    5. Backgrounds and borders
    6. Handling different text directions
    7. Overflowing content
    8. Values and units
    9. Sizing items in CSS
    10. Images, media, and form elements
    11. Styling tables
    12. Debugging CSS
    13. Organizing your CSS
  10. 样式化文本
    1. Styling text overview
    2. Fundamental text and font styling
    3. Styling lists
    4. Styling links
    5. Web fonts
    6. Assessment: Typesetting a community school homepage
  11. CSS 布局
    1. CSS layout overview
    2. Introduction to CSS layout
    3. Normal Flow
    4. Flexbox
    5. Grids
    6. Floats
    7. 位置
    8. Multiple-column Layout
    9. Responsive design
    10. Beginner's guide to media queries
    11. Legacy Layout Methods
    12. Supporting Older Browsers
    13. Fundamental Layout Comprehension
  12. JavaScript — Dynamic client-side scripting
  13. JavaScript 第一步
    1. JavaScript first steps overview
    2. What is JavaScript?
    3. A first splash into JavaScript
    4. What went wrong? Troubleshooting JavaScript
    5. Storing the information you need — Variables
    6. Basic math in JavaScript — Numbers and operators
    7. Handling text — Strings in JavaScript
    8. Useful string methods
    9. 数组
    10. Assessment: Silly story generator
  14. JavaScript 构建块
    1. JavaScript building blocks overview
    2. Making decisions in your code — Conditionals
    3. Looping code
    4. Functions — Reusable blocks of code
    5. Build your own function
    6. Function return values
    7. 事件介绍
    8. Assessment: Image gallery
  15. 引入 JavaScript 对象
    1. Introducing JavaScript objects overview
    2. Object basics
    3. 对象原型
    4. Object-oriented programming concepts
    5. Classes in JavaScript
    6. Working with JSON data
    7. Object building practice
    8. Assessment: Adding features to our bouncing balls demo
  16. 异步 JavaScript
    1. Asynchronous JavaScript overview
    2. General asynchronous programming concepts
    3. Introducing asynchronous JavaScript
    4. Cooperative asynchronous Java​Script: Timeouts and intervals
    5. Graceful asynchronous programming with Promises
    6. Making asynchronous programming easier with async and await
    7. Choosing the right approach
  17. 客户端侧 Web API
    1. 客户端侧 Web API
    2. Introduction to web APIs
    3. Manipulating documents
    4. Fetching data from the server
    5. Third party APIs
    6. Drawing graphics
    7. Video and audio APIs
    8. Client-side storage
  18. Web forms — Working with user data
  19. Core forms learning pathway
    1. Web forms overview
    2. Your first form
    3. How to structure a web form
    4. Basic native form controls
    5. The HTML5 input types
    6. Other form controls
    7. Styling web forms
    8. Advanced form styling
    9. UI pseudo-classes
    10. Client-side form validation
    11. Sending form data
  20. Advanced forms articles
    1. How to build custom form controls
    2. Sending forms through JavaScript
    3. CSS property compatibility table for form controls
  21. Accessibility — Make the web usable by everyone
  22. Accessibility guides
    1. Accessibility overview
    2. What is accessibility?
    3. HTML: A good basis for accessibility
    4. CSS and JavaScript accessibility best practices
    5. WAI-ARIA basics
    6. Accessible multimedia
    7. Mobile accessibility
  23. Accessibility assessment
    1. Assessment: Accessibility troubleshooting
  24. Tools and testing
  25. Client-side web development tools
    1. Client-side web development tools index
    2. Client-side tooling overview
    3. Command line crash course
    4. Package management basics
    5. Introducing a complete toolchain
    6. Deploying our app
  26. Introduction to client-side frameworks
    1. Client-side frameworks overview
    2. Framework main features
  27. React
    1. Getting started with React
    2. Beginning our React todo list
    3. Componentizing our React app
    4. React interactivity: Events and state
    5. React interactivity: Editing, filtering, conditional rendering
    6. Accessibility in React
    7. React resources
  28. Ember
    1. Getting started with Ember
    2. Ember app structure and componentization
    3. Ember interactivity: Events, classes and state
    4. Ember Interactivity: Footer functionality, conditional rendering
    5. Routing in Ember
    6. Ember resources and troubleshooting
  29. Vue
    1. Getting started with Vue
    2. Creating our first Vue component
    3. Rendering a list of Vue components
    4. Adding a new todo form: Vue events, methods, and models
    5. Styling Vue components with CSS
    6. Using Vue computed properties
    7. Vue conditional rendering: editing existing todos
    8. Focus management with Vue refs
    9. Vue resources
  30. Svelte
    1. Getting started with Svelte
    2. Starting our Svelte Todo list app
    3. Dynamic behavior in Svelte: working with variables and props
    4. Componentizing our Svelte app
    5. Advanced Svelte: Reactivity, lifecycle, accessibility
    6. Working with Svelte stores
    7. TypeScript support in Svelte
    8. Deployment and next steps
  31. Angular
    1. Getting started with Angular
    2. Beginning our Angular todo list app
    3. Styling our Angular app
    4. Creating an item component
    5. Filtering our to-do items
    6. Building Angular applications and further resources
  32. Git and GitHub
    1. Git and GitHub overview
    2. Hello World
    3. Git Handbook
    4. Forking Projects
    5. About pull requests
    6. Mastering Issues
  33. Cross browser testing
    1. Cross browser testing overview
    2. Introduction to cross browser testing
    3. Strategies for carrying out testing
    4. Handling common HTML and CSS problems
    5. Handling common JavaScript problems
    6. Handling common accessibility problems
    7. Implementing feature detection
    8. Introduction to automated testing
    9. Setting up your own test automation environment
  34. Server-side website programming
  35. 第一步
    1. First steps overview
    2. Introduction to the server-side
    3. Client-Server overview
    4. Server-side web frameworks
    5. Website security
  36. Django Web 框架 (Python)
    1. Django web framework (Python) overview
    2. 介绍
    3. 设置开发环境
    4. Tutorial: The Local Library website
    5. Tutorial Part 2: Creating a skeleton website
    6. Tutorial Part 3: Using models
    7. Tutorial Part 4: Django admin site
    8. Tutorial Part 5: Creating our home page
    9. Tutorial Part 6: Generic list and detail views
    10. Tutorial Part 7: Sessions framework
    11. Tutorial Part 8: User authentication and permissions
    12. Tutorial Part 9: Working with forms
    13. Tutorial Part 10: Testing a Django web application
    14. Tutorial Part 11: Deploying Django to production
    15. Web application security
    16. Assessment: DIY mini blog
  37. Express Web Framework (node.js/JavaScript)
    1. Express Web Framework (Node.js/JavaScript) overview
    2. Express/Node introduction
    3. Setting up a Node (Express) development environment
    4. Express tutorial: The Local Library website
    5. Express Tutorial Part 2: Creating a skeleton website
    6. Express Tutorial Part 3: Using a database (with Mongoose)
    7. Express Tutorial Part 4: Routes and controllers
    8. Express Tutorial Part 5: Displaying library data
    9. Express Tutorial Part 6: Working with forms
    10. Express Tutorial Part 7: Deploying to production
  38. Further resources
  39. Common questions
    1. HTML questions
    2. CSS questions
    3. JavaScript questions
    4. Web mechanics
    5. Tools and setup
    6. Design and accessibility