函数是第一类对象(函数是一等公民)
javascript中函数是第一类对象,函数拥有对象的所有能力。函数能够实现以下功能。
- 通过字面量创建。
function myFunc () {}
- 赋值给变量,数组项或其它对象属性。
var myfunc = function() {}//函数赋值给变量
arr.push(function() {})//函数作为数组项
myObj.item = function() {}//函数作为对象属性
- 作为函数的参数
function call(funcParam){
funcParam()
}
call(function(){})
- 作为函数的返回值
function retunFunc(){
return function(){}
}
- 具有动态创建和分配的属性
var myfunc = function() {}
myfunc.item = 'aaa'
回调函数
函数作为第一类对象的特点之一是作为函数的参数。将函数作为另一个函数的参数,随后会在未来某个时间点通过参数来调用该函数,称作回调函数。
回调函数是一种实现方式,与同步、异步没有直接关系。回调函数的使用场景可以是同步回调、异步回调、事件处理回调等
- 同步回调
function useless(callbackFunc){
callbackFunc()
}
- 异步回调
function useless(){
setTimeout(function(){
console.log('aaaaaaaaa')
}, 1000)
}
- 事件回调
document.body.addEventListener('mousemove', function(){
console.log('aaaaaaaa')
})
函数具有属性
函数作为第一类对象,我们可以给函数添加自定义属性(包括方法)。这种特性可以做更有趣的事情:
- 可以在函数属性中存储另一个函数用于之后的引用和调用
var store = {
nextId: 1,
cache: {},
add: function(fn) {
if(!fn.id){
fn.id = this.nextId++;
this.cache[fn.id] = fn;
return true;
}else{
return false;
}
}
}
function myFunc(){}
store.add(myFunc)//返回true
store.add(myFunc)//已经添加了,所以返回false
- 可以在函数属性创建一个缓存,用于减少不必要的计算
function isPrime(value){
if(!isPrime.answers){
isPrime.answers = {}
}
if(isPrime.answers[value] !== undefined){
return isPrime.answers[value]
}
var prime = value!==0 && value!==1;
for(var i=2; i<value; i++){
if(value % i===0) {
prime = false;
break;
}
}
return isPrime.answers[value] = prime;
}
isPrime(5)//true
isPrime.answers[5]//true
函数定义
- 函数声明 函数声明以强制性的function开头,其后紧接着强制性的函数名,以及括号和括号内一列以逗号分隔的参数名。函数体是一列可以为空的表达式,这些表达式包含在花括号中。
function myFunctionName (myFirstArg, mySecondArg) {
myStatement1;
myStatement2;
}
函数声明必须具有函数名,在代码中也必须作为独立的语句存在
- 函数表达式 Javascript中函数是第一类对象,这就意味着函数可以通过字面量创建,可以赋值给变量和属性,可以作为传递给其他函数的参数或返回值。 作为其他表达式的一部分的函数叫作函数表达式。
- 函数表达式作为变量声明赋值语句中的一部分
var myFunc = function(){}
- 函数表达式作为一次函数调用中的参数
function doSomething(action){
action()
}
- 函数表达式作为函数的返回值
myFunc(){
return function(){}
}
- 函数表达式可以作为一元操作符的参数
+function(){}
-function(){}
!function(){}
~function(){}
- 箭头函数 箭头函数是函数表达式的简化版,箭头函数的语法 胖箭头操作符前面是箭头函数的参数:如果没有参数或者多于一个参数,参数列表必须包裹在括号内。只有一个参数时,括号不是必须的。 胖箭头操作符后面是箭头函数的返回值:箭头函数的返回值可以是表达式也可以是代码块。
param => expression // 一个参数,返回表达式值
(param1, param2) => expression //两个参数,返回表达式的值
() => { // 没有参数,返回值是代码块
myStatement1;
myStatement2;
}
函数参数
- 形参和实参 形参是定义函数是所列举的变量。实参是调用函数时所传递给函数的值。实参是以函数形参制定的顺序赋值给函数形参。
- 剩余参数 额外的实参不会赋值给任何形参,这些多于的实参可以通过剩余参数获取。剩余参数为函数的最后一个命名参数前加上省略号(...)前缀,这个参数就变成了一个叫做剩余参数的数组,数组内包含着传入的剩余的参数。
function multimax(first, ...remainingNumbers){
...
}
- 默认参数 如果形参数量大于实参,那么那些没有对应实参的形参会被设置为undefined。调用函数时,若没有传入参数,默认参数可以给函数提供缺省的参数值。