函数

函数 属于 JavaScript

6 个练习

关于 函数

函数是一段有组织、可复用的代码,用于执行某个操作。在 JavaScript 中,定义函数有多种方式。这里我们会了解_函数声明_和_函数表达式_。其他方式,比如箭头函数,会在其他概念中介绍。

函数声明

在 JavaScript 中,定义函数的标准方式是_函数声明_,也叫_函数定义_或_函数语句_。

它由function关键字、函数名,以及用圆括号括起来、以逗号分隔的形参列表组成。之后是函数体(一组定义函数做什么的语句),用大括号包起来。

function someName(param1, param2, param3) {
  // ...
}

调用函数

在 JavaScript 中,调用函数的方法是写出函数名,后面跟上包含实参的圆括号。

someName(arg1, arg2, arg3);

在 JavaScript 中,仅仅写出函数名并不会调用函数。

function sayHello() {
  console.log('Hello, World!');
}

sayHello;
// => [Function: sayHello]
// The text representations varies between environments.

sayHello();
// => 'Hello, World!'

形参

在函数体中使用形参时,要留意可能对传入函数的原始值造成的副作用。在 JavaScript 中,实参是原始值引用的一个副本。这在实践中意味着什么,取决于实参的数据类型。

  • 原始数据类型的值是_不可变的_。 所有的“修改”都会创建一个新的原始值。 因此,函数体中对实参所做的任何操作都不会影响原始值。

    const num = 0;
    
    function increase(number) {
      number = number + 1;
    }
    
    increase(num);
    num;
    // => 0
    
  • 对于_对象_、数组、_函数_这样的值来说,情况就不同了。 由于复制的是引用,重新赋值不会影响原始值。 不过,由于你处理的是浅拷贝,修改函数体中的实参也会改变传入的原始值。

    const nums = [0, 1, 2, 3, 4];
    
    function pushFive(arr) {
      arr.push(5);
    }
    
    pushFive(nums);
    nums;
    // => [0, 1, 2, 3, 4, 5]
    

默认情况下,在 JavaScript 中,函数声明里定义的所有形参都是可选的。如果传给函数的实参比形参少,缺失的实参在函数体中会是undefined,参见 null 和 undefined。在很多情况下,如果没有传入值,或传入的值是undefined,用_默认值_初始化形参往往更合理。这可以通过在函数定义中直接指定默认形参来实现。

function someName(param1 = defaultValue1, param2 = defaultValue2) {
  // ...
}

调用函数时传入的实参可以比函数定义中的形参多。所有实参,包括多出来的那些,都能在 arguments “数组”中找到。

也可以定义接受任意数量实参的函数(可变参数函数),更多细节参见剩余与展开运算符中的剩余形参。

return语句

return语句会结束函数的执行,并指定一个返回给函数调用方的值。一个函数可以有多个return语句。

function checkNumber(num) {
  if (num === 0) {
    return 'You passed 0, please provide another number.';
  }

  return 'Thanks for passing such a nice number.';
}

一个不返回值、或没有return语句的函数,其结果是undefined。JavaScript 中没有隐式的return。

function nakedReturn(a) {
  a * 2;
  return;
}

nakedReturn(1);
// => undefined

function noReturn(a) {
  a * 2;
}

noReturn(1);
// => undefined

在 JavaScript 中,你只能返回一个值。如果你想传递更多信息,需要先把它们组合成一个整体,通常是对象或数组。

function divide(a, b) {
  return {
    quotient: Math.floor(a / b),
    remainder: a % b,
  };
}

函数表达式

函数声明是一条独立的语句。但有时把函数定义为另一个表达式的一部分会很有用,比如放在赋值中、作为函数的形参(回调),或作为对象中的值。这可以用函数表达式来实现。它的语法与函数声明相同,只是可以省略函数名来创建一个_匿名函数_。

const someFunction = function (param) {
  // ...
};

someOtherFunction(function (param) {
  // ...
});

const obj = {
  someFunction: function (param) {
    // ...
  },
};

作用域

函数会在 JavaScript 中引入一个新的执行上下文。在函数内部定义的变量,在该函数外部无法访问。但定义在父级作用域(即函数自身被定义时所在的作用域)中的变量,在函数内部可以访问。MDN 关于作用域的文档展示了这种行为的例子。

想进一步了解 JavaScript 中的变量作用域,可以看看闭包。

通过 GitHub 编辑 该链接会在新窗口或标签页中打开

学习 函数