闭包练习

484 阅读2分钟

1.创建具名函数表达式

var fn1=function xxcanghai(){};

注意:具名函数表达式的函数名只能在创建函数内部使用 即采用此种方法创建的函数在函数外层只能使用fn1不能使用xxcanghai的函数名。xxcanghai的命名只能在创建的函数内部使用

var fn1=function xxcanghai(){
    console.log("in:fn1<",typeof fn1,">xxcanghai:<",typeof xxcanghai,">");
};
console.log("out:fn1<",typeof fn1,">xxcanghai:<",typeof xxcanghai,">");
fn1();
//out:fn1< function >xxcanghai:< undefined >
//in:fn1< function >xxcanghai:< function >

可以看到在函数外部(out)无法使用xxcanghai的函数名,为undefined。

注意:在对象内定义函数如var o={ fn : function (){…} },也属于函数表达式 创建匿名函数表达式 var fn1=function (){}

2.所有声明的匿名函数都是一个新函数。

3.在函数表达式内部能不能访问存放当前函数的变量

3.1测试1,对象内部的函数表达式:

var o={
  fn:function (){
    console.log(fn);
  }
};
o.fn();//ERROR报错

3.2测试2,非对象内部的函数表达式:

var fn=function (){
  console.log(fn);
};
fn();//function (){console.log(fn);};正确

结论:使用var或是非对象内部的函数表达式内,可以访问到存放当前函数的变量;在对象内部的不能访问到。

4由函数作用域链求返回的函数为之前的那个函数(递归)

结论:使用var或是非对象内部的函数表达式内,可以访问到存放当前函数的变量
;在对象内部的不能访问到。

原因也非常简单,因为函数作用域链的问题,采用var的是在外部创建了一个fn变
量,函数内部当然可以在内部寻找不到fn后向上册作用域查找fn,而在创建对象
内部时,因为没有在函数作用域内创建fn,所以无法访问。

2.例题

function fun(n,o) {
  console.log(o)
  return {
    fun:function(m){
      return fun(m,n);
    }
  };
}
var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);//undefined,?,?,?
var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
var c = fun(0).fun(1);  c.fun(2);  c.fun(3);//undefined,?,?,?
//问:三行a,b,c的输出分别是什么?
//答案:
//a: undefined,0,0,0
//b: undefined,0,1,2
//c: undefined,0,1,1