javascript闭包和立即执行函数的作用

carrie_zhao      2022-02-12     402

关键词:

一、闭包——closure

  先看一个闭包的例子。我们想实现一个计数器,最简单的方法就是定义一个全局变量,计数的时候将其加1。但是全局变量有风险,哪里都有可能不小心改掉它。那局部变量呢,

它只在函数内部有效,函数调用完后它就没了,而且全局没法使用。那我们用想让计数器全局使用,又不想让这个变量被随便修改怎么办。这就需要闭包了:

function count(){
    var i=0;
    return function () {
        return ++i;
    }
}    

  这个例子实现了一个简单的计数器。函数"count()"定义了一个局部变量“i”,并返回一个内部匿名函数。因为是内部函数,所以它可以访问其外部函数的局部变量“i”,并且将其加1并返回。让我们看下怎么使用这个计数器。

c1 = count();
console.log(c1());  //print1
console.log(c1());  //print2
console.log(c1());  //print3

c2 = count();
console.log(c2());  //print1

 每次调用“count()”函数后就会生成一个计数器,而且不同的计数器之间不干扰。因为两次调用同一个函数,创建的栈是不同的,因此栈内的局部变量是不同的。上例中,我们生成了全局计数器“c1”和“c2”,他们都是不带参数的函数,即“count()”中返回的匿名函数。此后每次调用计数器,比如“c1()”,计数器就会自增1并返回。但是由于“count()”函数已经调用完毕,我们将无法通过任何其他办法去修改“count()”中变量“i”的值。这就是闭包最实用的功能,就是将你想操作的变量或对象隐藏起来,只允许特定的方法才能访问它

二、立即执行函数

  n年前看到jQuery的源码时,很好奇它的最外层结构是这样的(现在已经不一样了):var jQuery = (function(){……})();

  作为前端小白的我,实在想不通这是为什么,好好定义一个函数,为啥还要调用它。大家知道javascript在es6之前并不严格支持面向对象。js的对象其实就是一个map,比如下面的例子:

var car = {
    speed:0,
    start:function(){ this.speed=40; },
    getspeed:function(){ return this.speed; }
};
car.start();
console.log(car.getspeed()); //print 40

  这个对象有其成员变量“speed”及成员函数“start”和“getspeed”,但是它的成员变量没有私有化,同时它也没有办法被继承。要实现对象的继承,你可以使用构造函数原型继承。但怎么才能将成员变量私有化来实现对象的封装呢(而且有时候我们也不想那么麻烦使用原型)?有心的读者看了上面闭包的介绍,肯定马上有想法了。对,使用闭包!

function car() {
    var speed = 0;
    return { //返回的是一个对象
        start:function() {
            speed = 50;
        },
	getspeed:function () {
	     return speed;
        }
    }
}

var car1 = car();
car1.start();
console.log(car1.getspeed()); //print 50

  说了那么多,跟立即执行函数有什么关系呢。你再仔细看看上面的例子,你有了闭包函数来帮你创建“car”对象,这个函数就类似于工厂方法,它可以根据你的需要创建多个不同的对象。不过开发的时候经常遇到这样的情况,就是我们希望对象只有一份,比如jQuery库的对象,它必须确保整个程序只有一份,多了也没有。在后端开发模式中,这叫单例模式,可以通过私有化构造函数来实现,那么在js里呢?

 

  既然函数没法私有化,那么唯一的办法就是让这个工厂方法能且只能被调用一次。不能多次调用,那这个函数一定要是匿名函数;而且能被调用一次,那就必须在声明的时候立马执行。这时候,我们就可以邀请立即执行函数出场了:

 var car = (function () {
    var speed = 0;
    return {
        start:function () {
            speed=60;
        },
        getspeed:function () {
	     return speed;
        }
    }
})();

car.start();
console.log(car.getspeed()); //print 60                    

  很多人一开始会看错,认为对象“car”是一个函数,其实它是这个匿名的工厂方法执行完返回的对象,该对象拥有“start”和“getspeed”两个成员函数,而这两个函数所需要访问的“speed”变量对外不可见。同时你无法再次调用这个匿名的工厂方法来创建一个相同的对象。是不是很神奇?一个单例的,有着私有成员的对象就这么建好了。

  立即执行函数还有一种写法就是:

var car = (function () {
	……				
}());

  

本篇文章的出处:http://www.bjhee.com/js-closure-iif.html 

闭包和立即执行函数

...,我会持续更新!   一直没搞清楚立即执行函数和闭包之间的关系,总结一下:闭包有很多种理解:访问不到内部作用域,函数就是这样,所以函数就是闭包;闭包还有一种理解:通过把函数内部的变量和方法返回出来,... 查看详情

作用域闭包立即执行函数(代码片段)

一、作用域(Scope)        [[scope]]指的就是我们所说的作用域,其中存储了运行期上下文的集合。即作用域决定了代码区块中变量和其他资源的可见性。1、全局作用域        在外面定义的函数、变量,没有定义,却... 查看详情

javascript学习-46.立即执行函数(代码片段)

前言立即执行函数有以下作用创建一个独立作用域,这个作用域里面的变量,外部访问不到,避免变量污染。闭包和私有数据使用语法有两种写法//第一种:用括号把整个函数定义和括号调用包裹起来(function()//函... 查看详情

javascript闭包

什么是闭包  在JavaScript中,闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包指的就是在一个函数内部创建另一个函数。 闭包的作用  1.可以使外部作用域读取到内部作用域的变量    在js中的作用域... 查看详情

javascript——作用域和闭包概念

 js是函数级别作用域,在内部的变量,内部能都访问到,外部不能访问内部的,内部的可以访问外部的   闭包就是,拿到本不是应该属于他的东西。 当在函数内部定义了其他函数时,就创建了闭包,闭包有权访问... 查看详情

javascript作用域和闭包(代码片段)

JavaScript中的作用域指的是变量和函数的可访问范围。JavaScript中,闭包是一个函数对象,它可以访问定义该函数的作用域里的变量,即使函数已经返回。闭包的特点是,它可以在其相关环境不存在时保留变量。闭包可以被保存到... 查看详情

javascript初阶--------函数闭包立即执行函数

 函数     有时候我们的代码重复了很多次,编程里面称为耦合,但是编程要讲究高内聚,弱耦合。为了将重复多的聚在一起就出现了函数。定义    函数基本要素:函数声明(function),函数名称,参数(形参,实... 查看详情

javascript语言核心--高阶函数及闭包

标记及清除的内存管理方案解决了循环引用带来的内存泄漏倾向于认为"闭包"是保存保存变量的作用域在嵌套函数定义中,引用了外层函数的变量,此时闭包才会出现(结合Chrome devptools查看)立即执行表达式配合闭包创建私有... 查看详情

javascript之作用域和闭包

执行上下文1、在一段 <script>...</script> 标签里面会有一个全局执行上下文  变量声明、函数声明提前2、在一个函数 functionfn(arguments){...} 内部会有一个函数执行上下文  变量声明、函数声明、 this&n... 查看详情

javascript闭包的理解和实例

所谓闭包,值得是词法表示包括不必要计算的变量的函数,也就是说,该函数可以使用函数外定义的变量。顺便提示一下:词法作用域:变量的作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,通过静... 查看详情

浅谈javascript的闭包

  JavaScript是一门动态的,弱类型的脚本语言。和大多数编程语言一样,JavaScript也采用词法作用域。也即是说,函数的执行依赖于变量作用域。这个作用域是在函数定义时决定的,而非函数调用。函数对象可以通过作用域链互... 查看详情

立即执行函数

...印第一次1demo();//打印第二次2a执行b定义,并被保存下来闭包通俗讲就是:内部函数通过return保存在外部了,闭包会导致原有作用域链不释放,造成内存泄漏。闭包的作用:1.实现公有变量;2.可以做缓存(存储机制);3. 查看详情

js函数的应用---立即执行函数全局污染闭包沙箱递归

一、立即执行函数---IIFE立即执行函数的集中表现形式:立即执行函数的特点:二、JS全局污染为什么会造成全局污染?JS没有块级作用域,在函数外定义的变量,均为全局变量;全局变量过多会削弱程序的灵活性,增大了模块之... 查看详情

javascript闭包的用法和场景(代码片段)

这里写目录标题闭包变量的作用域闭包的形成例子闭包的使用场景闭包和面向对象设计闭包与内存管理闭包闭包的形成与变量的作用域以及变量的生存周期密切相关。变量的作用域变量的作用域就是指变量的有效范围。我们最常... 查看详情

javascript----闭包(什么是闭包,为什么使用闭包,闭包的作用)

经常被问到什么是闭包?说实话闭包这个概念很难解释。JavaScript权威指南里有这么一段话:“JavaScript函数是将要执行的代码以及执行这些代码作用域构成的一个综合体。在计算机学术语里,这种代码和作用域额综合体叫做闭包... 查看详情

记录闭包和立即执行函数

闭包:http://www.runoob.com/js/js-function-closures.html 立即执行函数:IIFE(ImmediatelyInvokedFunctionExpression)http://benalman.com/news/2010/11/immediately-invoked-function-expression/#iife 查看详情

简述js的作用域和闭包

...了它们在什么样的上下文中执行,亦即上下文执行环境。Javascript的作用域只有两种:全局作用域和本地作用域,本地作用域是按照函数来区分的。闭包:在js中的我的理解就是函数嵌套函数,当内部函数在定义它的作用域的外部... 查看详情

作用域和闭包(以及this的用法)(代码片段)

...后(例如:fn();),函数体中的代码才会执行.ps:arguments是JavaScript里的一个内置对象,所有的函数都有属于自己的一个arguments对象,它包括了函所要调用的参数。ps:函数申明和函数表达 查看详情