一个函数定义由一系列的 function
关键字组成,依次为:
{}
括起来(函数体)函数声明语句的组成要素:
function
关键字functionName
函数名arg
参数(可选)functionBody
函数体function functionName ([arg1 [,arg2 [...,argn]]]) {// functionBody 函数体}
函数声明要素 | 含义 | 说明 |
---|---|---|
function | 声明关键字 | 声明的函数名称的标识符 |
functionName | 函数名称 | 当前作用域内函数名称唯一 |
arg | 参数列表 | 函数名之后的圆括号中是参数列表,参数之间使用逗号分隔。当调用函数时,这些标识符则指代传入函数的实参。 |
functionBody | 函数体 | 所有语句的集合,包括花括号在内 |
Array
或用户自定义的其他对象),若函数改变了这个对象的的属性,这样的改变对函数外部是可见的function fn(arg1) {arg1.name = 'JavaScript';}let foo = { name: 'Java', year: 1998 };fn(foo);console.log(foo.name);// 'JavaScript'
function
语句里的 花括号是必需 的,这和 while
循环和其他一些语句所使用的语句块是不同的,即使函数体内只包含一条语句,仍然必须使用花括号将其括起来。function test();// SyntaxError: Unexpected end of inputfunction test(){};// 不报错while(true);// 不报错
⚠️ 注意:由于函数声明提升优先于函数表达式的变量声明提升,所以变量的声明无作用。
var foo;function foo() {console.log(1);}foo();// 1
后面的函数声明会覆盖前面的函数声明
baz();// 2function baz() {console.log(1);}function baz() {console.log(2);}
function foo() {console.log(1);}delete foo;// falseconsole.log(foo());// 1
函数表达式要素:
var/let/const
关键字variableName
变量名functionName
函数名(可选,没有的话叫做匿名函数)functionBody
函数体通常而言,以表达式方式定义函数时都不需要名称,这会让定义它们的代码更加紧凑。函数定义表达式特别适合用来定义那些只会使用一次的函数。
const variableName = function functionName(arg) {// 函数体functionBody;};
函数表达式要素与函数声明语句基本一致
匿名函数(anonymous function) 也叫拉姆达函数,是 function
关键字后面没有标识符的函数。
const square = function (number) {return number * number;};
函数表达式也可以提供函数名,并且可以用于在函数内部使用来代指其本身,或者在调试器堆栈跟踪中鉴别该函数。
const factorial = function fac(n) {return n < 2 ? 1 : n * fac(n - 1);};console.log(factorial(3));var x = square(4);// x 得到的值为16
一个函数定义表达式包含名称,函数的局部作用域将会包含一个绑定到函数对象的名称。实际上,函数的名称将成为函数内部的一个局部变量。
const foo = function fn() {return fn;};console.log(foo);// fn(){// return fn// }console.log(foo());// fn(){// return fn// }console.log(foo()());// fn(){// return fn// }
个人理解:
const foo = function fn() {return fn === foo;};console.log(foo());// trueconsole.log(foo === fn);// ReferenceError: fn is not defined
函数定义了一个非标准的 name
属性,通过这个属性可以访问到给定函数指定的名字,这个属性的值永远等于跟在 function
关键字后面的标识符,匿名函数的 name
属性为空
// IE11- 浏览器无效,均输出 undefined// Chrome在处理匿名函数的 name 属性时有问题,会显示函数表达式的名字function fn() {}console.log(fn.name);// 'fn'var fn = function () {};console.log(fn.name);// '',在chrome浏览器中会显示'fn'var fn = function abc() {};console.log(fn.name);// 'abc'
虽然都可以定义函数,但最大的区别在于:
foo();// 能正常运行 弹出 foobar();// 报错 Uncaught TypeError: baz is a function(...)function foo() {alert('foo');}var baz = function bar() {alert('bar');};