首页 > 代码库 > 六一笔记

六一笔记

一、ajax

AJAX的概念就是页面互动无刷新的效果。

例如:你做一个注册页面,因为用户一般都是唯一的,这个时候你就可以选择一个比较人性化的做法,就是使用AJAX技术,当填完信息鼠标移开txtUserName这个文本框的时候 触发一个事件,然后这个事件调用一个JS方法。JS方法里面使用xmlHttpRequest这个对象。就可以异步的调用后来 来完成一个 查询并且判断的过程。 最后返回一个结果 在前面来判断输入的 “用户名是否在!”。

二、表单验证

表单验证是javascript中的高级选项之一。JavaScript 可用来在数据被送往服务器前对 HTML 表单中的这些输入数据进行验证。

被 JavaScript 验证的这些典型的表单数据有:

用户是否已填写表单中的必填项目?

用户输入的邮件地址是否合法?

用户是否已输入合法的日期?

用户是否在数据域(numeric field) 中输入了文本?

必填项目

下面的函数用来检查用户是否已填写表单中的必填(或必选)项目。假如必填或必选项为空,那么警告框会弹出,并且函数的返回值为 false,否则函数的返回值则为 true(意味着数据没有问题):

function validate_required(field, alerttxt)

{ with(field)

{ if (value =http://www.mamicode.com/= null || value =="")

{ alertalerttxt); return false; }

else { return true; } } }

function validate_required(field, alerttxt)

{ with(field)

{ if (value =http://www.mamicode.com/= null || value =="")

{ alertalerttxt); return false; }

else { return true; } } }

下面是连同 HTML 表单的代码:

Email:

邮箱验证

下面的函数检查输入的数据是否符合电子邮件地址的基本语法。

意思就是说,输入的数据必须包含 @ 符号和点号(.)。同时,@ 不可以是邮件地址的首字符,并且 @ 之后需有至少一个点号:

function validate_email(field, alerttxt) { with(field) { apos = value.indexOf("@") dotpos = value.lastIndexOf(".") if (apos < 1 || dotpos - apos < 2) { alertalerttxt); return false; } else { return true; } } }

function validate_email(field, alerttxt) { with(field) { apos = value.indexOf("@") dotpos = value.lastIndexOf(".") if (apos < 1 || dotpos - apos < 2) { alertalerttxt); return false; } else { return true; } } }

下面是连同 HTML 表单的完整代码:

function validate_email(field, alerttxt)

{

with(field) { apos = value.indexOf("@"); dotpos = value.lastIndexOf(".");

if (apos < 1 || dotpos - apos < 2)

{

alertalerttxt);

return false;

}

else

{

return true;

}

}

}

function validate_form(thisform)

{

with(thisform)

{

if (validate_email(email, "Not a valid e-mail address!") == false)

{

email.focus();

return false

}

}

}

Email:

发送数据

三、弹出框大小

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>jQuery Alert Dialogs</title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<meta name="description" content="This is a demonstration page." />
<meta name="keywords" content="alert, confirm, prompt, demo" />

<style type="text/css">
BODY,
HTML {
padding: 0px;
margin: 0px;
}
BODY {
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
background: #FFF;
padding: 15px;
}

H1 {
font-size: 20px;
font-weight: normal;
}

H2 {
font-size: 16px;
font-weight: normal;
}

FIELDSET {
border: solid 1px #CCC;
-moz-border-radius: 16px;
-webkit-border-radius: 16px;
border-radius: 16px;
padding: 1em 2em;
margin: 1em 0em;
}

LEGEND {
color: #666;
font-size: 16px;
padding: 0em .5em;
}

PRE {
font-family: "Courier New", monospace;
font-size: 11px;
color: #666;
background: #F8F8F8;
padding: 1em;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
}

/* Custom dialog styles */
#popup_container.style_1 {
font-family: Georgia, serif;
color: #A4C6E2;
background: #005294;
border-color: #113F66;
}

#popup_container.style_1 #popup_title {
color: #FFF;
font-weight: normal;
text-align: left;
background: #76A5CC;
border: solid 1px #005294;
padding-left: 1em;
}

#popup_container.style_1 #popup_content {
background: none;
}

#popup_container.style_1 #popup_message {
padding-left: 0em;
}

#popup_container.style_1 INPUT[type=‘button‘] {
border: outset 2px #76A5CC;
color: #A4C6E2;
background: #3778AE;
}

</style>

<!-- Dependencies -->
<script src="http://www.mamicode.com/jquery.js" type="text/javascript"></script>
<script src="http://www.mamicode.com/jquery.ui.draggable.js" type="text/javascript"></script>

<!-- Core files -->
<script src="http://www.mamicode.com/jquery.alerts.js" type="text/javascript"></script>
<link href="http://www.mamicode.com/jquery.alerts.css" rel="stylesheet" type="text/css" media="screen" />

<!-- Example script -->
<script type="text/javascript">

$(document).ready( function() {

$("#alert_button").click( function() {
jAlert(‘This is a custom alert box‘, ‘Alert Dialog‘);
});

$("#confirm_button").click( function() {
jConfirm(‘Can you confirm this?‘, ‘Confirmation Dialog‘, function(r) {
jAlert(‘Confirmed: ‘ + r, ‘Confirmation Results‘);
});
});

$("#prompt_button").click( function() {
jPrompt(‘Type something:‘, ‘Prefilled value‘, ‘Prompt Dialog‘, function(r) {
if( r ) alert(‘You entered ‘ + r);
});
});

$("#alert_button_with_html").click( function() {
jAlert(‘You can use HTML, such as <strong>bold</strong>, <em>italics</em>, and <u>underline</u>!‘);
});

$(".alert_style_example").click( function() {
$.alerts.dialogClass = $(this).attr(‘id‘); // set custom style class
jAlert(‘This is the custom class called &ldquo;style_1&rdquo;‘, ‘Custom Styles‘, function() {
$.alerts.dialogClass = null; // reset to default
});
});
});

</script>

</head>

<body>

<h1><a href="http://abeautifulsite.net/2008/12/jquery-alert-dialogs/">&laquo; jQuery Alert Dialogs (Alert, Confirm, &amp; Prompt Replacements)</a></h1>

<h2>Basic Examples</h2>

<fieldset>
<legend>Alert</legend>
<pre>
jAlert(‘This is a custom alert box‘, ‘Alert Dialog‘);
</pre>
<p>
<input id="alert_button" type="button" value="http://www.mamicode.com/Show Alert" />
</p>
</fieldset>


<fieldset>
<legend>Confirm</legend>
<pre>
jConfirm(‘Can you confirm this?‘, ‘Confirmation Dialog‘, function(r) {
    jAlert(‘Confirmed: ‘ + r, ‘Confirmation Results‘);
});
</pre>
<p>
<input id="confirm_button" type="button" value="http://www.mamicode.com/Show Confirm" />
</p>
</fieldset>

<fieldset>
<legend>Prompt</legend>
<pre>
jPrompt(‘Type something:‘, ‘Prefilled value‘, ‘Prompt Dialog‘, function(r) {
    if( r ) alert(‘You entered ‘ + r);
});
</pre>
<p>
<input id="prompt_button" type="button" value="http://www.mamicode.com/Show Prompt" />
</p>
</fieldset>



<h2>Additional Examples</h2>
<fieldset>
<legend>With HTML</legend>
<pre>
jAlert(‘You can use HTML, such as <strong>bold</strong>, <em>italics</em>, and <u>underline</u>!‘);
</pre>
<p>
<input id="alert_button_with_html" type="button" value="http://www.mamicode.com/Show Alert" />
</p>
</fieldset>

<fieldset>
<legend>Alternate Styles</legend>
<p>
By changing the value of the <samp>$.alerts.dialogClass</samp> property (and creating
your own CSS class), you can changes the style of your dialogs:
</p>

<p>
<input id="style_1" class="alert_style_example" type="button" value="http://www.mamicode.com/Style 1" />
</p>

<p>
View the plugin source for additional properties that can be modifed at runtime.
</p>
</fieldset>


<p>
<a href="http://abeautifulsite.net/2008/09/jquery-context-menu-plugin/">Back to the project page</a>
</p>

</body>

</html>


记得导入3个js 和 1个css,可以通过css改变样式

四、开发人员控制面板

Elements:查找网页源代码HTML中的任一元素,手动修改任一元素的属性和样式且能实时在浏览器里面得到反馈。
Console:记录开发者开发过程中的日志信息,且可以作为与JS进行交互的命令行Shell。
Sources:断点调试JS。
Network:从发起网页页面请求Request后分析HTTP请求后得到的各个请求资源信息(包括状态、资源类型、大小、所用时间等),可以根据这个进行网络性能优化。
Timeline:记录并分析在网站的生命周期内所发生的各类事件,以此可以提高网页的运行时间的性能。
Profiles:如果你需要Timeline所能提供的更多信息时,可以尝试一下Profiles,比如记录JS CPU执行时间细节、显示JS对象和相关的DOM节点的内存消耗、记录内存的分配细节。
Application:记录网站加载的所有资源信息,包括存储数据(Local Storage、Session Storage、IndexedDB、Web SQL、Cookies)、缓存数据、字体、图片、脚本、样式表等。
Security:判断当前网页是否安全。
Audits:对当前网页进行网络利用情况、网页性能方面的诊断,并给出一些优化建议。比如列出所有没有用到的CSS文件等。注: 这一篇主要讲解前三个面板Elements、Console、Sources。

五、onclick用法

window.location.replace(“url”):将地址替换成新url,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,你不能通过“前进”和“后 退”来访问已经被替换的URL,这个特点对于做一些过渡页面非常有用!

window.location.reload():强制刷新页面,从服务器重新请求!

 

window.location.href和window.location.replace的区别:

假设有3个jsp页面(1.jsp, 2.jsp, 3.jsp),进系统默认的是1.jsp ,当我进入2.jsp的时候, 2.jsp里面用window.location.replace(“3.jsp”);与用window.location.href(“3.jsp”);从用户界面来看是没有什么区别的,但是当3.jsp页面有一个“返回”按钮,调用window.history.go(-1);wondow.history.back();方法的时候,一点这个返回按钮就要返回2.jsp页面的话,区别就出来了,当用window.location.replace(“3.jsp”);连到3.jsp页面的话,3.jsp页面中的调用window.history.go(-1);wondow.history.back();方法是不好用的,会返回到1.jsp 。当用window.location.href(“3.jsp”);连到3.jsp页面的话,3.jsp页面中的调用window.history.go(-1);wondow.history.back();方法是好用的,会返回2.jsp。因为window.location.replace(“3.jsp”);是不向服务器发送请求的跳转,而window.history.go(-1);wondow.history.back();方法是根据服务器记录的请求决定该跳到哪个页面的,所以会跳到系统默认页面1.jsp 。window.location.href(“3.jsp”);是向服务器发送请求的跳转,window.history.go(-1);wondow.history.back();方法是根据服务器记录的请求决定该跳到哪个页面的,所以就可以返回到2.jsp。 

window.location和window.open区别:

在给按钮、表格、单元格、下拉列表和DIV等做链接时一般都要用Javascript来完成,和做普通链接一样,可能需要让链接页面在当前窗口打开,也可能需要在新窗口打开,这时就可以使用下面两项之一来完成:

window.open 用来打开新窗口

window.location 用来替换当前页,也就是重新定位当前页

可以用以下来个实例来测试一下。

<input type=”button” value=http://www.mamicode.com/”新窗口打开” onclick=”window.open(‘http://www.zhousl.com/’)”>

<input type=”button” value=http://www.mamicode.com/”当前页打开” onclick=”window.location=’http://www.zhousl.com/’”>

window.location.Reload()和window.location.href=http://www.mamicode.com/window.location.href;都是刷新当前页面。

六、分支循环

1、当有多个条件是用 elif 这样就不用那么多缩进

score = int(input(‘输入一个分数‘))
if 100 >= score >= 85:
print(‘A‘)
elif 85 > score >= 60:
print(‘B‘)
elif 60 > score >= 0:
print(‘C‘)
else:
print(‘输入错误! ‘)

2、三元操作符  语法 x if 条件 else y

    small = x if x < y else y  #当if后面的条件为真的时候把x的值赋给small;当条件为假的时候把y的值赋给small

3、断言 assert #当这个关键字后面的条件为假的时候程序自动崩溃,并抛出AssertError。当需要程序中的某个条件一定为真时才能让程序正常运行,assert就非常有用。

>>> assert 3 < 4
>>> assert 3 > 5
Traceback (most recent call last):
File "<pyshell#70>", line 1, in <module>
assert 3 > 5
AssertionError

4、while循环  #在条件为真的时候执行某一段制定的代码,只要条件为真,while循环就会一直去重复执行那一段代码。这段代码就是一个循环体。

5、for循环

①>>> favourite = ‘welcom‘          ②>>>member = [‘QQ‘, ‘QW‘, ‘QR‘]       
   >>> for i in favourite:                 >>>for each in member:
               print(i, end=‘8‘)                         print(eacd, len(each))         #打印each的长度  即QQ有两个字符就打印2    


   w8e8l8c8o8m8                            QQ 2

                                                    QW 2

                                                    QR 2
 6、range语法:range(start, stop, step) 默认step=1 

     ① >>> range(0,5)     

      >>> list(range(5))

      [0, 1, 2, 3, 4]

      ② >>> for i in range(2, 7):    #7是不包含的

                      print(i)


        2
        3
        4
        5
        6

>>> for i in range(1, 10, 4):        #4代表每次步进4,从1开始打印出1-10从1开始每次步进4的数

              print(i)


   1
   5
   9

7、break 终止当前循环并跳出这个循环体  

bingo = ‘猜答案‘
print(‘输入一句话‘)
answer = raw_input()
#print bingo
#print answer
while True:
if answer == bingo:
break
print(‘抱歉输错了,请重新输入才能退出‘)
answer = raw_input() 
print(‘很好额‘)
print(‘答对了‘)

8、continue  当循环条件为True的时候终止本轮循环并开始下一轮循环 ,如果不退的话会跳出循环

for i in range(10):
if i%2 != 0:
print(i)
continue
i += 2
print(i)

显示结果是:
2

1

4

3

6

5

8

7

10

9

 

window.location.Reload()如果有数据提交的话,会提示是否提交的(是和否选项)

window.location.href=http://www.mamicode.com/window.location.href是定向url提交数据

 

最好不要用location.re

 

load(),而用location=location比较好,还有在模式窗口(showModalDialog和showModelessDialog)前者不能用。

 

reload() 方法用于重新加载当前文档。

语法

location.reload(force)说明

如果该方法没有规定参数,或者参数是 false,它就会用 HTTP 头 If-Modified-Since 来检测服务器上的文档是否已改变。如果文档已改变,reload() 会再次下载该文档。如果文档未改变,则该方法将从缓存中装载文档。这与用户单击浏览器的刷新按钮的效果是完全一样的。

如果把该方法的参数设置为 true,那么无论文档的最后修改日期是什么,它都会绕过缓存,从服务器上重新下载该文档。这与用户在单击浏览器的刷新按钮时按住 Shift 健的效果是完全一样。

 

好象是说:

如果window.loacation.reload(true)==window.location.href=http://www.mamicode.com/”xxx.xx”;

 

This entry was posted in js and tagged JQ函数, Js函数. Bookmark the permalink

七、强数据类型

强类型定义语言 

一种总是强制类型定义的语言。Java和Python是强制类型定义的。如果你有一个整数,如果不显示地进行转换,你不能将其视为一个字符串来用
弱类型定义语言
一种类型可以被忽略的语言,与强类型定义相反。VBScript是弱类型定义的。在VBScript中,可以将字符串 ‘12‘ 和整数 3 进行连接得到字符串 ‘123‘,然后可以把它看成整数 123,而不需要显示转换 。

 八、垃圾回收机制

要理解什么是垃圾回收机制,首先要对内存管理概念有一个基本的认识。内存管理是指操作系统如何进行内存的分配和回收的机制。早期的计算机语言,比如C, 它通过malloc, free函数来向操作系统请求
内存和释放内存。 这种机制的优点是内存分配和释放的效率很高。但是它也有着它的缺点,主要表现在对于复杂的系统,存在着大量的内存分配和释放操作。程序员很容易不小心忘记释放内存,从而造成内
存的泄露,对于长期运行的软件来讲,这将是一个致命的威胁,因为系统的内存会逐渐被吃光。 因此,更新的编程语言,比如JAVA, C#, 都提供了所谓“垃圾回收的机制”,运行时自身会运行相应的垃圾
回收机制。程序员只需要申请内存,而不需要关注内存的释放。垃圾回收器(GC)会在适当的时候将已经终止生命周期的变量的内存给释放掉。

GC的优点就在于它大大简化了应用层开发的复杂度,降低了内存泄露的风险
九、闭包
闭包是指可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包” 一词来源于以下两者的
结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)。在PHP、Scala、Scheme、Common Lisp、
Smalltalk、Groovy、JavaScript、Ruby、 Python、Go、Lua、objective c、swift 以及Java(Java8及以上)等语言中都能找到对闭包不同程度的支持。

本质

集合 S 是闭集当且仅当 Cl(S)=S(这里的cl即closure,闭包)。特别的,空集的闭包是空集,X 的闭包是 X。集合的交集的闭包总是集合的闭包的交集的子集(不一定是真子集)。有限多个集合的并集的闭包和这些集合的闭包的并集相等;零个集合的并集为空集,所以这个命题包含了前面的空集的闭包的特殊情况。无限多个集合的并集的闭包不一定等于这些集合的闭包的并集,但前者一定是后者的父集。
若 A 为包含 S 的 X 的子空间,则 S 在 A 中计算得到的闭包等于 A 和 S 在 X 中计算得到的闭包(Cl_A(S) = A ∩ Cl_X(S))的交集。特别的,S在 A 中是稠密的,当且仅当 A 是 Cl_X(S) 的子集。
 

度量空间中的

对欧几里德空间的子集 S,x 是 S 的闭包点,若所有以 x 为中心的开球都包含 S 的点(这个点也可以是 x)。
这个定义可以推广到度量空间 X 的任意子集 S。具体地说,对具有度量 d 的度量空间 X,x 是 S 的闭包点,若对所有 r > 0,存在 y 属于 S,使得距离 d(x,y) < r(同样的,可以是 x = y)。另一种说法可以是,x 是 S 的闭包点,若距离 d(x,S) := inf{d(x,s) : s 属于 S} = 0(这里 inf 表示下确界)。
这个定义也可以推广到拓扑空间,只需要用邻域替代“开球”。设 S 是拓扑空间 X 的子集,则 x 是 S 的闭包点,若所有 x 邻域都包含 S 的点。注意,这个定义并不要求邻域是开的。

极限点

闭包点的定义非常接近极限点的定义。这两个定义之间的差别非常微小但很重要——在极限点的定义中,点 x 的邻域必须包含和 x 不同的集合的点。
因此,所有极限点都是闭包点,但不是所有的闭包点都是极限点。不是极限点的闭包点就是孤点。也就是说,点 x 是孤点,若它是 S 的元素,且存在 x 的邻域,该邻域中除了 x 没有其他的点属于 S。
对给定的集合 S 和点 x,x 是 S 的闭包点,当且仅当 x 属于 S,或 x 是 S 的极限点。
集合的闭包
集合 S 的闭包是所有 S 的闭包点组成的集合。S 的闭包写作 cl(S),Cl(S) 或 S?。

性质

cl(S) 是 S 的闭父集。
cl(S) 是所有包含 S 的闭集的交集。
cl(S) 是包含 S 的最小的闭集。
集合 S 是闭集,当且仅当 S = cl(S)。
若 S 是 T 的子集,则 cl(S) 是 cl(T) 的子集。
若 A 是闭集,则 A 包含 S 当且仅当 A 包含 cl(S)。
有时候,上述第二或第三条性质会被作为拓扑闭包的定义。
在第一可数空间(如度量空间)中,cl(S) 是所有点的收敛数列的所有极限。

举例说明

闭包 (closure)是个精确但又很难解释的电脑名词。在 Perl 里面,闭包是以 匿名函数的形式来实现,具有持续参照位于该函数范围之外的文字式变数值的能力。这些外部的文字变数会神奇地保留它们在闭包函数最初定义时的值 (深连结)。
如果一个程式语言容许函数递回另一个函数的话 (像 Perl 就是),闭包便具有意义。要注意的是,有些语言虽提供匿名函数的功能,但却无法正确处理闭包; Python 这个语言便是一例。如果要想多了解闭包的话,建议你去找本功能性程式 设计的教科书来看。Scheme这个语言不仅支持闭包,更鼓励多加使用。
以下是个典型的产生函数的函数:
sub add_function_generator {
return sub { shift + shift };
}
$add_sub = add_function_generator();
$sum = &$add_sub(4,5); # $sum是 9了
闭包用起来就像是个函数样板,其中保留了一些可以在稍後再填入的空格。add_function_generator() 所递回的匿名函数在技术上来讲并不能算是一个闭包, 因为它没有用到任何位在这个函数范围之外的文字变数。
把上面这个例子和下面这个make_adder()函数对照一下,下面这个函数所递回的匿名函数中使用了一个外部的文字变数。这种指明外部函数的作法需要由 Perl递回一个适当的闭包,因此那个文字变数在匿名函数产生之时的值便永久地被锁进闭包里。
sub make_adder {
my $addpiece = shift;
return sub { shift + $addpiece };
}
$f1 = make_adder(20);
$f2 = make_adder(555);
这样一来&$f1($n) 永远会是 20加上你传进去的值$n ,而&$f2($n) 将 永远会是 555加上你传进去的值$n。$addpiece的值会在闭包中保留下来。
闭包在比较实际的场合中也常用得到,譬如当你想把一些程式码传入一个函数时:
my $line;
timeout(30,sub { $line = <STDIN> });
如果要执行的程式码当初是以字串的形式传入的话,即‘$line = <STDIN>‘ ,那么timeout() 这个假想的函数在回到该函数被呼叫时所在的范围後便无法再撷取$line这个文字变数的值了。
 

语法结构

Groovy的闭包
闭包(Closure)是Java所不具备的语法结构(JAVA8增加了对闭包的支持)。闭包就是一个代码块,用“{ }”包起来。此时,程序代码也就成了数据,可以被一个变量所引用(与C语言的函数指针比较类似)。闭包的最典型的应用是实现回调函数(callback)。Groovy的API大量使用闭包,以实现对外开放。闭包的创建过程很简单,例如:
{ 参数 ->
代码...
}
参考下面的例子代码,定义了c1和c2两个闭包,并对它们进行调用:
def c1 = { println it }
def c2 = { text -> println text }
c1.call("content1") //用call方法调用闭包
c2("content2") //直接调用闭包
“->;”之前的部分为闭包的参数,如果有多个参数,之间可用逗号分割;“->;”之后的部分为闭包内的程序代码。如果省略了“->;”和它之前的部分,此时闭包中代码,可以用名为“it”的变量访问参数。
闭包的返回值和函数的返回值定义方式是一样的:如果有return语句,则返回值是return语句后面的内容;如果没有return语句,则闭包内的最后一行代码就是它的返回值。
 

环境表达

在Javascript中闭包(Closure)
什么是闭包
“官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
相信很少有人能直接看懂这句话,因为他描述的太学术。我想用如何在Javascript中创建一个闭包来告诉你什么是闭包,因为跳过闭包的创建过程直接理解闭包的定义是非常困难的。看下面这段
 

代码

1
2
3
4
5
6
7
8
9
function a(){
var i=0;
function b(){
alert(++i);
}
return b;
}
var c=a();
c();
 

特点

这段代码有两个特点:
1、函数b嵌套在函数a内部;
2、函数a返回函数b。
这样在执行完var c=a( )后,变量c实际上是指向了函数b,再执行c( )后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:
当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。
 

作用

简而言之,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。这是对闭包作用的非常直白的描述,不专业也不严谨,但大概意思就是这样,理解闭包需要循序渐进的过程。
在上面的例子中,由于闭包的存在使得函数a返回后,a中的i始终存在,这样每次执行c(),i都是自加1后alert出i的值。
那 么我们来想象另一种情况,如果a返回的不是函数b,情况就完全不同了。因为a执行完后,b没有被返回给a的外界,只是被a所引用,而此时a也只会被b引 用,因此函数a和b互相引用但又不被外界打扰(被外界引用),函数a和b就会被回收。(关于Javascript的垃圾回收机制将在后面详细介绍)
 

另一个例子

模拟私有变量
function Counter(start){
var count = start;
  return{
  increment:function(){
  count++;
  },
  get:function(){
  return count;
  }
  }
  }
  var foo =Counter(4);
  foo.increment();
  foo.get();// 5
 

结果

这里,Counter 函数返回两个闭包,函数 increment 和函数 get。 这两个函数都维持着 对外部作用域 Counter 的引用,因此总可以访问此作用域内定义的变量 count.
文法
objective c的闭包(block)
objective c 中的的闭包,是通过block实现的。Apple在C,Objective-C和C++中扩充了Block这种文法的,并且在GCC4.2中进行了支持。你可以把它理解为函数指针,匿名函数,闭包,lambda表达式,这里暂且用块对象来表述,因为它们之间还是有些许不同的。
声明一个块
如果以内联方式使用块对象,则无需声明。块对象声明语法与函数指针声明语法相似,但是块对象应使用脱字符(^)而非星号指针 (*)。下面的代码声明一个aBlock变量,它标识一个需传入三个参数并具有float返回值的块。
float (^aBlock)(const int*, int, float);
l 创建一个块
块使用脱字符(^)作为起始标志,使用分号作为结束标志。下面的例子声明一个简单块,并且将其赋给之前声明的block变量(oneFrom)。
int (^oneFrom)(int);
oneFrom = ^(int anInt) {
return anInt - 1;
};

六一笔记