JavaScript 学习笔记 -- Function
JS 中 函数、继承、闭包、作用域链。。。 一直都是硬伤,一碰到这样的问题头就大了。但是如果我继续着说:我不会,就真的无药可救了。要勇敢地说出:我的字典里就没有不会这个词,吼吼。。正好昨天在书城里看了本JS红宝书,还没有看完,先记录下:
Function-函数在JS中有两种使用方法:
(1)函数声明: 声明和调用是没有严格的先后顺序的
1 Greet(); //executed correctly. there is not the strict order between declaration and invoking 2 //a standard statement of a function 3 function Greet (name) { 4 alert("Hello, " + (name || "JS")); 5 }
(2)函数表达式: 声明和调用是有顺序要求的
1 //myFun(); //Wrong: Uncaught TypeError: Property 'myFun' of object [object Object] is not a function 2 //another statement: function expression 3 var myFun = function(name){ 4 alert("Hello, " + (name || "JS")); 5 } 6 //like a variable, need to be declared firstly 7 myFun("Tom");
其他的区分倒不记得了,稍后去度娘那儿问下。现在用函数来展示下阶乘的递归实现:
1 function factorial (num) { 2 if(num == 1) 3 return 1; 4 else 5 return num * factorial(num-1); 6 } 7 alert(factorial(5)); // 120 - OK
正常的使用。但在JS中Function也是一个对象,可以像一般变量那样使用,具体指代的是函数入口的指针,与委托类似。在不济,就是把整个函数的定义赋值给目标变量(我就是按照这种理解的)
1 //used as a variable 2 var fact = factorial; 3 alert(fact(5)); // 120 - OK
但是这是个递归的实现,递归就是不断重复地调用自身。上面的用法就是把函数的实现过程委托给一个变量来执行。但是函数体中调用自身的函数仍然指向原函数,此时如果更改了原函数,结果就大不一样:
1 factorial = function(){return 1}; 2 alert(fact(5)); //5 - effected by the original function
这就是不严谨的Bug, 递归一般用arguments.callee来替代函数自身:
1 // - correct usage 2 function factorial (num) { 3 if(num == 1) 4 return 1; 5 else 6 return num * arguments.callee(num-1); 7 }
还有另外一种用法:
1 // mark 2 var myFactorial = (function f (num) { 3 if(num == 1) 4 return 1; 5 else 6 return num * f(num-1); 7 }); 8 alert(myFactorial(5)); // 120
这种语法真没见过,Mark。。。