函数的声明
1.函数的声明
(1) function
命令
function print(s) {
console.log(`1`);
}
(2) 函数表达式
采用函数表达式声明函数时,function
命令后面部带有函数名。如果加上函数名,该函数名只在函数体内部有效,在函数体外部无效。
var print = function x(s) {
console.log(typeof x);
}
x //ReferenceError: x is not defined
print() //function
当同时采用function
命令和赋值语句声明同一个函数时,最后总是采用赋值语句的定义。
function f() {
console.log('1');
}
var f = function() {
console.log('2');
}
f() //2
(3) Function 构造函数
Function 构造函数接受任意数量的参数,只有最后一个参数会被当做函数体,如果只有一个参数,该参数就是函数体。new
命令可以省略。
var add = new Function(
'x',
'y',
'return x + y'
)
//等同于
var add = function(x, y) {
return x + y;
}
2.函数名的提升
JavaScript 引擎将函数名视同变量名,所以采用function
命令声明函数时,整个函数会像变量声明一样,被提升到代码头部。
f() //2
function f() {
console.log('1');
}
function f() {
console.log('2');
}
//函数被多次声明,后声明的函数会覆盖之前的同名函数。
但是使用函数表达式定义函数会报错:
f();//TypeError: undefined is not a function
var f = function f() {
console.log('1');
}
上述代码等同于下面的形式:
var f;
f();//TypeError: undefined is not a function
f = function() {
console.log('1');
}
调用函数f
的时候,函数f
只是被声明了,还没有被赋值,等于undefined
,所以会报错。
3.递归
函数内部调用自身,这就是递归(recursion)。下面通过递归,计算斐波那契数列的第6个元素,得出8。
function fib(num) {
if(num === 0) return 0;
if(num === 1) return 1;
return fib(num - 2) + fib(num - 1);
}
fib(6) //8
4.第一等公民
凡是可以使用值的地方,就能使用函数,函数在JavaScript中也被称为第一等公民。
function add(x, y) {
return x + y;
}
function a(op) {
return op;
}
a(add)(1, 2); //3
函数的属性和方法
1. name 属性
函数的name
属性返回函数的名字。
function f1() {}
f1.name // "f1"
var a = function() {};
a.name // "a"
var a = function f2() {};
a.name // "f2"
2. length 属性
函数的length
属性返回函数预期传入的参数个数,即函数定义之中的参数个数。
function f(a, b) {}
f.length //2
length
属性提供了一种机制,判断定义时和调用时参数的差异,以便实现面向对象变成的“方法重载”(overload)。
3. toString()
函数的toString()
方法返回一个字符串,内容是函数的源码。
function add(x, y) {
return x + y;
}
add.toString()
//function add(x, y) {
// return x + y;
//}
对于那些原生的函数,toString()
方法返回function(){[native code]}
。
Math.sqrt.toString()
//function sqrt() { [native code] }