[javascript]js函数的几种写法 闭包概要

http://www.cnblogs.com/jianghua/archive/2012/05/10/2493842.html

最常见的:

Js代码
1 function foo() {  
2  alert('hi, js');  
3 }  
4 foo();  

用匿名函数:

Js代码
1 var foo = function () {  
2  alert('hi, js');  
3 }  
4 foo(); 

改装一下,给调用的foo()加个括号:

Js代码
1 var foo = function () {  
2  alert('hi, js');  
3 }  
4 (foo)();  

干脆,连foo的定义也省掉------把foo赋值语句的等号右边的东东、直接替换掉刚才括起来的foo:

Js代码
1 (function () {  
2  alert('hi, js');  
3 })();  

先看常用的函数:

复制代码
1 function sayHello(name) {  
2   var text = 'Hello ' + name;  
3   var sayAlert = function() { alert(text); }  
4   sayAlert();  
5 }  
6 sayHello('Bob');  
复制代码

闭包的例子

一句话描述:

  • 闭包是函数的局部变量,在函数return之后,仍然有值, 或者
  • 闭包是stack-frame,在函数return的时候,它不会被释放。(就好像'stack-frame'是内存分配、而非处于堆栈!)

下面的代码返回一个function的引用:

复制代码
1 function sayHello2(name) {  
2   var text = 'Hello ' + name; // local variable  
3   var sayAlert = function() { alert(text); }  
4   return sayAlert;  
5 }  
6 var say2 = sayHello2('Jane');  
7 say2(); //hello Jane  
复制代码

多数JavaScript程序员能够理解上面代码的函数引用如何返回给变量。请在学习闭包之前理解它。C程序员把函数看做返回的一个函数指针,变量sayAlert和say2分别是函数指针。


C函数指针和JavaScript的函数引用有着本质的不同。在JavaScript,函数引用变量既是一个函数指针,又是一个隐藏的闭包指针。

上面代码拥有闭包,因为函数体内又声明了一个匿名函数 function() { alert(text); } ,参看例子中的sayHello2()。如果你在另一个函数内使用function关键字,闭包就产生了。

在C和其他多数语言,当函数return之后,stack-frame就被销毁了,所有的局部变量也就不能访问了。

在JavaScript中,如果你在函数里声明了函数,在你调用的函数renturn之后,局部变量仍然可以访问。请注意上面的例子,我们调用了变量text,它是函数sayHello2的局部变量。

Example 3

这个例子表明局部变量不是拷贝传递,而是引用传递。在外层函数退出时,它把stack-frame保存在内存。

复制代码
 1 function say667() {  
 2   // Local variable that ends up within closure  
 3   var num = 666;  
 4   var sayAlert = function() { alert(num); }  
 5   num++;  
 6   return sayAlert;  
 7 }  
 8 var sayNumba = say667();  
 9 sayNumba(); //667,而不是666  
10 alert(sayNumba.toString());  
复制代码

Example 4

三个函数对某个闭包使用同一个引用,因为它们均在setupSomeGlobals()里声明的。

复制代码
 1 var gAlertNumber = gIncreaseNumber = gSetNumber = null;  
 2 function setupSomeGlobals() {  
 3   // Local variable that ends up within closure  
 4   var num = 666;  
 5   // Store some references to functions as global variables  
 6   gAlertNumber = function() { alert(num); }  
 7   gIncreaseNumber = function() { num++; }  
 8   gSetNumber = function(x) { num = x; }  
 9 }  
10 setupSomeGlobals();  
11 //任意、多次 运行下面的函数  
12 gAlertNumber();  
13 gIncreaseNumber();  
14 gSetNumber(5); //把num重新设为 5  
15 gSetNumber(-8888); //把num重新设为 -8888  
复制代码

重新运行setupSomeGlobals(); 就会重新产生一个新的闭包。在JavaScript中,当你在函数里又声明一个函数,外部函数每调用一次,内部函数将再被重新产生一次。

Example 5

当心下面例子的循环:闭包中的局部变量可能和你最初想的不一样。

复制代码
 1 function buildList(list) {  
 2   var result = [];  
 3   for (var i = 0; i < list.length; i++) {  
 4     var item = 'item' + list[i];  
 5     result.push( function() {alert(item + ' ' + list[i])} );  
 6   }  
 7   return result;  
 8 }  
 9   
10 function testList() {  
11   var fnlist = buildList([1,2,3]);  
12   // using j only to help prevent confusion - could use i  
13   for (var j = 0; j < fnlist.length; j++) {  
14     fnlist[j]();  
15   }  
16 }  
17   
18 testList();  //输出3次:'item3 undefined'  
复制代码

Example 6

下面的例子表明,闭包包含了 在外部函数退出之前、定义的任何局部变量。注意,变量alice实际上在匿名函数之后声明的。匿名函数先被声明:当函数被调用时,它可以访问alice,因为alice在闭包里。

复制代码
1 function sayAlice() {  
2   var sayAlert = function() { alert(alice); }  
3   // Local variable that ends up within closure  
4   var alice = 'Hello Alice';  
5   return sayAlert;  
6 }  
7 sayAlice()(); //Hello Alice  
8 alert(alice); //错误:alice不是全局变量,它在函数体内var了  
复制代码

Example 7


下面的例子表明,每次调用会产生各自的闭包。

复制代码
 1 function newClosure(someNum, someRef) {  
 2   // Local variables that end up within closure  
 3   var num = someNum;  
 4   var anArray = [1,2,3];  
 5   var ref = someRef;  
 6   return function(x) {  
 7       num += x;  
 8       anArray.push(num);  
 9       alert('num: ' + num +   
10           '\nanArray ' + anArray.toString() +   
11           '\nref.someVar ' + ref.someVar);  
12     }  
13 }  
14 closure1 = newClosure(40, {someVar : 'closure 1'});   
15 closure1(5);  
16   
17 closure2 = newClosure(1000, {someVar : 'closure 2'});  
18 closure2(-10);  
复制代码

小结


读一些说明要比理解上面的例子难得多。我对于闭包的说明以及stack-frame等等在技术上可能不正确 --- 但是它们的确有助于理解


s函数的两种写法:静态函数及非静态函数 
http://blog.sina.com.cn/s/blog_675879000100iju3.html
1、js静态化函数,使用的时候不需要初始化。如下:
  var CheckFlash = {
            check: function() {
                var isIE = (navigator.appVersion.indexOf("MSIE") >= 0);
                var hasFlash = true;
                if (isIE) {
                    try {
                        var objFlash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
                    } catch (e) {
                        hasFlash = false;
                    }
                } else {
                    if (!navigator.plugins["Shockwave Flash"]) {
                        hasFlash = false;
                    }
                }
                return hasFlash;
            }
         , prompt: function() {
             var flag = this.check();
             if (!flag) {
                 window.alert("本页面需要安装9.0以上的flash播放器后才能正常安装!");
             }
             else {
                 alert("Y");
             }
         }
     }

使用的时候直接调用即可:window.onload = CheckFlash.prompt();
2、需要初始化得写法
        var CheckFlash = function(){};
        CheckFlash.prototype={
            check: function() {
                var isIE = (navigator.appVersion.indexOf("MSIE") >= 0);
                var hasFlash = true;
                if (isIE) {
                    try {
                        var objFlash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
                    } catch (e) {
                        hasFlash = false;
                    }
                } else {
                    if (!navigator.plugins["Shockwave Flash"]) {
                        hasFlash = false;
                    }
                }
                return hasFlash;
            }
         , prompt: function() {
             var flag = this.check();
             if (!flag) {
                 window.alert("本页面需要安装9.0以上的flash播放器后才能正常安装!");
             }
             else {
                 alert("Y");
             }
         }
     }

   调用方法: var c = new CheckFlash();
        c.prompt();
   两者的优点缺点暂时还不知

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值