`

javascript 闭包的一个例子

阅读更多

<html>
<title></title>
<head>
 
<script type="text/javascript">
 (function(msg) {
     alert(msg);
  })('hello');

</script>
</head>
</html>

 

 

以上代码将会弹出hello窗口

 

以上代码实际上是定义了一个匿名函数,并且调用了该匿名函数

分享到:
评论
11 楼 ca7pe 2012-05-15  
[/color][color=red]
引用
引用
引用
引用
引用
引用
引用

    [*]
[img][/img][/url][url][/url][url][url][/url]
10 楼 superobin 2011-03-11  
suiye007 写道
kidneyball 写道
suiye007 写道
superobin 写道
虽然勉强可以算是闭包,但是基本没有体现闭包的特性额
var closure = (function() {
    var a = 3;
    return function() {
        alert(a);
    };
})();
closure();//3

这个或许可以再深入一点?

我不明白你的代码与下面的代码有什么区别呢,或简单的说是优点呢?
var closure = function() {
    var a = 3;
    return function() {
        alert(a);
    };
};
closure();//3


下面的代码调用closure()得到的结果不是3,而是一个闭包。上面的代码closure本身就是闭包,调用这个闭包得到结果3

谢谢,发现问题所在了,我取的时候也是3,是New一个对象,然后,apply的,直接调用确实不是,不过,我有点不太明白什么时候要用闭包,什么时候不要用,虽然我的程序中闭包用得也比较的多,那是不得已的时候才用的 ,能给点经验吗?




我觉得闭包是一种更自然的代码形式,可以让你不拘泥于简单的块、函数作用域而穿透作用域。
举2个例子,一个用于隐藏一些变量,另一个用于异步调用:
1、隐藏变量:
Function.prototype.bind = function(obj) {
    var _this = this;
    return function() {
        _this.apply(obj,arguments);
    };
}



这个是最原始的Prototype框架里bind函数(绑定函数作用域)的最简化版本。在这里,我们可以看到调用bind后对obj对象的隐藏(这段代码可以理解为一种转移作用域的代理模式吧)。

2、异步调用。
假如我们有一段代码
function test() {
    var a = 1,b=2,c=3;
    alert(a+b+c);
}

需要改成异步延时的,只需要改成
function test() {
    var a = 1,b=2,c=3;
    setTimeout(function() {
        alert(a+b+c);
    },1000);
}

其实经验上讲,绝大多数的同步的地方改成异步都都可以用上述方法,只要将需要异步的部分(通常是从某一行开始到函数末尾)包含在闭包中,就可以进行异步处理了。

其实还有挺多其他应用,总之,如果心里想着“什么是闭包”,“我在用闭包”这种事的话,反而往往用不好闭包。只要深刻的理解js这种特性,这种作用域机制,将闭包使用在无形之中,才算是真正会使用闭包了吧。
9 楼 kidneyball 2011-03-11  
suiye007 写道

谢谢,发现问题所在了,我取的时候也是3,是New一个对象,然后,apply的,直接调用确实不是,不过,我有点不太明白什么时候要用闭包,什么时候不要用,虽然我的程序中闭包用得也比较的多,那是不得已的时候才用的 ,能给点经验吗?


往大里说,闭包是一种跟面向对象技术同样层面的“把数据与操作进行绑定”的技术。只不过面向对象是基于数据(对象实体)来封装操作(对象方法),而闭包是基于操作(函数)来封装数据(自由变量)

往小里说,使用闭包的最常见的场景是用来模拟“柯里化”。所谓柯里化,就是假如你有一个带有多个参数的函数,你可以通过指定其中某些参数的值,来产生参数较少的新函数。例如:
function f(x,n) { //求幂
    var result = 1;
    for (var i = 0; i <n; i++) {result *= x;}
    return result;
}

function currying(n) {
    return function(x) {return f(x,n);};
}

var square = currying(2);
var cube = currying(3);

alert(squre(2)); //4
alert(cube(2));  //8

柯里化有两个用处,

1是你可以为柯里化之后的方法命名,更有效地表达业务逻辑。

2是为回调函数提供接口上缺失但在绑定时可以确定的运行期信息。就是当回调函数接口无法提供满足业务需求的足够上下文信息,而这些信息在运行期注册回调函数时可以确定。这时我们在编程时可以设计出具有额外接口参数的回调函数,在注册回调函数时运用Currying创建出携带有这些信息的符合接口规范的新函数。

例如:
btn1.onclick=function() {....;n=n*3;....}; 
btn2.onclick=function() {....;n=n*6;....};  //...部分与btn1一致
btn3.onclick=function() {....;n=n*7;....};  //...部分与btn1一致

其中3,6,7是根据业务需求硬编码的,没有规律(也就是说在你绑定onclick时才知道到底是用3,6,还是7)。为了把回调函数抽象统一起来,如果不用闭包,你就必须把这个绑定期的信息缓存起来,以便在回调时可以使用:
btn1.x = 3;
btn2.x = 6;
btn2.x = 7;
function click() {...,n=n*this.x,...};
btn1.onclick=click; 
btn2.onclick=click;
btn3.onclick=click;

这种代码一多就搞得很乱,而且缓存信息的安全性也无法保证(很可能在回调之前就被其他人误操作修改了)。如果用闭包你可以:
function makeClick(x) {return function(x) {...;n=n*x;...}};
btn1.onclick=makeClick(3);
btn2.onclick=makeClick(6);
btn3.onclick=makeClick(7);


还有就是你可以通过闭包为某个函数实例保存一些内部的全局状态,这与面向对象类似,但是写起来比较方便简洁,避免了多余的传参或全局变量。例如:
function makeCounter() {
    var a = 0;
    return function() {return ++a;);
}

var counter1 = makeCounter();
var counter2 = makeCounter();

counter1(); counter1(); 
alert(counter1());  //3

counter2();
alert(counter2());  //2


代码是随手打的,没有测试,只是表达一下意思。
8 楼 suiye007 2011-03-11  
kidneyball 写道
suiye007 写道
superobin 写道
虽然勉强可以算是闭包,但是基本没有体现闭包的特性额
var closure = (function() {
    var a = 3;
    return function() {
        alert(a);
    };
})();
closure();//3

这个或许可以再深入一点?

我不明白你的代码与下面的代码有什么区别呢,或简单的说是优点呢?
var closure = function() {
    var a = 3;
    return function() {
        alert(a);
    };
};
closure();//3


下面的代码调用closure()得到的结果不是3,而是一个闭包。上面的代码closure本身就是闭包,调用这个闭包得到结果3

谢谢,发现问题所在了,我取的时候也是3,是New一个对象,然后,apply的,直接调用确实不是,不过,我有点不太明白什么时候要用闭包,什么时候不要用,虽然我的程序中闭包用得也比较的多,那是不得已的时候才用的 ,能给点经验吗?
7 楼 kidneyball 2011-03-10  
suiye007 写道
superobin 写道
虽然勉强可以算是闭包,但是基本没有体现闭包的特性额
var closure = (function() {
    var a = 3;
    return function() {
        alert(a);
    };
})();
closure();//3

这个或许可以再深入一点?

我不明白你的代码与下面的代码有什么区别呢,或简单的说是优点呢?
var closure = function() {
    var a = 3;
    return function() {
        alert(a);
    };
};
closure();//3


下面的代码调用closure()得到的结果不是3,而是一个闭包。上面的代码closure本身就是闭包,调用这个闭包得到结果3
6 楼 suiye007 2011-03-10  
superobin 写道
虽然勉强可以算是闭包,但是基本没有体现闭包的特性额
var closure = (function() {
    var a = 3;
    return function() {
        alert(a);
    };
})();
closure();//3

这个或许可以再深入一点?

我不明白你的代码与下面的代码有什么区别呢,或简单的说是优点呢?
var closure = function() {
    var a = 3;
    return function() {
        alert(a);
    };
};
closure();//3
5 楼 zk1878 2011-03-09  
mabusyao 写道
闭包:可以用一个概念本身来定义该概念。

LZ的例子似乎有那么点不恰当。。。

谢谢,指正 ,是我理解错了
4 楼 zk1878 2011-03-09  
呵呵,是我理解错了 ,谢谢各位指正
3 楼 kidneyball 2011-03-09  
闭包是“带有自由变量的函数”。楼上的例子是闭包(带有自由变量a),但楼主的例子不是闭包,只是“函数字面量”。
2 楼 superobin 2011-03-09  
虽然勉强可以算是闭包,但是基本没有体现闭包的特性额
var closure = (function() {
    var a = 3;
    return function() {
        alert(a);
    };
})();
closure();//3

这个或许可以再深入一点?
1 楼 mabusyao 2011-03-09  
闭包:可以用一个概念本身来定义该概念。

LZ的例子似乎有那么点不恰当。。。

相关推荐

    JavaScript闭包

    Javascript中有几个非常重要的语言特性——对象、原型继承、闭包。其中闭包 对于那些使用传统静态...本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点 ECMAScript语言规范来使读者可以更深入的理解闭包。

    javascript闭包详解中文word版

    本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点 ECMAscript语言规范来使读者可以更深入的理解闭包。闭包是Closure, 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。

    Javascript 闭包完整解释

    ### JavaScript闭包完整解释 #### 一、闭包的基本概念 **闭包**是一个非常重要的JavaScript概念,它指的是一个函数能够记住并访问其外部作用域中的变量的能力,即使该函数在其外部作用域之外被调用也是如此。具体...

    基于javascript 闭包基础分享

    文章中提到了两个例子:第一个例子中,通过一个循环来创建带有闭包的函数数组,但是由于JavaScript变量作用域和循环的作用,所有函数最终都只访问到了循环的最终值。第二个例子通过立即执行函数表达式(IIFE)来解决...

    javascript 闭包实例下载

    在这个例子中,`innerFunction`就是一个闭包,因为它可以访问到`outerFunction`的作用域内的变量`outerVar`,即使`outerFunction`已经执行完毕。`innerFunction`被赋值给了`innerReference`并调用,此时`outerVar`...

    javaScript闭包技术资料

    ### JavaScript闭包技术详解 #### 一、闭包的基本概念 **闭包**是JavaScript中一个重要的概念,它涉及到函数的执行环境、作用域链等关键要素。简单来说,闭包是一个函数及其相关的引用环境的组合。具体而言,当一...

    Javascript闭包实例详解

    另一个例子展示了闭包在循环中的应用,以及如何防止共享变量的问题: ```javascript function buildFunctions() { var funcArr = []; for (var i = 0; i ; i++) { funcArr.push(function() { console.log(i); ...

    javascript闭包高级教程

    ### JavaScript闭包高级教程 #### 简介 在JavaScript编程中,“闭包”是一个非常重要的概念,尤其对于希望深入理解和高效使用JavaScript的开发者来说。简单地说,闭包是一种能够记住并访问其创建时周围环境的函数...

    JavaScript闭包详解1

    JavaScript中的闭包是一种高级特性,它允许一个函数访问并操作其外部作用域的变量,即使在外部函数已经执行完毕后。这种机制的核心在于,当内部函数引用了外部函数的变量时,JavaScript会保持对外部作用域的引用,...

    揭开Javascript闭包的真实面目

    以下是一个简单的闭包例子: ```javascript function outerFunction() { var outerVariable = 'I am from the outer scope'; function innerFunction() { console.log(outerVariable); } return inner...

    javaScript闭包的理解

    ### JavaScript闭包的理解 #### 一、闭包的定义与特点 闭包是JavaScript中一个非常重要的概念,它指的是一个函数能够访问并操作其外部作用域中的变量的能力。这一特性使得JavaScript具有了一些其他语言不具备的...

    跟我学习javascript的闭包

    JavaScript 闭包究竟是什么? 用JavaScript一年多了,闭包总是让人...创建闭包的常见方式就是在一个函数内部创建另外一个函数。 直接上例子 function a(){ var i=0; function b(){ alert&#40;++i&#41;; } return

    javascript闭包详解

    ### JavaScript闭包详解 #### 一、什么是闭包? 闭包是JavaScript中一个重要的概念,它涉及函数如何访问外部作用域中的变量。虽然官方定义较为复杂:“闭包是一个拥有许多变量和绑定了这些变量的环境的表达式...

    JavaScript闭包与活动.pdf

    在这个例子中,`inner`函数形成了一个闭包,因为它引用了外部函数`outer`的`outerVar`变量。即使`outer`函数执行完毕,`outerVar`仍然可以通过`innerFunc`访问,因为闭包保存了对外部作用域的引用。 `this`关键字在...

    javascript闭包

    ### JavaScript闭包详解 #### 一、闭包概念与工作机制 **闭包**是JavaScript中最强大的特性之一,它使得函数能够记住并访问其定义时所在的作用域中的变量。要理解和运用闭包,首先需要理解作用域、作用域链以及...

    javaScript闭包

    ### JavaScript闭包详解 #### 引言 JavaScript作为一种动态、弱类型的编程语言,在Web开发领域占据了举足轻重的地位。其中,“闭包”是JS语言中一个非常重要的概念,它不仅能够帮助开发者实现某些特殊的功能,如...

    使用XMLHTTPRequest实现自定义ajax。javascript闭包模式写法。值的学习

    闭包是JavaScript中的一个重要特性,它可以访问并操作函数内部的变量,即使在函数执行完毕后,这些变量依然存在。下面是一个使用闭包模式实现的Ajax函数示例: ```javascript function createAjax() { var xhr = ...

    JavaScript闭包深入理解.pdf

    官方解释可能较为抽象,但简单来说,JavaScript中的每个函数都可以视为一个闭包,尤其是当一个函数内部定义了另一个函数,并且内部函数引用了外部函数的变量时,就形成了一个强大的闭包。例如以下代码: ```...

    JavaScript闭包的定义和理解,含代码示例

    ### JavaScript闭包详解 #### 一、闭包的定义与概念 闭包是JavaScript中一个非常重要的概念,它涉及到函数作用域以及变量的作用域链。简单来说,闭包就是一个能够访问其外部作用域中变量的函数。具体而言,当一个...

Global site tag (gtag.js) - Google Analytics