前言:
今天写了一个关于Java内部的博客,在内部类的最后一点中谈到了Java闭包的概念,他是这样定义闭包的:闭包是一个可调用的对象,它记录了一些信息,这些信息来自创建它的作用域。结合Java的内部类可以很好的理解这一点(如有需要可参考https://www.cnblogs.com/jinliang374003909/p/10351877.html)。突然之间想到js中的闭包,一直都无法很好的理解,故借此又看了一下js中的闭包,对我个人而言,感悟良多,借此也与大家分享一下,希望可以帮助大家,并一起快乐的学习成长,天天向上。
零:js闭包概念(通过Java闭包和js嵌套函数和图一分析 :纯个人 见解,欢迎评论和建议)
闭包是一个返回给调用者的对象,而这个返回对象携带了一些调用者无法获取的信息
一:js中的对象定义(因为是针对闭包的学习就只简单介绍一种定义方法)
<script> function Car() { //定义class var color = "blue"; //定义属性 } Car.prototype.getColor = function() { //通过原型定义方法 console.info(this.color) return this.color; } var oCar1 = new Car();//创建对象实例 oCar1.getColor(); //调用方法 </script>
二:js中的变量作用域(全局变量和局部变量)
var a = "我是全局变量"; function myFunction() { var b = "我是局部变量" return a ; }function my2(){ consoke.info(b) #报错}
2.1 全局变量a:即属性window的属性,在同一页面内所有的js脚本,都共享同一个window对象,故共享全局变量a.
2.2 局部变量b :局部变量只能用于定义它函数内部。对于其他的函数或脚本代码是不可用的。
备注:变量声明时如果不使用 var 关键字,那么它就是一个全局变量,即便它在函数内定义。
三:计数器困境(引入问题)
解题思路:需要一个变量,这个变量需要在方法内访问并加一,多次调用该变量就是多次加一的和,故不能把该变量定义在方法的内部,如果把该变量定义在方法的内部就不能实现多次调用返回多次调用的和,故把该方法定义为全局变量如下,但这样定义该变量即不安全如调用方法2
var counter = 0; function add() { return counter += 1; } function myFunction(){ document.getElementById("demo").innerHTML = add(); } function myFunction2(){ counter = 100; document.getElementById("demo").innerHTML = add(); } myFunction(); myFunction();//实现多次调用返回,多次调用的和 ##counter =2 myFunction2();//但如果调用该方法,就不返回多次调用的和 #因为是全局变量,任何脚本都可更改该变量的值,这样及其不不安全。 ##counter =101
解题思路2:如果能把count变量隐藏起来不让其它js方法修改它不就行了吗?如果我们熟悉Java语言,用Java就很容易解决该问题。因为Java提供的修饰符private可以控制属性的访问限制。并定义一个唯一public方法设置该属性(就是把属性定义为私有的,并提供唯一的get和set方法,就这么简单)。然而如果把问题抛给js就很难解决这个问题了,以为js没有提供这样的修饰符,来控制访问属性。如何解决类似Java private成员的问题请看下面
四:JS的 内嵌函数(类比Java内部类 ,我们发现嵌套函数及其的像Java的内部类??)
JavaScript 支持嵌套函数。嵌套函数可以访问上一层的函数变量(我们可以这样理解:内部的变量可以访问其外面的变量,而外面的不能访问内部的。
//一个简单的js嵌套函数 function add() { //外部类 var counter = 0; function plus() { //嵌套函数 内部类 counter += 1; //嵌套函数可以访问其外部的变量 } plus(); return counter; }
类比Java :Java内部类可以访问外围对象的所有属性包括私有属性,js的嵌套函数好行也有这个属性??。
五:js立刻执行函数(顾名思义就是立刻执行),下面是一个立刻只能函数的写法
var aa = ( function(){ alert("sssss"); return {}; } )() //备注:当我们刷新当前页面时就会执行function方法并返回{}对象 //不需要手动调用该方法
通过立刻执行函数,并且返回一个空的对象,结合内嵌函数的特性,我们可知这个对象是可以访问外围的属性和方法的。
然后我们分析:利用嵌套函数和闭包的特性来分析下图
{//区域A(window) {//区域B return {//区域C 区域C返回到了区域A } } }
图一
结论如下
1. 区域A不能访问区域B定义的数据,故B就对A隐藏了。然而区域C可以访问区域B定义的数据,
2.区域C同过return返回给了区别A,如果区域C是一个方法,则A就可以调用这个方法,而这个方法是唯一能访问到B区域的。故B又提供了对A访问的方法。
这样就形成了一个js的闭包,(即闭包是一个返回给调用者的对象,而这个返回对象携带了一些调用者无法获取的信息)
备注:js方法也是对象
六:JS闭包,解决计数器困境
代码如下
var add = (function () { var counter = 0; return function () {return counter += 1;} })(); add(); add(); add(); // 计数器为 3
备注:
原文地址:https://www.cnblogs.com/jinliang374003909/p/10352464.html