javascript函数
函数是 JavaScript 中的基本组件之一。一个函数是 JavaScript 过程是一组执行任务或计算值的语句。要使用一个函数,你必须将其定义在你希望调用它的作用域内。
当函数是一个对象的属性时,被叫做方法。
在javascript中,函数是头等对象,因为它们可以像任何其他对象一样具有属性和方法。它们与其他对象的区别在于函数可以被调用。它们是Function
对象。
如何定义函数
使用函数声明
一个函数定义(或称函数声明,或称函数语句)是由function
关键字和语句组成。有函数名称,函数参数列表,多个参数用逗号分隔,定义函数的语句,用大括号{}
包裹。
示例:定义一个简单的addSum
函数:
function addSum(x, y) {
return x + y;
}
函数的名称叫addSum
,它有两个参数,大括号中的语句将该函数的参数相加后返回。函数 的return
语句确定了函数的返回值。如果函数中没有return
语句,默认返回undefined
。
参数是原始参数(如数字,字符串,布尔值)作为值传递给函数,如果被调用函数改变了这个参数的值,不会影响到全局或调用函数。
参数如果是非原始值(如对象或数组),函数改变了这个非原始值的内容,这个改变会影响到函数外部的非原始值的内容。
函数生成器声明(function*
语句)
函数声明有一种特殊的语法
function* name(param) { statements }
使用函数表达式
使用函数表达式来创建函数,这个函数可以是匿名的,也可以提供函数名。
方式一(匿名函数表达式)示例:
const addSum = function (x, y) {
return x + y;
}
let sum = addSum(1, 3)
方式二(带函数名的函数表达式)示例:
const addSum = function fn (num) {
return num <= 1 ? 1 : fn(num - 1);
}
let sum = addSum(3)
当不以function
开头的函数语句就是函数表达式定义。
当函数只使用一次,通常使用IIFE
,IIFE
是在函数声明后立即调用的函数表达式。
(function() {
statements
})()
函数生成器表达式(function*
表达式)
function* [name](param) { statements }
构造函数表达式和函数声明类似,有着相同的语法,函数名称可以被省略。
箭头函数表达式(=>)
(params) => { statements }
Function构造函数
不推荐使用Function
构造函数创建函数,因为它需要的函数体作为字符串可能会阻止一些JS引擎优化,也会引起其他问题。
new Function(...args)
如何调用函数
函数只有被调用后才会执行,函数不会自动执行。
函数调用时一定要处于声明它的函数域(指函数声明时所在的地方,或者函数在顶层被声明时指整个程序)中,但是函数的声明可以被提升(函数提升仅适用于函数声明的方式,不适用于函数表达式)。
正确示例:
// 方式一:addSum(1, 4),使用函数声明方式可以提升
function addSum (x, y) {
return x + y;
}
// 方式二:addSum(1, 4) // 正常调用函数
函数可以调用自身,即递归函数。递归近似于循环,两者都重复执行相同的代码,并且两者都需要一个终止条件(避免无限循环或无限递归)。
// 计算阶乘
function factorial(n){
if ((n == 0) || (n == 1))
return 1;
else
return (n * factorial(n - 1));
}
错误示例:
addSum(1) // Uncaught ReferenceError: Cannot access 'addSum' before initialization
const addSum = function fn (num) {
return num <= 1 ? 1 : fn(num - 1);
}
函数的参数
调用函数时,传递给函数的值被称为函数的实参(值传递),对应位置的函数参数名被叫作形参。
ES6中,函数有两个新的类型的参数:默认参数和剩余参数。
默认参数
在javascript中,函数参数的默认值是undefined
,然而,在某些情况下设置不同的默认值是有用的。
function outside(x, y = 1) {
return x * y;
}
剩余参数
剩余参数允许将不确定数量的参数表示为数组。
function getArgs(x, ...args) {
return args;
}
getArgs(10, 11, 2, 4, 5) // [11, 2, 4, 5]
什么是函数作用域
在函数内定义的变量不能在函数之外的任何地方访问,因为变量仅在该函数的域内部有定义。相对应的,一个函数可以访问定义在其范围内的任何变量和函数。换言之,定义在全局域中的函数可以访问所有定义在全局域中的变量。在另一个函数中定义的函数也可以访问在其父函数中定义的所有变量和父函数有权访问的任何其他变量。
函数中使用arguments
对象
函数的实际参数会被保存在一个类似数组的arguments
对象中,
function outside(x, y) {
console.log(arguments) //Arguments(2) [10, 11, callee: ƒ, Symbol(Symbol.iterator): ƒ]
}
outside(10, 11)
使用 arguments
对象,你可以处理比声明的更多的参数来调用函数。这在你事先不知道会需要将多少参数传递给函数时十分有用。你可以用arguments.length
来获得实际传递给函数的参数的数量,然后用arguments
对象来取得每个参数。
注意:arguments
变量只是类数组对象,并不是一个数组,叫类数组对象是说它有一个索引编号和length
属性,但它并不拥有数组全部的操作方法。
箭头函数
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this
,arguments
,super
或new.target
。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且箭头函数不能用作构造函数。
var Foo = () => {};
更多关于箭头函数的内容参考下一部分内容。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。