闭包的概念

闭包就是能读取其他函数内部变量的函数。

也可以简单的理解为:“定义在一个函数内部的函数”

闭包的形式

    //在执行fn1时,其返回值是一个函数,即fn2,所以再一次执行的时候就是返回的a+b的值。function fn1(){var a = 5;return function fn2(b){return a + b}}var result = fn1();alert(result(2)); //7

ES6中的闭包(经典闭包面试题)

    //闭包常见的面试题
for (var i = 1; i <= 5; i++) {setTimeout( function timer() {console.log(i);}, 1000 );
}   //连续5个6for (var i = 1; i <= 5; i++) {(function(i){setTimeout( function timer() {console.log(i);}, 1000 );})(i);
}    //1,2,3,4,5for (let i = 1; i <= 5; i++) {setTimeout( function timer() {console.log(i);}, 1000 );
}    //1,2,3,4,5

闭包的优缺点

优点:

  1. 保护函数内的变量安全,加强了封装性
  2. 在内存中维持一个变量(用的太多就变成了缺点,占内存)

缺点:

  1. 闭包有一个非常严重的问题,那就是内存浪费问题,这个内存浪费不仅仅因为它常驻内存,更重要的是,对闭包的使用不当会造成无效内存的产生

闭包的作用

看了闭包与ES6块级作用域的比较之后,我们会不会觉得既然有了块级作用域就没有闭包存在的必要性了呢?答案是否定的,闭包的作用远不止于此。

单例模式(封装变量,收敛权限)
  1. 什么是单例模式?

用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象
2. 写一个单例模式?

    //单例模式的实现var CreateDiv = function (html) {this.html = html;this.init();};CreateDiv.prototype.init = function () {var div = document.createElement('div');div.innerHTML = this.html;document.body.appendChild(div);};var ProxySingletonCreateDiv = (function () {var instance;return function (html) {if (!instance) {instance = new CreateDiv(html);}return instance;}})();var a = new ProxySingletonCreateDiv('sven1');var b = new ProxySingletonCreateDiv('sven2');alert(a === b); //true
  1. 核心?

     //单例模式抽象,分离创建对象的函数和判断对象是否已经创建var getSingle = function (fn) {var result;return function () {return result || ( result = fn.apply(this, arguments) );}};
    
函数柯里化
  1. 什么是函数柯里化?
    柯里化是指这样一个函数(假设叫做createCurry),他接收函数A作为参数,运行后能够返回一个新的函数。并且这个新的函数能够处理函数A的剩余参数。
  2. 与闭包的关系?

在前端面试中,你可能会遇到这样一个涉及到柯里化的题目。

    // 实现一个add方法,使计算结果能够满足如下预期:add(1)(2)(3) = 6;add(1, 2, 3)(4) = 10;add(1)(2)(3)(4)(5) = 15;

要补充的知识点是函数的隐式转换。当我们直接将函数参与其他的计算时,函数会默认调用toString方法,直接将函数体转换为字符串参与计算。

    function fn() { return 20 }console.log(fn + 10);     // 输出结果 function fn() { return 20 }10

但是我们可以重写函数的toString方法,让函数参与计算时,输出我们想要的结果。

    function fn() { return 20; }fn.toString = function() { return 30 }console.log(fn + 10); // 40

除此之外,当我们重写函数的valueOf方法也能够改变函数的隐式转换结果。

    function fn() { return 20; }fn.valueOf = function() { return 60 }console.log(fn + 10); // 70

当我们同时重写函数的toString方法与valueOf方法时,最终的结果会取valueOf方法的返回结果。

    function fn() { return 20; }fn.valueOf = function() { return 50 }fn.toString = function() { return 30 }console.log(fn + 10); // 60

下面是具体的实现方法:

    //实现参数不确定下的相加function add() {// 第一次执行时,定义一个数组专门用来存储所有的参数var _args = [].slice.call(arguments);// 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值var adder = function () {var _adder = function() {// [].push.apply(_args, [].slice.call(arguments));_args.push(...arguments);return _adder;};// 利用隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回_adder.toString = function () {return _args.reduce(function (a, b) {return a + b;});}return _adder;}// return adder.apply(null, _args);return adder(..._args);}var a = add(1)(2)(3)(4);   // f 10var b = add(1, 2, 3, 4);   // f 10var c = add(1, 2)(3, 4);   // f 10var d = add(1, 2, 3)(4);   // f 10// 可以利用隐式转换的特性参与计算console.log(a + 10); // 20console.log(b + 20); // 30console.log(c + 30); // 40console.log(d + 40); // 50// 也可以继续传入参数,得到的结果再次利用隐式转换参与计算console.log(a(10) + 100);  // 120console.log(b(10) + 100);  // 120console.log(c(10) + 100);  // 120console.log(d(10) + 100);  // 120// 其实上栗中的add方法,就是下面这个函数的柯里化函数,只不过我们并没有使用通用式来转化,而是自己封装function add(...args) {return args.reduce((a, b) => a + b);}
经典的作用域问题

只要牵涉到函数作用域的问题我们一般都要想到闭包。他的牵涉范围甚广,一道题往往牵涉作用域,闭包,变量提升,自由变量,this指向等等。

在全局函数中this等于window

当函数被当做某个对象的方法调用时,this等于那个对象

匿名函数的执行环境具有全局性,this通常指向window

闭包在实际开发中的运用?

在实际开发中,闭包主要是用来封装变量,收敛权限。

    //封装变量,收敛权限
function isFirstLoad(){var list=[];return function(option){if(list.indexOf(option)>=0){ //检测是否存在于现有数组中,有则说明已存在console.log('已存在')}else{list.push(option);console.log('首次传入'); //没有则返回true,并把这次的数据录入进去}}
}var ifl=isFirstLoad();
ifl("zhangsan");
ifl("lisi");
ifl("zhangsan");

闭包的概念,作用,和优缺点相关推荐

  1. 闭包的概念、作用、问题及解决方式

    闭包(closure) **概念:**有权访问另一个函数作用域中变量的函数 **作用:**延伸变量的作用范围 特殊点: 代码中的变量分为两种:全局变量和局部变量,全局变量可以提供给全局所用函数使用,而 ...

  2. JS闭包的作用与优缺点

    一.什么是闭包 闭包是指一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure). 简单来说就是指有权访 ...

  3. 什么是闭包?闭包的工作原理、优缺点、使用场景和对页面的影响

    参考博客:http://www.cnblogs.com/cxying93/p/6103375.html 闭包(closure)是javascript的一大难点,也是它的特色.很多高级应用都要依靠闭包来 ...

  4. [html] 你认为table的作用和优缺点是什么呢?

    [html] 你认为table的作用和优缺点是什么呢? 优点:写表格方便快捷,样式统一,居中对齐,减少使用div,seo较好 缺点:需要写的内容较多 个人简介 我是歌谣,欢迎和大家一起交流前后端知识. ...

  5. 深入理解Lua的闭包:概念和应用

    深入理解Lua的闭包一:概念和应用_cbbbc的博客-CSDN博客 本文首先通过具体的例子讲解了Lua中闭包的概念,然后总结了闭包的应用场合,最后探讨了Lua中闭包的实现原理. 闭包的概念 在Lua中 ...

  6. 闭包的形成,闭包的优点和缺点,闭包有哪些作用?

    什么是闭包?形成闭包的条件?闭包的优点和缺点?闭包有哪些作用? 1.闭包须具备三个条件,缺一不可. 2.函数A里面直接或者间接返回一个函数B. 3. 函数B里面使用着函数A里面的私有变量或者私有数据. ...

  7. 【mysql】主键的概念作用及特点

    概念 : 主关键字(主键,primary key)是被挑选出来,作表的行的惟一标识的候选关键字.一个表只有一个主关键字.主关键字又可以称为主键.主键可以由一个字段,也可以由多个字段组成,分别成为单字段 ...

  8. 关于前后端分离的概念,作用,优缺点

    前端概念 前端是一切直接与用户交互的页面或软件(用户看得见.摸得着)的统称,比如各种网站网页.andorid 手机各种 App.苹果手机各种 app.微信小程序.网络游戏客户端等.所以,普通人使用计算 ...

  9. 什么是闭包?闭包有啥作用?闭包的应用有啥?内存优化?

    什么是闭包?闭包的应用有哪些? 是不是很多人一开始所了解的闭包是一个函数套着另一个函数,然后其他的函数可以引用里面的函数的变量(很久之前俺就是这么理解的)?看完这篇文章后,球球泥们不要再这么回答了好嘛 ...

最新文章

  1. 彻底理解 Cookie、Session、Token
  2. Python爬虫基础:常用HTML标签和Javascript入门
  3. 获取androdmanifest里面的meta-data
  4. php网页制作头部和尾部,用phpcms如何将静态页面制作成企业网站,头部加尾部
  5. 腾讯翻译君在线翻译怎么翻译整个文件_希腊语怎么翻译?教你两个超实用的翻译方法...
  6. bp神经网络误差反向传播,bp神经网络结果不一样
  7. 重置Win10网络网卡命令
  8. 5G无线关键技术 — 灵活频谱共享技术
  9. 笔记本内置网卡发射wifi
  10. 分布式数据存储系统:三要素
  11. phpmywind教程:单页信息调用说明【进阶篇一】
  12. 205. Isomorphic Strings
  13. picker插件 vue 移动端_移动端的picker参考vux
  14. html多张图片无缝滚动播放,jQuery实现的多张图无缝滚动效果【测试可用】
  15. 数据治理【主数据管理】
  16. java模拟简单的银行账户,可用于存取款,查询业务操作
  17. 2017年支付宝五福活动的python生福脚本。
  18. 搭建树莓派 4B + intel movidius 神经元计算棒2代深度学习环境
  19. 《失控》之九--《冒出》的生态圈
  20. 手撕自动驾驶算法——IMU测量模型、运动模型、误差模型

热门文章

  1. Vulkan系列教程—VMA教程(一)—快速上手VMA
  2. Linux的用户-组-权限详解
  3. Form 表单提交的几种方式
  4. Ubuntu 卸载 Docker
  5. 最简单的视音频播放演示样例3:Direct3D播放YUV,RGB(通过Surface)
  6. java sql传参_JAVA执行带参数的SQL语句
  7. Ubuntu16.04 64位 + GTX1070显卡驱动 + CUDA 8.0
  8. linux下parted分区,linux下parted分区
  9. SPS PPS SEI
  10. ping与telnet