[关闭]
@cpt 2015-04-20T03:25:08.000000Z 字数 2029 阅读 925

函数表达式

读书笔记


函数定义

  1. //以函数声明定义,不会抛出错误
  2. sayHi();
  3. function sayHi(){
  4. alert('Hi');
  5. }
  6. //以函数表达式定义,出错
  7. sayHi();
  8. var sayHi = function(){
  9. alert('Hi');
  10. }
  11. /*再来看一个例子
  12. *理解两者区别
  13. */
  14. //以下代码表面上看会在condition为true时返回一个sayHi函数的定义;否则就使用另外一个定义。但是,这是无效语法,JS引擎会尝试修正错误。各浏览器对修正错误的办法不一致。
  15. if(condition){
  16. function sayHi(){
  17. alert('Hi');
  18. }
  19. }else{
  20. function sayHi(){
  21. alert('yoooo');
  22. }
  23. }
  24. //可以这样使用
  25. var sayHi();
  26. if(condition){
  27. sayHi = function(){
  28. alert('Hi');
  29. }
  30. }else{
  31. sayHi = function(){
  32. alert('yooo');
  33. }
  34. }

函数递归

  1. function factorial(){
  2. if(num<=1){
  3. return 1;
  4. }else{
  5. return num*factorial(num-1);
  6. }
  7. }
  8. //但是以下代码会让它出错,因为在JS中,函数名只是一个包含指向某个函数的指针的变量。当被设置为空时,指向原是函数的引用只有anotherFactorial,接下来调用anotherFactorial()时,由于必须执行factorial(),而factorial已经不再是函数,导致错误。即使用arguments.callee替换掉else中的factorial,在严格模式下仍会出错。(arguments.callee是一个指向正在执行函数的指针)
  9. var anotherFactorial = factorial;
  10. factorial = null;
  11. alert(anotherFactorial(4));
  12. //正确用法是使用命名函数表达式
  13. var factorial = (function f(num){
  14. if( num <= 1){
  15. return 1;
  16. }else{
  17. return num * f(num-1);
  18. }
  19. });
  20. //创建一个名为f()的命名函数表达式,然后将他它赋值给变量factorial,这样即便把函数赋值给另外一个变量,函数名字f仍然有效,递归仍能正确完成。

函数闭包

关于JS闭包的问题,下周另外做一个专门的笔记。

this对象

  1. var name = "The window";
  2. var object = {
  3. name : "My Object",
  4. getNameFunc : function(){
  5. return function(){
  6. return this.name;
  7. };
  8. }
  9. };
  10. alert(object.getNameFun()());//"The window"非严格模式下

getNameFunc返回一个函数,所以调用object.getNameFunc()()就会立即调用它返回的匿名函数,结果就是返回一个字符串。在这里返回"The window".为什么匿名函数没有其包含作用域即外部作用域中的this对象呢?
因为每个函数在调用的时候都会取得两个特殊变量:this和arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止(这里为window,因为i额匿名函数的执行对象为window),因此永远不可能直接访问外部函数中的这两个变量。不过,把外部作用域中的this对象保存到一个闭包能够访问的变量里,就可以让闭包访问该对象了。

  1. var name = "The window";
  2. var object = {
  3. name : "My Object",
  4. getNameFunc : function(){
  5. var that = this; //that===object
  6. return function(){
  7. return that.name;
  8. };
  9. }
  10. };
  11. alert(object.getNameFun()());
  12. //arguments也存在同样的问题,如果想要访问作用域中的arguments对象,必须将该对象的引用保存在另一个闭包能够访问的变量中

小结

在JavaScript中,函数表达式是一种非常有用的技术。使用函数表达式无需对函数命名,从而实现动态编程。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注