JavaScript的“闭包”到底是什么

在JavaScripot函数闭包的定义中,一般都有一个outer 函数,一个inner函数。那么“闭包”到底是指outer函数呢,还是指inner函数?

从官方定义来看,并不清楚:A closure is a combination of a code block and data of a context in which this code block is created.

那么在下列函数中:

function outerfunc(y) {

 

          var internal1 = 100 ;

          var internal2 = 200 ;

         

          function innerfunc1(x) {

                    internal1++;

                    internal2 --;

          }

                   

          function innerfunc2()

          {

                    internal1--;

                    internal2++;

          }

         

          function get1()

          {

                    return internal1;

          }

         

          function get2()

          {

                    return internal2;

          }

         

          y.func1 = innerfunc1;

          y.func2 = innerfunc2;

          y.get1 = get1;

          y.get2 = get2;

}

 

到底是哪个函数闭包那个呢?是outerfunc闭包innerFunc1, innerfunc2呢?还是相反?

一般的教科书认为是innerfunc1 闭包了internal1和internal2。同样innerfunc2闭包了上述两个变量。这也不违反上述官方定义,只是总觉得在“语义”层面说不过去。看过我C++博客的读者会知道我对语义的痴迷。

我认为,正确的理解应该是outerfunc, innerfunc1, innerfunc2,get1,get2共同组成一个闭包,包揽了outerfunc的所有自由变量,参数, 以及local变量。

为什么呢?因为:

1) innerfunc1 和innerfunc2 都“定义”在outerfunc内,共享outerfunc的自由变量internal1和internal2。单独谈哪一个函数都没有意义。

2) 因为有了innerfunc1和innerfunc2,outerfunc的“语义”发生了根本的变化。本来是“auto”变量的internal1和 internal2变成了“heap”变量。具体的实现是JavaScript的implementation细节。但是懂得这一微妙的细节,会加深你对 JavaScript的理解。也知道closure的实现代价。

3) 上面这条的详细解读:没有闭包的outerfunc可以优化,利用stack变量来实现internal1和internal2。有了闭包,internal1和internal2必须由Garbage collection 来实现。功能当然会大幅下降。

以上第二点,对理解“闭包”,以及JavaScript函数的性质,有根本意义。

时间: 2024-08-01 08:39:00

JavaScript的“闭包”到底是什么的相关文章

JavaScript的“闭包”到底是什么(2)

我的上篇博客标题不对,造成一些误解.我认为博客的宗旨不是背教科书,而是分享研发心得.我的上篇标题因该改成"JavaScript 闭包的一个议题:它对outer scope 的影响",因为我没有严格地去分析闭包的定义,而是分析了实现闭包的其中一个语义问题. 讲清楚闭包是件麻烦事,我也没有看到什么关于JavaScript的权威性著作(比如像C++语言有 Bjarne Stroustrup的C++ programming language).所以除了苦读JavaScript语言国际标准<

跟我学习javascript的闭包_javascript技巧

JavaScript 闭包究竟是什么? 用JavaScript一年多了,闭包总是让人二丈和尚摸不着头脑.陆陆续续接触了一些闭包的知识,也犯过几次因为不理解闭包导致的错误,一年多了资料也看了一些,但还是不是非常明白,最近偶然看了一下 jQuery基础教程 的附录,发现附录A对JavaScript的闭包的介绍简单易懂,于是借花献佛总结一下. 1.定义 闭包:是指有权访问另外一个函数作用域中的变量的函数.创建闭包的常见方式就是在一个函数内部创建另外一个函数. 直接上例子 function a(){ v

深入理解JavaScript的闭包特性

有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4. <!DOCTYPE HTML>  <html>  <head>  <meta charset="utf-8" />  <title>闭包演示</title>  <style type="text/css">      p {background:gold;}   <

JavaScript创建闭包的两种方式的优劣与区别分析

  这篇文章主要介绍了JavaScript创建闭包的两种方式的优劣与区别分析的相关资料,需要的朋友可以参考下 通常JavaScript创建闭包比较常用的有两种方式. 构造函数方式: ? 1 2 3 new function() { var 变量... } 内联执行方式: ? 1 2 3 (function() { var 变量... })(); 在JavaScript内部运行机制下他们有什么区别?用哪种方式创建比较好?它与其它方式创建的闭包相比有什么优势? 我是这样理解的: 区别: 第一个:子方

javascript的闭包介绍(司徒正美)_javascript技巧

闭包的定义非常晦涩--闭包,是指语法域位于某个特定的区域,具有持续参照(读写)位于该区域内自身范围之外的执行域上的非持久型变量值能力的段落.这些外部执行域的非持久型变量神奇地保留它们在闭包最初定义(或创建)时的值(深连结).简单来说,闭包就是在另一个作用域中保存了一份它从上一级函数或作用域取得的变量(键值对),而这些键值对是不会随上一级函数的执行完成而销毁.周爱民说得更清楚,闭包就是"属性表",闭包就是一个数据块,闭包就是一个存放着"Name=Value"的对照表.

JavaScript中闭包之浅析解读(必看篇)_javascript技巧

JavaScript中的闭包真心是一个老生常谈的问题了,最近面试也是一直问到,我自己的表述能力又不能完全支撑起来,真是抓狂.在回来的路上,我突然想到了一个很简单的事情,其实我们在做项目时候,其实就经常用到闭包的,可是面试问的时候,回答又往往是我们经常搜到的答案,唉 不管是应付面试 还是真的想学点东西 ,我也用自己的理解跟大家分享一下,书面化就避免不了了的. 1.闭包是什么? 红宝书中曰:"是指有权访问另外一个函数作用域中的变量的函数." 简单的说,JavaScript允许使用内部函数-

JavaScript与PHP到底有何不同?

JavaScript与PHP,都是目前人气较高的两款编程语言.PHP是基于C语言而打造,因此非常适合有C语言基础的开发者.事实上,两种语言对于新手程序员来说都是比较容易上手的,而且它们都具备出色的灵活性与可扩展性. 那么,它们到底有何不同? 1.PHP能更轻松地实现定制化目标: 重构与定制化能力是决定编程语言命运的两大重要因素.PHP是开放源代码软件,意味开发者可以根据社区需求进行修改,而非立足单个开发者的需求,也正是它的开源特性使得PHP更为灵活也更加适用.凭借着这一点PHP能获得很多开发者的

学习javascript的闭包,原型,和匿名函数之旅_javascript技巧

本文通过示例给大家介绍javascript的闭包,原型,和匿名函数,具体详情请看下文. 一 .>关于闭包 理解闭包 需要的知识 1.变量的作用域 例1: var n =99; //建立函数外的全局变量 function readA(){ alert(n); //读取全局变量 } readA(); //执行此函数 例2: function readB(){ var c = 9; function readC(){ console.log(c); //ok c可见 } return readC; }

浅谈JavaScript的闭包函数_javascript技巧

在JavaScript中,闭包恐怕是很多人不能理解的一个概念了,甚至很多人也会把闭包和匿名函数混淆. 闭包是有权访问另一个函数作用域中的变量的函数.首先要明白的就是,闭包是函数.由于要求它可以访问另一个函数的作用于中的变量,所以我们往往是在一个函数的内部创建另一个函数,而"另一个函数"就是闭包. 比如之前提到过的作为比较函数: function createComparisonFunction(propertyName){ return function(object1,object2