函数是对象,函数名是指针:函数名仅仅是指向函数的指针,同包含对象指针的其他变量没区别,也就是说,一个函数可能会有多个名字,在下面的代码中,先定义了一个名为sum()的函数,用于求两个数的和,在将sum的值赋给一个新的变量anoanotherSum(使用不带圆括号的函数名是访问函数指针,而非调用函数),此时,anotherSum和sum都指向同一个函数,因此anotherSum()也可以被调用并返回结果,即使将sum设置为null,仍然可以正常调用anotherSum()。
function sum(num1,num2){
return num1 + num2;
}
console.log(sum(10,10)); //20
var anotherSum = sum;
console.log(anotherSum(10,10)); //20
sum = null;
console.log(anotherSum(10,10)); //20
函数没有重载
function a1(num){
return num + 100;
}
function a1(num){
return num + 200;
}
console.log(a1(100)); //300
var a2 = function(num){
return num + 100;
}
a2 = function(num){
return num + 200;
}
console.log(a2(100)); //300
函数声明提升
创建函数可以使用函数声明和函数表达式两种方式,这两种方式在解析加载的数据的时候,效果是不一样的,因为存在变量提升和函数提升。
console.log(b1); //ƒ b1(){return b1;}
console.log(b2); //undefined
function b1(){
return b1;
}
var b2 = function(){
return b2;
};
相当于
var b1= 'function';
var b2;
console.log(b1);
console.log(b2);
对于第一个函数,在代码开始执行前,解析器就已经通过函数声明提升的过程读取并将函数声明添加到执行环境中,在对代码求值的时候,JavaScript引擎在第一遍会声明函数并置顶,所以,即使声明函数的代码在调用它的代码后面,也会因为提升而不会报错。而在第二个函数中,函数位于一个初始化语句中,在执行到函数所在语句前,变量b2中不会保存对函数的引用,因此打印出undefined,如果是下面的情况,则会直接报错。
console.log(b3(20)); //Uncaught TypeError: b3 is not a function
var b3 = function(num){
return num + 10;
};
函数提升和变量提升的优先级
console.log(c); //ƒ c(){console.log(10);}
console.log(c()); //10
var c = 3;
function c(){
console.log(10);
}
console.log(c); //undefined
c = 6;
console.log(c()); //c is not a function
因为函数提升比变量提升的优先级高,且不会被变量声明覆盖,但是会被变量赋值之后覆盖,因此上面的代码等同于下面
var d = function(){
console.log(10);
};
var d;
console.log(d); //ƒ c(){console.log(10);}
console.log(d()); //10
d = 3;
console.log(d); //undefined
d = 6;
console.log(d()); //d is not a function