// javascript 学习笔记 函数表达式
// 声明函数的两种方式:1、函数声明 2、函数表达式
// 1、函数声明
function functionName(arg0, arg1, arg2) {
//函数体 fireFox Safari, Chrome, Opera都给函数定义了一个非标准的name属性,用于访问函数名,这个值永远在function关键字后面
alert(functionName.name)
}
/* 关于函数声明,有一个重要的特征,就是函数声明提升(function declaration hoisting)
在执行代码之前会先读取函数声明,这样,也就意味着可以把函数声明放在调用它的后面
*/
// 例如
sayHi();
function sayHi(){
alert("Hi!")
}
//2、 函数表达式(创建一个匿名函数[拉姆达函数],并把它赋值给 functionName)
var functionName = function(arg0, arg1, arg2) {
// 函数体
}
// 如果 用函数表达式创建一个函数, 函数表达式和其他表达式一样,使用之前必须给他赋值,否则会报错。这点一定要和函数声明创建函数区分开来
// 永远不要这样做,
if(conditoin){
function sayHi(){
alert("Hi!");
}
}else{
function sayHi(){
alert("Yo!");
}
}
// 因为在ECMAScript中这属于无效语法。JavaScript引擎会尝试修正错误,但是浏览器修正错误的方式不一样。大多数浏览器会返回第二个声明,忽略condition;FireFox会在condtion为true时返回第一个声明。
// 正确的做法
var sayHi;
if(conditoin){
sayHi = function(){
alert("Hi!");
};
}else{
sayHi = function() {
alert("Yo!");
};
}
// 递归的一些陷阱
// 递归是在一个函数通过名字调用自身的情况下构成的
function factorial(num){
if(num <= 1){
return 1;
}else{
return num * factorial(num - 1)
}
}
// 我们如果通过一个变量引用 factorial函数,这个变量就会指向factorial函数,不小心把factorial 置为null时,就会出现错误
var anotherFactorial = factorial;
factorial = null;
alert(anotherFactorial(4));//报错
// 这个问题通过arguments.callee可以解决,仅在非严格模式下有效
function factorial(num){
if(num <= 1){
return 1;
} else {
return num * arguments.callee(num - 1)
}
}
// 原因,通过使用 arguments.callee代替函数名,可以确保无论怎样调用函数,都不会出问题。
// 然而,严格模式下还会报错,有一个两全的方法,这时候就用到命名函数表达式达到相同的结果
var factorial = (function f(num){
if(num <= 1){
} else {
return num * f(num - 1)
}
});
// 闭包
// 以比较条件函数为例
function createComparisonFunction(propertyName) {
return function(object1, object2){
var value1 = object1[propertyName];
var value2 = object2[propertyName];
if (value1 < value2) {
return -1;
}else if (value1 > value2) {
return 1;
}else{
return 0;
}
};
}
// 内部的匿名函数,内部访问到了 外部函数createComparisonFunction 的参数propertyName
// 即使外部