首页 前端知识 js中匿名函数和闭包的关系

js中匿名函数和闭包的关系

2023-05-14 16:05:32 前端知识 前端哥 52 600 我要收藏

前端哥今天分享的是关于js中的闭包和匿名函数两者之间的关系,从匿名函数概念到立即执行函数,最后到闭包。下面一起来看看文章分析,希望你会喜欢

本文讲的是关于js中的闭包和匿名函数两者之间的关系,从匿名函数概念到立即执行函数,最后到闭包。下面一起来看看文章分析,希望你会喜欢。 前面讲了一篇在for循环中加setTimeout输出内容,我们用到了一个闭包,但同时也可以说是匿名函数,到底匿名函数和闭包有没有关系呢?【答案是它们之间没有关系】

匿名函数

匿名函数,顾名思义,就是没有名字的函数,与之对应的就是有名字的函数,也叫具名函数。

//匿名函数function (){    console.log('匿名函数');}//具名函数function myFn(){    console.log('具名函数');}//变量a就是匿名函数的名字var a = function(){    console.log('a就是匿名函数的名字');}

如果我们直接在控制台中运行匿名函数,会发现报错,无法执行。匿名函数是无法执行的,一般用到匿名函数的时候都是立即执行,也叫自执行匿名函数或者自调用匿名函数,一般人都叫立即执行函数。

立即执行函数

比较常见的立即执行函数如下:

;(function(){    console.log('caibaojian.com');})();(function(){    console.log('caibaojian.com');}());

上面这两种都是典型的立即执行函数写法,两者的区分就是一个执行在匿名函数括号外面,另外一个发起执行的括号在匿名函数里面。比较常见的是第一种写法,括号在匿名函数的括号外面。

  1. 首先声明一个匿名函数 function(){alert('我是匿名函数')}。
  2. 然后在匿名函数后面接一对括号 (),调用这个匿名函数。那为什么还要用一个括号包起来呢?其实是为了兼容JS的语法,如果我们不加括号,直接写成
function (){alert('我是匿名函数')}()

浏览器会报语法错误,想要通过浏览器的语法检查,必须加点小东西,比如下面几种,更多请看:深入js立即调用的函数表达式

(function(){alert('我是匿名函数')} ()) // 用括号把整个表达式包起来(function(){alert('我是匿名函数')}) () //用括号把函数包起来!function(){alert('我是匿名函数')}() // 求反,我们不在意值是多少,只想通过语法检查。 function(){alert('我是匿名函数')}()-function(){alert('我是匿名函数')}()~function(){alert('我是匿名函数')}()void function(){alert('我是匿名函数')}()new function(){alert('我是匿名函数')}()

实际上,立即执行函数的作用只有一个:创建一个独立的作用域,在这个作用域里面,外面访问不到,避免变量污染。比如我们前面的一篇文章,setTimeout的第三个参数里面讲到的一道题目。

for(var i=0;i<6;i  ){    setTimeout(function(){        console.log(i); //为什么输出的总是 6,而不是0,1,2,3,4,5    },i*1000);}

我们发现上面这个定时器总是输出6,因为setTimeout里面的执行函数是异步的,执行的时候,i的值是贯穿整个作用域的,而不是单独一个给每个定期器分配了一个i,for运行完的值是6,此时输出就总是6了。 那怎么解决呢?用立即执行函数给每个定时器创造一个独立作用域即可。

for(var i=0;i<6;i  ){    (function(j){        setTimeout(function(){            console.log(j);        },j*1000);    })(i);  }

在for循环执行时,立即执行函数就已经有了结果了。而每个立即执行函数里面的j值就是独立的一个,不会受后面影响。所以会分别执行5次定时器。

//第一个立即执行函数(function(0){    setTimeout(function(){        console.log(0);    })})(0);//第二个立即执行函数(function(1){    setTimeout(function(){        console.log(1);    })})(1);//……//第六个立即执行函数(function(5){    setTimeout(function(){        console.log(5);    })})(5);

i 的值从 0 变化到 5,对应 6 个立即执行函数,这 6 个立即执行函数里面的 j 「分别」是 0、1、2、3、4、5。 上面说了这么多关于匿名函数和立即执行函数的,相信你对这两个概念已经很清楚,那么闭包跟匿名函数有关系吗?

闭包

js闭包是指有权访问另一个函数作用域中的变量的函数,个人认为js闭包最大的用处就是防止对全局作用域的污染。闭包最神奇的地方就是能在一个函数外访问函数中的局部变量,把这些变量用闭包的形式放在函数中便能避免污染。更多介绍:浅谈JavaScript中的闭包 我们可以分离出上面的第一个立即执行函数

function box(i){    setTimeout(function(){        console.log(i);    },i*1000);}box(1);//或者这样function box(i){    function inner(){        console.log(i);    }    return inner;}var outer = box(1);outer();

很明显这是一个闭包,然后我们再看看我们最前面的匿名函数代码和立即执行函数代码,可以看出匿名函数和闭包两者并没有关系。闭包既可以在匿名函数也可以在具名函数中使用。 这个for循环中的闭包怎么理解以及自执行匿名函数的作用: 这个for循环产生的闭包其实是定时器的回调函数,这些回调函数的执行环境是window,类似刚才例子中的引用inner的全局outer的执行环境,匿名函数则相当于刚才例子中的box函数。 Stackoverflow网站上的一个提问跟我们今天分析的类似。有一个回答挺好。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/58.html
评论
发布的文章

jQuery AJAX请求的统一封装

2024-02-01 12:02:53

jQuery知识学习

2024-02-01 12:02:53

JQuery——动画效果

2024-02-01 12:02:52

jQuery复习

2024-02-01 12:02:51

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!