您好、欢迎来到现金彩票网!
当前位置:秒速快三计划 > 属性闭包 >

分享一些前端开发中最常用的JS代码片段以及理解 JS闭包

发布时间:2019-07-07 05:08 来源:未知 编辑:admin

  参考资料:1.《你所不知道的JavaScript-上卷》闭包和作用域章节、2. 阮一峰老师的《学习JavaScript闭包》

  ( 大家学习时 为了更好理解,最好跟着本文内容 在IDE或浏览器控制台中,敲一遍所有的示例代码 )

  要彻底弄懂闭包,必须先理解 JS的变量作用域,变量分为:全局变量和局部变量,JS的特殊之处在于:每个函数都会创建一个新的作用域,函数内部可以读取函数外部的变量,相反 函数外部无法读取内部变量。

  上面代码中有三个逐级嵌套的作用域,我们可以将它们想象成几个逐级包含的作用域气泡如下图:

  作用域气泡是逐级包含的,图中最里面的紫色气泡被完全包在 最外层的foo所创建的淡蓝色气泡里。

  气泡2:包含着 函数foo 所创建的作用域,其中有三个标识符a、b、bar

  当JS引擎执行console.log(a, b, c)时,开始查找a、b、c这3个变量的引用,引擎首先从最内部的作用域  即function bar(c) {…}中开始查找,由于无法在这里找到a,因此它会去上一级的functionfoo() {…}作用域中继续查找,结果在这里找到了a,引擎便使用了这个引用,对于变量b、c 的查找过程也是一样,引擎会逐级向上查找。

  一般情况当然是不行的,但有个办法!我们可以在函数内部再定义一个函数,再将内部这个函数作为返回值,看下面代码你就明白了:

  我来解释下原理,函数bar的作用域能访问foo的内部作用域,而函数bar被作为值返回,当var todo =foo();执行了函数foo时,其实就将函数bar作为值引用类型传递给了todo,当执行todo()时 等于执行了bar(),这样在foo外部访问到了内部的局部变量a,所以我们看到输出结果为2。神奇的闭包让函数从外面作用域访问到了内部作用域的变量,原理其实就是 局部函数bar在它自己所定义的作用域之外被执行了。

  JS 中,通常一个函数执行完后,内部的整个作用域都会被销毁,被JS引擎的垃圾回收器回收,但闭包的出现阻止了这件事,上个例子中函数foo的作用域就不会销毁,因为它内部的作用域依然还存在,原来是本身在使用变量a的引用,而bar在foo的作用域之外被执行,当每次调用todo()时,便又访问到函数foo内部的变量a。

  各种专业文献上的”闭包“(closure)定义的非常抽象,晦涩难懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。由于在 Javascript 语言中,只有函数内部的子函数才能读取该函数的局部变量,因此可以把闭包简单理解成 “定义在一个函数内部的函数”。

  在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以在函数外部读取内部的变量,另一个就是让这些变量的值始终保持在内存中。

  其实在你写过的代码中 到处都有闭包的身影,如果将函数当作第一级的值类型并到处传递时,你就会看到闭包在这些函数中的应用,如:定时器、事件、Ajax请求、跨窗口通信、Web Workers或任何其他异步或同步的任务中,只要使用了回调函数,那就是在使用闭包,下面举了几个闭包的例子:

  (1) 由于闭包会使得函数中的变量都被保存在内存中,内存会消耗很大,如果滥用闭包,会造成网页的性能问题,在IE中还可能导致内存泄露。可以在退出函数之前,将不使用的局部变量全部删除 (设为null)。

  (2) 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

  有时候我们需要对一个变量查检其是否存在或者检查值是否有一个有效值,如果存在就返回 true 值。为了做这样的验证,我们可以使用!!操作符来实现是非常的方便与简单。对于变量可以使用 !!variable 做检测,只要变量的值为:0、null、” “、undefined 或者 NaN 都将返回的是 false,反之返回的是 true。比如下面的示例:

  这个技巧非常有用,其非常简单,可以交字符串数据转换成数字,不过其只适合用于字符串数据,否则将返回NaN,比如下面的示例:

  你也可以将变量简写,并且使用 && 和函数连接在一起,比如上面的示例,可以简写成这样:

  如果一些属性或函数存在于一个对象中,你也可以这样做检测,如下面的代码所示:

  在ES6中有默认参数这一特性。为了在老版本的浏览器中模拟这一特性,可以使用操作符,并且将将默认值当做第二个参数传入。如果第一个参数返回的值为 false,那么第二个值将会认为是一个默认值。如下面这个示例:

  这个技巧很简单,这个在处理一个很大的数组循环时,对性能影响将是非常大的。基本上,大家都会写一个这样的同步迭代的数组:

  如果是一个小型数组,这样做很好,如果你要处理的是一个大的数组,这段代码在每次迭代都将会重新计算数组的大小,这将会导致一些延误。为了避免这种现象出现,可以将 array.length 做一个缓存:

  当你需要检测一些属性是否存在,避免运行未定义的函数或属性时,这个小技巧就显得很有用。如果你打算定些一些跨兼容的浏览器代码,你也可能会用到这个小技巧。例如,你想使用 document.querySelector() 来选择一个 id,并且让它能兼容IE6浏览器,但是在IE6浏览器中这个函数是不存在的,那么使用这个操作符来检测这个函数是否存在就显得非常的有用,如下面的示例:

  Array.prototype.slice(begin,end)用来获取begin和end之间的数组元素。如果你不设置end参数,将会将数组的默认长度值当作end值。但有些同学可能不知道这个函数还可以接受负值作为参数。如果你设置一个负值作为begin的值,那么你可以获取数组的最后一个元素。如:

  这个小技巧主要用来锁定数组的大小,如果用于删除数组中的一些元素来说,是非常有用的。例如,你的数组有10个元素,但你只想只要前五个元素,那么你可以通过 array.length=5 来截断数组。如下这个示例:

  String.replace()函数允许你使用字符串或正则表达式来替换字符串,本身这个函数只替换第一次出现的字符串,不过你可以使用正则表达多中的 /g 来模拟 replaceAll() 函数功能:

  然后这个函数并不适合用来合并两个大型的数组,因为其将消耗大量的内存来存储新创建的数组。在这种情况之个,可以使用 Array.pus().apply(arr1,arr2)来替代创建一个新数组。这种方法不是用来创建一个新的数组,其只是将第一个第二个数组合并在一起,同时减少内存的使用:

  对于数组元素的洗牌,不需要使用任何外部的库,比如Lodash,只要这样做:

  现在你学会了些有用的JavaScript小技巧。希望这些小技巧能在工作中帮助你解决一些麻烦,或者说这篇文章对你有所帮助。如果你有一些优秀的JavaScript小技巧,欢迎与我们一起分享

  之前我用过一个检测客户端的库 觉得挺好用的,也推荐给大家 叫 device.js,大家可以 Googel 或 百度

  闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 一、变量的作用域要理解闭包,首先必须理解Javascript特殊的变量作用域。变量的作用域无非...博文来自:ruanhongbiao的专栏

  关于JS中闭包的理解,相信很多人都和笔者一样刚开始很是困惑。笔者也是在看了很多前辈的文章后,总结出一点自己的理解。记录与此,囿于笔者水平有限,若有错误之处,恳请不啬赐教。你可以在一个函数里面嵌套另外一...博文来自:cauchy6317的博客

  闭包是js中的一大特色,也是一大难点。简单来说,所谓闭包就是说,一个函数能够访问其函数外部作用域中的变量。闭包的三大特点为:1、函数嵌套函数2、内部函数可以访问外部函数的变量3、参数和变量不会被回收。...博文来自:baidu_33295233的博客

  中的代码解读使用闭包时,理解[color=red]内部函数是直接访问外部函数的实际变量,而非复制一份新变量是非常重要的[...博文来自:laj12347的专栏

  “官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。相信很少有人能直接看懂这句话,因为他描述的太学术。其实这句话通俗的来说就是:...博文来自:u013055993的博客

  1、问题及方案后台js代码规范度不好,怎么写的都有,不易维护、复用度低,我们不期全部使用backbone做到前端MVC,但使用模块化编程库做到模块化开发还是简单而有意义的。2、为什么要模块化时至今日,...博文来自:ww_regou的博客

  阮一峰博客:《学习Javascript闭包》章节中最后有个思考题:如果你能理解下面两段代码的运行结果,应该就算理解闭包的运行机制了。代码片段一varname=TheWindow;varobject...博文来自:残冰的代码笔记

  闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。闭包的特性闭包有三个特性:1.函数嵌套函数2.函数内部可以引用外部的参数和变量3.参数和变量不会...博文来自:Sarah_yzx的博客

  闭包实现了同时具有全局变量的特点和局部变量的特点。闭包既能够让函数能够去全局中获得其他方法作用域中的变量,还不会影响到全局中的那些变量,使他们互相影响。主要通过Returnfunction保存住变量。...博文来自:施天琦的博客

  关于js闭包的理解及特点闭包的概念:大致意思,在函数内部,定义一个内部函数,并用return返回,那么此内部函数就是一个闭包函数。详细的概念理解,请参考链接functionw(x){varc=&...博文来自:ybdt1201的博客

  javascript闭包、this2016-01-25 js pl闭包其实很好理解,但是由于经常把this和闭包绑在一起,从而加大了理解的难度,如果将他们分开考虑,那就清晰多了。闭包闭包并不是js首创...博文来自:破晓

  JS闭包的理解 一、变量的作用域二、如何从外部读取局部变量三、什么是闭包四、深入理解闭包五、闭包的用途六、使用闭包注意情况七、JavaScript的垃圾回收机制八、一些思考题 一、变量作用域1、要理解...博文来自:saucxs的博客

  执行环境和作用域每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返还给之前的执行环境。当代码在一个环境中执行时,会创建变...博文来自:RaeZhang的博客

  一、变量的作用域要理解闭包,首先必须理解Javascript特殊的变量作用域。变量的作用域无非就是两种:全局变量和局部变量。Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。Js...博文来自:小鱼儿的博客

  请教大家,如下定义一个abc的函数对象,第一次运行完abc()里面的i变成1,但是运行完成i不是被释放了吗,第二次运行应该i还是从零开始啊,为什么如下的会从上一次的i为1开始呢? 还有,这种定义函数对论坛

  作用域先来谈谈变量的作用域变量的作用域无非就是两种:全局变量和局部变量。全局作用域:最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的:varouterVar=outer;f...博文来自:Hello World

  闭包是什么?·了解闭包首先了解js的‘链式作用域’结构,对象可以一级一级的向上查找父对象的变量,所以父对象的变量对子对象可见,反之不成立;所以都可以访问全局变量·为了解决函数外部无法访问函数内局部变量...博文来自:zhouzuoluo的博客

  今天遇到一个面试题,结果让我百思不得其解。后来在查阅了各种文档后,理清了来龙去脉。让我们先来看看这道题:1functionFoo(){2vari=0;3returnfunction(){4...博文来自:初心勿忘

  最近开始学习js,这里总结一下常用JS代码,是对自己学习的一些总结,也希望对初学者有些帮助...博文来自:僅此的博客

  1.文本框焦点问题onBlur:当失去输入焦点后产生该事件onFocus:当输入获得焦点后,产生该文件Onchange:当文字值改变时,产生该事件Onselect:当文字加亮后,产生该文件(value...博文来自:zhangliangaries的专栏

  忽视右键或如何几秒后转到别的页面?点击关闭窗口点击关闭窗口!请问如何去掉主页右面的滚动条? 请问如何做到让一个网页自动关闭.这个窗口会在10秒过后自动关闭,而且不会出现提示. 如何在不刷新页面的情况下...博文来自:xinyu5073的专栏

  在理解js作用域和作用域链之后,()我们可以去探究闭包。functiona(){functi...博文来自:TimCope的博客

  在工作中遇到了内存泄露问题,在这记录一下:首先简单了解一下内存泄露的概念:链接然后看一下比较通俗易懂的例子,也是平时很少会注意的一些地方,了解一下:链接先简单介绍一下我这边的需要处理的工作:主要是将摄...博文来自:liuzijiang1123的专栏

  分析JavaScript的闭包机制,介绍词法作用域、函数作用域、GC、执行环境等博文来自:mht1829的博客

  在开发过程中经常用到总结出来的一些方法,收集整理,希望能给大家带来帮助,如有错误,欢迎指正。/*验证手机号码*/functionisTelNum(str){  var_tel=$.trim(str),...博文来自:人生如戏、全靠演技

  转自:前言:还是一篇入门文章。Javascript中有几个非常重要的语言特性——对象、...博文来自:chelen_jak的专栏

  是什么?当一个嵌套的内部函数引用了外部函数的变量或者函数时,外部函数在执行时就产生了闭包典型的闭包将另一个函数作为另一个函数的返回值functionFoo(){vara=0;functionfoo()...博文来自:要优秀!

  有工作经验的前端都知道,面试时基本都会问下js闭包问题,考查下你的js基础水平。作为新手前端刚入门的你,这个前端面试必备知识点,你会吗?不会的话,就赶快看下吧,补补课吧。1.闭包的概念:闭包就是一个函...博文来自:web前端开发博客

  闭包是JavaScript中比较重要的一部分,也是比较难的一个知识点。在看了阮一峰老师的关于闭包的博客后,感觉对闭包的理解更清晰了,有需要的同学不妨一看。博文来自:秃头哥编程

  帐号相关流程注册范围n企业n政府n媒体n其他组织换句话讲就是不让个人开发者注册。 :)填写企业信息不能使用和之前的公众号账户相同的邮箱,也就是说小程序是和微信公众号一个层级的。填写公司机构信息,对公账...博文来自:小雨同学的技术博客

  jquery/js实现一个网页同时调用多个倒计时(最新的)nn最近需要网页添加多个倒计时. 查阅网络,基本上都是千遍一律的不好用. 自己按需写了个.希望对大家有用. 有用请赞一个哦!nnnn//jsn...博文来自:Websites

  command窗口是命令窗口,即为sqplus窗口,有命令提示符,识别sqlplus命令,基本的命令都可以执行nsql仅可执行DDL、select、DML等...博文来自:Ape55的博客

  对象的创建和销毁在一定程度上会消耗系统的资源,虽然jvm的性能在近几年已经得到了很大的提高,对于多数对象来说,没有必要利用对象池技术来进行对象的创建和管理。但是对于有些对象来说,其创建的代价还是比较昂...博文来自:赶路人儿

  扫二维码关注,获取更多技术分享nnn 本文承接之前发布的博客《 微信支付V3微信公众号支付PHP教程/thinkPHP5公众号支付》必须阅读上篇文章后才可以阅读这篇文章。由于最近一段时间工作比较忙,...博文来自:Marswill

  记得很早以前公司项目中添加过移动支付这一块, 包括微信,支付宝,银联等第三方的整合。 但是后来懒于总结就没留下什么, 最近公司项目打算添加,所以打算简单总结一下,记上一笔以备将来使用。 毕竟第三方的支...博文来自:samuelnotes的专栏

  本篇文章是根据我的上篇博客,给出的改进版,由于时间有限,仅做了一个简单的优化。相关文章:将excel导入数据库2018年4月1日,新增下载地址链接:点击打开源码下载地址十分抱歉,这个链接地址没有在这篇...博文来自:Lynn_Blog

  最近比较有空,大四出来实习几个月了,作为实习狗的我,被叫去研究Docker了,汗汗!nnDocker的三大核心概念:镜像、容器、仓库n镜像:类似虚拟机的镜像、用俗话说就是安装文件。n容器:类似一个轻量...博文来自:我走小路的博客

http://isaegil.net/shuxingbibao/397.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有