JS函数怎么写?

148 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

本文是入门级教程,简要介绍JS函数,不讲this

函数是一系列逻辑代码的封装。它可以接受一系列输入(参数),并最终返回一个结果。

基础写法

JS函数的基础写法很像Java或者C++,只是因为JS没有静态类型,所以不需要声明参数的类型,也不需要指定返回值的类型。例如:

function add (x, y) {
  return x + y
}

console.log(add(1, 2)) // 3

在调用时,按顺序传入函数的实际参数1, 2),这些参数会被赋值给参数表中定义的形式参数x, y),随后函数体中的代码会被执行。JS允许你调用函数时传入任意多个实际参数。超出形式参数的部分会被忽略,不足的部分形式参数会被赋值为undefined

在函数中,使用return关键字可以立即终止函数。return后面的表达式会被作为函数的返回值,替换掉函数的调用部分。因此,上面的例子最终输出了3

请注意,在JS的函数中,同一个函数的不同的return语句允许返回不同的类型。若return后没有表达式,则返回值为undefined。此外,return语句也会立即终止函数运行,例如:

function isPrime (x) {
  for (let i = 2; i <= Math.sqrt(x); i++) {
    if (x % i === 0) return false
  }
  return true
}

匿名函数

在上面的例子中,函数在被定义的时候都有自己的名字用于调用。事实上,JS的函数本身是一个对象。没错,就是那些大括号展开的那种对象。因此,JS函数可以作为任何变量的值,甚至作为一个对象中某个属性的值。例如:

const add = function (x, y) {
  return x + y
}

console.log(add(1, 2)) // 3

我们注意到,此时定义函数时我们没有在参数表之前放函数的名字。这种方法定义的JS函数被称为匿名函数。如你所见,匿名函数可以被赋值给一个变量(add),随后你就可以正常地调用这个函数了。

如果你愿意在整个函数外面加一个小括号,你甚至可以不用给它名字就调用它,例如:

(function () {
  console.log('hello!')
})()

第一组小括号用于将函数打包成一个对象,最后一组小括号用于调用函数。这样的代码看起来很丑陋,但是在一些特殊的情况下会很有用(例如闭包etc.)。

箭头函数

事实上,匿名函数可以用一种更简单的方式声明,我们甚至可以将function关键字都省略。例如:

const add = (x, y) => {
  return x + y
}

console.log(add(1, 2)) // 3

简单来说,我们将function关键字换成了一个从参数表指向函数体的箭头=>。它与function关键字定义的匿名函数基本等效,唯一区别在于this的指向问题,本文不做细述。

我们甚至可以将函数体的大括号{}return关键字都省略。当箭头函数只是返回一个表达式(例如这里的x + y),我们可以进一步省略写为:

const add = (x, y) => x + y

console.log(add(1, 2)) // 3
console.log(((x, y) => x + y)(2, 3)) // 5

是不是很优雅!

参数表

JS参数表可以接受默认参数,例如:

const add = (x = 1, y = 2) => x + y

console.log(add(2, 3)) // 5
console.log(add(2)) // 4
console.log(add()) // 3

当传入参数被缺省时,参数表中的默认参数就会启用。如果没有默认参数,缺省的参数会变为undefined

JS参数表也可以自动展开对象并匹配参数,例如:

const add = ({ x, y }) => x + y

console.log(add({ x: 2, y: 3 })) // 5

JS参数表也可以匹配可变数量的参数,例如:

const print = (first, ...rest) => {
  console.log(first, rest)
}
print(1, 2, 3, 4) // 1, [2, 3, 4]

使用展开运算符...我们就可以将剩余的参数打包为数组(rest),在函数中使用。

异步函数

JS异步超过了本文作为入门教程的难度上限,Promise相关的内容也许会在以后的其他教程中详细讲解。

在整个函数头部之前加上关键字async,我们就可以构造一个异步函数。需要了解的是,在异步函数中我们可以使用关键字await来等待一个Promise。例如:(这个例子只能在baidu首页的网页控制台运行)

async function baidu () {
  const res = await fetch('https://www.baidu.com/')
  console.log(res)
}
baidu()

简单说,异步函数会在调用时立即返回一个Promise,函数返回时这个Promise会resolve函数的返回值。