本文已参与「新人创作礼」活动,一起开启掘金创作之路。
本文是入门级教程,简要介绍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函数的返回值。