首先,一个小小的题目:将10以内的数字进行输出。相信大家看到这个题目一定会感到非常熟悉,这不就是一层简单的for循环吗? 不就是这样一段demo:

function test1(){var count = 0;for(var i =0; i < 10;i++){document.write(i+" ");}}test1();

运行结果就是:0 1 2 3 4 5 6 7 8 9

相信上面的题目只要学过编程的人都会轻松的写出来。那么题目要求改变一下:要求输出一个数组内的10个函数的索引值。函数索引值?直接把数组角标输出不就行了,比上面多两行代码而已,代码如下:

function test(){var arr = [];for(var i = 0;i < 10;i ++){arr[i] = function(){document.write(i + " ");}}return arr;}var myArr = test();for(var j = 0;j < 10;j++){myArr[j]();     }

从上面的代码可以看见:使用for循环给数组内储存十个函数,并调用函数再次使用for循环输出。看起来简直天衣无缝。但是....运行结果却是这样的:

当我看到这个运行结果我也很纳闷。首先,输出10个数。这是毋庸置疑的。但是10个数一样就很怪异了,更让人费解的是为什么输出了10,输出10个9我能理解(第一段demo输出0-9)。

闭包

闭包包含自由(未绑定到特定对象)变量,这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)。

 function a(){function b(){          //内部函数var bbb = 234;console.log(aaa); }var aaa = 123;}var glob = 100;var demo = a();demo();

从上面的demo可以看到,先进行定义a函数,a函数内部有一b函数,b函数用控制台进行aaa的输出。最后用demo将a进行调用,程序结束。   相信有一半的人会认为是这样,运行结果是:

不但没有结果,还出现了报错。请再把闭包的概念看一遍:变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。作用域不同,其实就是局部变量不能在全局使用。只需一行即可完成demo。

 function a(){function b(){          //内部函数var bbb = 234;console.log(aaa); }var aaa = 123;return b;            //return  返回外部(保存在外部)  闭包}var glob = 100;var demo = a();demo();

运行结果:

现在我们返回第二个题目,输出函数索引。可能有人会想直接加一个return arr,把数组返回到外部就OK了,但是仔细看demo,已经存在返回的数组arr。

为什么会是10?

当i加到9的时候,9<10,再进行i++;

为什么会有10个10?

函数在外部for循环进行调用,那么已经在函数内部进行了预编译,此时的i值已经全部变成了10,外部再一个一个的进行调用,所以输出了10个10。

如何改正demo使其正确?

引入概念:立即执行函数(IIFE

Javascript和其他编程语言相比比较随意,所以Javascript代码中充满各种奇葩的写法,有时雾里看花,当然,能理解各型各色的写法也是对javascript语言特性更进一步的深入理解。其中( function(){…} )()( function (){…} () )是两种javascript立即执行函数的常见写法。

首先得知道这三个名词:函数声明,函数表达式,匿名函数。

函数声明: function fnName() {...} ;
使用 function 关键字声明一个函数,再执行一个函数名,叫函数声明。

函数表达式: var fnName = function() { ... } ;
使用 function 关键字声明一个函数,但未给函数命名,最后将匿名函数赋予一个变量,叫函数表达式,这是最常见的函数表达式语法形式。

匿名函数: function() { ... } ;
使用 function 关键字声明一个函数,但未给函数命名,所以叫匿名函数,匿名函数属于函数表达式,匿名函数有很多作用,赋予一个变量则创建函数,赋予一个事件则成为事件处理程序或创建闭包等等。

以下是我今天听课所学习到的关于立即执行函数的知识:

//立即执行函数//针对初始化功能的函数  执行完就被释放(function (){var a = 123;var b = 234;console.log(a+b);}())var num = (function(a,b){var c = a+b*4;return c;}(234,564));console.log(num);//(function(){}());            //建议第一种//(function(){})();//只有表达式才能被执行符号执行function test(){var a = 213;}test();var test = function(){console.log('a');}//能被执行符号执行的表达式变成立即执行函数var test = function(){console.log('a');}();+ function test(){       //+ - ! (*和/不行   + - 是正负不是加减)console.log('a');}();var num = function test(a , b , c , d){console.log(a+b+c+d);}(1 , 2 , 3 , 4);

通过闭包和立即执行函数,这是我们就可以改正我们之前的demo了。

function test(){var arr = [];for(var i = 0;i < 10;i ++){(function (j){arr[j] = function(){console.log(j + " ");}}(i));}return arr;} var myArr = test();for(var j = 0;j < 10;j++){myArr[j]();       }

运行结果:

以上若有不足之处,还请指出。

Mr.J--JS学习(闭包及IIFE)相关推荐

  1. 你不懂的JS学习笔记(作用域和闭包)

    You don't KnowJS 引语:你不懂的JS这本书github上已经有了7w的star最近也是张野大大给我推荐了一波,阅读过之后感觉对js的基础又有了更好的理解.本来我是从来不这种读书笔记的, ...

  2. js学习笔记(执行上下文、闭包、this部分)

    1.函数的准备工作 函数在执行会进行一些准备工作,如创建一个"执行上下文"环境:执行上下文可以理解为当前代码的执行环境,它会形成一个作用域: 每个碰到可执行代码的时候都会进行这些& ...

  3. sizzle.js学习笔记利用闭包模拟实现数据结构:字典(Map)

    sizzle.js学习笔记利用闭包模拟实现数据结构:字典(Map) 这几天学习和查看了jQuery和Property这两个很流行的前端库的御用选择器组件Sizzle.js的源代码,收获还是相对多的!之 ...

  4. 用闭包实现重载的过程学习闭包

    用闭包实现重载的过程学习闭包 let global = {overLoad:function(){} }; function Refactoring(func) {let oldFunc = glob ...

  5. 利用js的闭包原理做对象封装及调用方法

    创建一个js文件,名为testClosure.js: ? 1 2 3 4 5 6 7 8 9 (function () {   function a()   {     alert('i am a') ...

  6. javascript从入门到跑路-----小文的js学习笔记目录

    ** javascript从入门到跑路-----小文的js学习笔记(1)---------script.alert.document.write() 和 console.log 标签 javascri ...

  7. JS学习笔记(九)深拷贝浅拷贝【Array、Object为例】

    JS学习笔记(九) 本系列更多文章,可以查看专栏 JS学习笔记 文章目录 JS学习笔记(九) 一.赋值&复制 二.浅拷贝(shallow copy) 1. 什么是浅拷贝 2. 数组的浅拷贝 ( ...

  8. Jquery真的不难~第八回 JS的闭包问题

    百度百科中对闭包的定义: 闭包是可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义."闭包" 一词来源 ...

  9. ArcGIS JS 学习笔记4 实现地图联动

    原文:ArcGIS JS 学习笔记4 实现地图联动 1.开篇 守望屁股实在太好玩了,所以最近有点懒,这次就先写个简单的来凑一下数.这次我的模仿目标是天地图的地图联动. 天地的地图联动不仅地图有联动,而 ...

  10. backbone.js学习笔记

    backbone.js学习笔记 之前只接触过jQuery,看来Backbone是除了jQuery的第二大JS框架... backbone到底是个啥? 其实刚开始我也不知道=_=,我是这周二才听说居然还 ...

最新文章

  1. 后端如何发出请求_gRPC系列(三) 如何借助HTTP2实现传输
  2. 软件中常用的“发送邮件”、“打印文档”,其本质是“队列”!
  3. 极大似然估计的朴素理解
  4. 四十五、深入Java的网络编程(上篇)
  5. yum安装mysql和mysql源,配置mysql(亲测)
  6. 皇室战争:暗夜女巫重做,去掉亡语机制后,她凉的可能会更快
  7. STL源码剖析---deque
  8. 上交所行情文件导入数据库
  9. php根据浏览器调用支付_Android通过外部浏览器调用微信H5支付,Android+PHP详解
  10. php海外研发,国外主流PHP框架比较
  11. activeperl安装不成功_手把手教你:Windows系统上安装GPU深度学习环境
  12. 正则表达式 查找以某些字符开始 某些字符结束的匹配项 解决之道
  13. 【比赛】新冠肺炎疫情趋势预测大赛~推荐大家参加下
  14. 网页截图插件FireShot
  15. Mosquitto修改默认端口port
  16. JS网页特效实例:让网页前进和后退
  17. 计算机网络atm功能,现代计算机网络原理4ATM交换技术.ppt
  18. 定义一个方法,使用随机的字母+数字生成一个6位数的密码
  19. Jmeter实现多用户压测
  20. No mapping found for HTTP request with URI问题解决

热门文章

  1. CV Code | 本周计算机视觉新出开源代码汇总(含目标检测、深度估计、视频识别、网络加速算法等)...
  2. 超强!MDETR:基于Transformer的端到端目标检测神器!开源!
  3. 教程|YOLOX目标检测ncnn实现
  4. 经验 | 上交机械本硕转计算机视觉岗位面经
  5. 深度学习 | Why and How:神经网络中的权重初始化
  6. c语言判断回文字符串递归,用递归实现判断一个字符串是否为回文串
  7. 重复类发展手法_正确的护肤手法(动态演示),喜欢就拿去收藏吧!
  8. 计算机适配器有什么作用,例举适配器是什么
  9. java oop入门_java入门(十六) | OOP(三)之构造方法
  10. 32f4 usb 升级程序_不断中招的你还放心升级win10吗?wi10近期更新问题及解决办法...