关于闭包知识的整理

2021-11-25  本文已影响0人  即将有人鱼线的李先森


一、创建函数的几种方式

1、声明函数

最普通最标准的声明函数方法,包括函数名及函数体。

function  fn1(){}

2、创建匿名函数表达式

创建一个变量,这个变量的内容为一个函数

var fn1 = function(){}

注意采用这种方法创建的函数为匿名函数,即没有函数name

var fn1 = function (){};

3、创建具名函数表达式

创建一个变量,内容为一个带有名称的函数

var fn1 = function frankName(){};

注意:具名函数表达式的函数名只能在创建函数内部使用

即采用此种方法创建的函数在函数外层只能使用fn1不能使用frankName的函数名。frankName的命名只能在创建的函数内部使用测试:

varfn1=function frankName(){

    console.log("in:fn1<",typeoffn1,">frankName:<",typeof frankName,">");

};

console.log("out:fn1<",typeoffn1,">frankName:<",typeof  frankName,">");

fn1();

//out:fn1< function >frankName:<undefined>//in:fn1< function >frankName:< function >

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

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

4、Function构造函数

可以给Function构造函数传一个函数字符串,返回包含这个字符串命令的函数,此种方法创建的是匿名函数

5、自执行函数

(function(){alert(1);})();

(functionfn1(){alert(1);})();

自执行函数属于上述的“函数表达式”,规则相同

6、其他创建函数的方法

当然还有其他创建函数或执行函数的方法,这里不再多说,比如采用eval,setTimeout,setInterval等非常用方法,这里不做过多介绍,属于非标准方法,这里不做过多展开

二、函数作用域链的问题

问题:在函数表达式内部能不能访问存放当前函数的变量?

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

var o = {

 fn:function(){    

console.log(fn);  

}

};

o.fn();//ERROR报错

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

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

fn();

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

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

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

三、简单的几个代码片段

代码片段一:

var name = "The Window";

var object = {

name : "My Object",

getNameFunc : function(){

return function(){

return this.name;

};

 }

};

alert(object.getNameFunc()());

// The Window

代码片段二:

var name = "The Window";

var object = {

    name : "My Object",

    getNameFunc : function(){

    var that = this;

        return function(){

        return that.name;

        };

    }

};

alert(object.getNameFunc()());

//My Object

ps:匿名函数的执行环境是window

代码片段三:

代码片段四:


四、闭包的注意事项

 由于闭包会常驻内存,使用不当会导致内存溢出。

上一篇 下一篇

猜你喜欢

热点阅读