函数表达式
function (someArgs) { someStatements }
function name(someArgs) { someStatements }
(someArgs) => { someStatements }
- 函数表达式就是要,在一个表达式中定义一个函数;
- 箭头函数也是一个简洁的函数表达式;
- 执行完函数表达式,才能开始调用:
- 一般是立刻调用、用作回调等;
- 可以赋值给其他变量,使得后续可以继续使用,不能变量提升(先调用后声明)。
- 根据语法解构,函数表达式可以分为两类:
- 箭头函数表达式;
- 由关键字
function
引导的函数表达式。
g(); // 报错,函数还没有声明
f(); // 报错,函数还没有声明
let f = function g() { console.log('Hi'); } // =后边的是一个具名函数表达式
f(); // 'Hi'
g(); // 报错,具名函数表达式的名字只能在函数体内部调用
具名函数表达式
具名函数表达式在语法上,多一个名字:
- 创建的函数
name
属性就是该名字,不会因为因为赋值而改变;
let g = function f(n) { }
let h = gg.name // 'f'
h.name // 'f'(function(){}).name // '',空字符串,没有名字
let k = function () {}
k.name // 'k'
- 具名函数表达式的名字只能在函数体内部调用,递归的场景可以使用;
let factorial = function fac (n) {if (n <= 1) return 1;else return n * fac(n - 1); // 不要使用 factorial(n - 1)
}factorial(4) // 24
fac(4) // 报错
- 注意:不要在函数表达式的函数体内,使用其赋值的变量,这样容易出错。
let factorial = function fac (n) {if (n <= 1) return 1;else return n * factorial(n - 1);
}factorial(4) // 24let f = factorial;
factorial = 1;
f(4) // 报错
箭头函数表达式
箭头函数表达式的语法更加简洁,含义上有一些差异,用法上也有一些限制:
- 箭头函数没有独立的
this
; - 没有
arguments
对象; - 不能用作构造函数(使用
new
调用会 报错,无法访问new.target
关键字); - 函数体内不能使用
yield
,不能用以创建生成器。
基本语法
- 只有一个参数时,
()
可以省略; - 函数体只有单个语句,
{}
可以省略,返回值就是该语句/表达式的值。 - 函数体有多个语句,必须使用
{}
包围。
/* 函数体只有一个语句 */
() => 单个语句
单个参数 => 单个语句
(单个参数) => 单个语句
(参数1, 参数2) => 单个语句
let f = ()=>console.log(111)
f() === undefined // true/* 函数体有多个语句,使用{} */
() => { 多个语句 }
单个参数 => { 多个语句 }
(单个参数) => { 多个语句 }
(参数1, 参数2) => { 多个语句 }
let g = ()=>{}
注意事项
- 语法上,一个对象作为表达式返回时,加
()
;
let f = ()=>{ a:1 } // 不报错,a被当成一个标签,执行了表达式 “1”,返回 undefined
let f = ()=>{ a: 1, b: 2 } // 报错
let f = ()=>{ a: 1; b: 2 } // 不报错,a,b都时标签
let f = ()=>( {a:1, b:2} ) // 不报错,()改变了优先级
- 注意
this
的指向。更多因此导致的注意事项,见此