// 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// 即使外部