flash AS3函数闭包代码
“舶夏”投稿了9篇flash AS3函数闭包代码,下面是小编整理后的flash AS3函数闭包代码,希望能帮助到大家!
篇1:flash AS3函数闭包代码
闭包是可以包含自由(未绑定)变量的代码块; 这些变量不是在这个代码块或者任何全局上下文中定义的,而是在定义代码块的环境中定义,
flash AS3函数闭包代码
。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量的存在,相关变量引用没有释放)和为自由变量提供绑定的计算环境(作用域)。在 Scheme、Common Lisp、Smalltalk、Groovy、JavaScript、Ruby 和 Python 等语言中都能找到对闭包不同程度的支持。闭包的价值在于可以作为函数对象或者匿名函数,对于类型系统而言这就意味着不仅要表示数据还要表示代码。支持闭包的多数语言都将函数作为第一级对象,就是说这些函数可以存储到变量中、作为参数传递给其他函数,最重要的是能够被函数动态地创建和返回。
package
{
importflash.display.Sprite;
/**
* ...
* @author ria.args.cn ...
*/
publicclassTest extends Sprite
{
private var array:Array = new Array;
public function Test()
{
for (var i:int = 0; i < 5; i++) {
var object:Object = new Object();
object.num = function():void {
this.number = i;
trace(this.number);
}
array.push(object);
}
}
public function run():void {
for (var i:int = 0; i < array.length; i++) {
array.num();
}
}
}
}
package
{
import flash.display.Sprite;
/**
* ...
* @author ria.args.cn ...
*/
public class RunTest extends Sprite
{
public function RunTest()
{
var t:Test = new Test();
t.run();
}
}
}
先调用setup 方法,在 setup 方法的 for 语句中循环创建对象 obj,并为 obj 创建一个方法 num(),该方法将当前循环的 index 赋值给 obj 的一个属性 n,并 trace 出 n 的值,
将 for 循环生成的对象存到数组 array 中用于在 run 方法中取出。 调用 run 方法,取出 array 中的对象,并调用他们的 num() 方法。 猜猜输出的结果是什么?
结果是: 5 5 5 5 5 并不是期望中的(我期望中的): 0 1 2 3 4
为什么呢? 研究并实验了几下才发现,原来函数闭包虽然可以记录上下文环境的 snapshot ,但却是最近状态的一个 snapshot ,比如上例在 for 循环中,虽然把循环的当前的 i 值赋给了 n ,然而 i 是属于 num() 函数之外的,是 snapshot 中的变量,所以它只记录最近的状态,也就是 for 循环的最后一次,i 等于 5 。输出的就都是 5 了。按照这个原理,你也可以实验一下,把 i 的最后状态改成其他的值,比如
public function setup():void
{
for(var i:int=0;i<5;i++)
{
var obj:Object = {}
obj.num = function():void
{
this.n = i
trace(this.n)
}
array.push(obj)
}
i = 100
}
虽然在 for 循环结束之后才设置的值,不过 i 依然在那个 snapshot 的范围之内,所以输出将会是 5 个 100 。
既然知道了原理,问题解决起来就容易了。只要让 i 不在函数闭包的上下文环境的 snapshot 的范围里就好了。可以这样改写一下:
public var array:Array = []
public function setup():void{
for(var i:int=0;i<5;i++)
{
array.push(createObj(i))
}
}
public function run():void
{
for(var j:int=0;j<5;j++)
{
array[j].num()
}
}
public function createObj(index:int):Object
{
var obj:Object = {}
obj.num = function():void
{
this.n = index
trace(this.n)
}
return obj
}
将创建函数闭包的部分拿到 createObj() 方法中,这样这个 snapshot 只是该函数的上下文环境,不会受到 i 的重复赋值的影响,输出结果也是预期的 0 1 2 3 4
篇2:经典JS闭包面试题
都答对了么?如果都答对了恭喜你在js闭包问题当中几乎没什么可以难住你了;如果没有答案,继续往下分析。
AD:
由工作中演变而来的面试题
这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧。
先看题目代码:
function fun(n,o) {
console.log(o)
return {
fun:function(m){
return fun(m,n);
}
};
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);//undefined,?,?,?
var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined,?,?,?
//问:三行a,b,c的输出分别是什么?
这是一道非常典型的JS闭包问题。其中嵌套了三层fun函数,搞清楚每层fun的函数是那个fun函数尤为重要。
可以先在纸上或其他地方写下你认为的结果,然后展开看看正确答案是什么?
答案
都答对了么?如果都答对了恭喜你在js闭包问题当中几乎没什么可以难住你了;如果没有答案,继续往下分析。
JS中有几种函数
首先,在此之前需要了解的是,在javascript中函数可以分为两种,具名函数(命名函数)和匿名函数。
区分这两种函数的方法非常简单,可以通过输出 fn.name 来判断,有name的就是具名函数,没有name的就是匿名函数
注意:在低版本IE上无法获取具名函数的name,会返回undefined,建议在火狐或是谷歌浏览器上测试
或是采用兼容IE的获取函数name方法来获取函数名称:
/**
* 获取指定函数的函数名称(用于兼容IE)
* @param {Function} fun 任意函数
*/
function getFunctionName(fun) {
if (fun.name !== undefined)
return fun.name;
var ret = fun.toString();
ret = ret.substr('function '.length);
ret = ret.substr(0, ret.indexOf('('));
return ret;
}
遂用上述函数测试是否为匿名函数:
image
可以得知变量fn1是具名函数,fn2是匿名函数
创建函数的几种方式
说完函数的类型,还需要了解javascript中创建函数都有几种创建方法。
1、声明函数
最普通最标准的声明函数方法,包括函数名及函数体。
function fn1(){}
2、创建匿名函数表达式
创建一个变量,这个变量的内容为一个函数
var fn1=function (){}
注意:采用这种方法创建的函数为匿名函数,即没有函数name
var fn1=function (){};
getFunctionName(fn1).length;//0
3、创建具名函数表达式
创建一个变量,内容为一个带有名称的函数
var fn1=function xxcanghai(){};
注意:具名函数表达式的函数名只能在创建函数内部使用
即采用此种方法创建的函数在函数外层只能使用fn1不能使用xxcanghai的函数名。xxcanghai的命名只能在创建的函数内部使用
测试:
var fn1=function xxcanghai(){
console.log(“in:fn1<”,typeof fn1,“>xxcanghai:<”,typeof
xxcanghai,“>”); }; console.log(“out:fn1<”,typeof
fn1,“>xxcanghai:<”,typeof xxcanghai,“>”);
fn1();
//out:fn1< function >xxcanghai:< undefined >
//in:fn1< function >xxcanghai:< function >
可以看到在函数外部(out)无法使用xxcanghai的函数名,为undefined。
注意:在对象内定义函数如var o={ fn : function (){…} },也属于函数表达式
4、Function构造函数
可以给 Function 构造函数传一个函数字符串,返回包含这个字符串命令的函数,此种方法创建的是匿名函数。
image
5、自执行函数
(function(){alert(1);})();
(function fn1(){alert(1);})();
自执行函数属于上述的“函数表达式”,规则相同
6、其他创建函数的方法
当然还有其他创建函数或执行函数的方法,这里不再多说,比如采用 eval , setTimeout , setInterval 等非常用方法,这里不做过多介绍,属于非标准方法,这里不做过多展开
篇3:Javascript闭包简单理解
提到闭包,想必大家都早有耳闻,下面说下我的简单理解,
说实话平时工作中实际手动写闭包的场景并不多,但是项目中用到的第三方框架和组件或多或少用到了闭包。
所以,了解闭包是非常必要的。呵呵...
一、什么是闭包
简而言之,就是能够读取其他函数内部变量的函数。
由于JS变量作用域的特性,外部不能访问内部变量,内部可以外部变量。
二、使用场景
1. 实现私有成员。
2. 保护命名空间,避免污染全局变量。
3. 缓存变量。
先看一个封装的例子:
var person = function {
// 变量作用域为函数内部,外部无法访问
var name = “default”;
return {
getName: function () {
return name;
},
setName: function (newName) {
name = newName;
}
}
}();
console.log(person.name); // 直接访问,结果为:undefined
console.log(person.getName()); // 结果为:default
console.log(person.setName(“langjt”));
console.log(person.getName()); // 结果为:langjt
再看循环中常用闭包解决引用外部变量问题:
var aLi = document.getElementsByTagName('li');
for (var i=0, len=aLi.length; i aLi[i].onclick = function() { alert(i); // 无论点击哪个 元素,弹出的值都为len,表明这里的i和在for之后打印i的值是一样的。 }; } 使用闭包后: var aLi = document.getElementsByTagName('li'); for (var i=0, len=aLi.length; i aLi[i].onclick = (function(i) { return function() { alert(i); // 此时点击 元素,就会弹出对应的下标了。 } })(i); } 三、注意事项 1. 内存泄漏 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题, 比如: function foo() { var Div = document.getElementById(‘J_DIV’); var id = oDiv.id; oDiv.onclick = function() { // alert(oDiv.id); 这里存在循环引用,IE低版本页面关闭后oDiv仍在内存中。所以尽可能缓存基本类型而不是对象。 alert(id); }; Div = null; } 2. 变量命名 如果内部函数的变量和外部函数的变量名相同时,那么内部函数再也无法指向外部函数那个同名的变量。 比如: function foo(num) { return function(num) { console.log(num); } } var f = new foo(9); f(); // undefined 其实上面的用法,专业术语叫函数柯里化(Currying),就是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。本质上也利用了闭包可以缓存的特性,比如: var adder = function(num) { return function(y) { return num+y; }; }; var inc = adder(1); var dec = adder(-1); //inc, dec现在是两个新的函数,作用是将传入的参数值 (+/)1 alert(inc(99));//100 alert(dec(101));//100 alert(adder(100)(2));//102 alert(adder(2)(100));//102 再比如阿里玉伯的seaJS源码中: /** * util-lang.js - The minimal language enhancement */ function isType(type) { return function(obj) { return {}.toString.call(obj) == “[object ” + type + “]” } } var isObject = isType(“Object”); var isString = isType(“String”);
篇4:Python中用函数作为返回值和实现闭包的教程
作者:廖雪峰 字体:[增加 减小] 类型:
这篇文章主要介绍了Python中用函数作为返回值和实现闭包的教程,代码基于Python2.x版本,需要的朋友可以参考下
函数作为返回值
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回,
我们来实现一个可变参数的求和。通常情况下,求和的函数是这样定义的:
def calc_sum(*args): ax = 0 for n in args: ax = ax + n return ax
但是,如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求和的函数!
def lazy_sum(*args): def sum(): ax = 0 for n in args:ax = ax + n return ax return sum
当我们调用lazy_sum()时,返回的并不是求和结果,而是求和函数:
>>> f = lazy_sum(1, 3, 5, 7, 9)>>> f 调用函数f时,才真正计算求和的结果: >>> f()25 在这个例子中,我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。 请再注意一点,当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数: >>> f1 = lazy_sum(1, 3, 5, 7, 9)>>> f2 = lazy_sum(1, 3, 5, 7, 9)>>> f1==f2False f1()和f2()的调用结果互不影响, 闭包 注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。 另一个需要注意的问题是,返回的函数并没有立刻执行,而是直到调用了f()才执行。我们来看一个例子: def count(): fs = [] for i in range(1, 4): def f(): return i*i fs.append(f) return fsf1, f2, f3 = count() 在上面的例子中,每次循环,都创建了一个新的函数,然后,把创建的3个函数都返回了。 你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果是: >>> f1()9>>> f2()9>>> f3()9 全部都是9!原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9。 返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。 如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变: >>> def count():... fs = []... for i in range(1, 4):... def f(j):... def g():... return j*j... return g... fs.append(f(i))... return fs... >>> f1, f2, f3 = count()>>> f1()1>>> f2()4>>> f3()9 缺点是代码较长,可利用lambda函数缩短代码。 本文不谈闭包的概念,因为概念容易把人搞晕,本文希望通过几个鲜活的例子来探究闭包的性质,相信对理解闭包会有所帮助, 程序1 var f = (function { var n = 10; return function() { ++n; console.log(n); } })(); f(); 输出: 11 结论: 闭包函数可以访问外层函数中的变量。 程序2 var arr = []; (function() { var n = 0; for (var i=0; i<3; ++i) { arr[i] = function() { ++n; console.log(n); } } })(); for (var i=0; i<3; ++i) { var f = arr[i]; f(); } 输出: 1 2 3 结论: 一个函数内有多个闭包函数,那么这些闭包函数共享外层函数中的变量。可以看出,例子中3个闭包函数中的n是同一个变量,而不是该变量的3个副本。 程序3 var f0 = function() { ++n; console.log(n); } var f = (function() { var n = 10; return f0; })(); f(); 输出: 错误指向“++n”这一行。 结论: 闭包函数的作用域不是在引用或运行它的时候确定的,看起来好像是在定义它的时候确定的。 说明: 虽然该程序与“程序1”看起来一样,但由于函数f0一个在内部定义一个在外部定义,尽管它们都是从函数内部返回,但在这个例子中f0却无法访问变量n。 程序4 var f = (function() { var n = 10; return new Function('++n;console.log(n);'); })(); f(); 输出同“程序3”: 结论: 该程序是对“程序3”的进一步印证和补充。由该程序可以得出的结论是:闭包函数的作用域是在编译它的时候确定的。 说明: 使用Function构造器可以创建一个function对象,函数体使用一个字符串指定,它可以像普通函数一样执行,并在首次执行时编译。因此,虽然在匿名函数内部定义了此function对象,但一直要到调用它的时候才会编译,即执行到“f()”时,而此时原函数的作用域已经不存在了。 再看一个例子: 程序5 var f = (function() { var n = 10; return eval('(function(){++n;console.log(n);})'); })(); f(); 输出: 11 结论:无 说明: 这个例子是对上面两个程序的补充, 这个例子之所以能够和“程序1”一样打印出11,是因为eval( )函数会立即对传递给它字符串进行解析(编译、执行),因此使用eval定义的函数和直接定义的效果是等价的。 (注意:eval( )中的“function(){...}”必须用括号扩起来,否则会报错) 程序6 var f = (function() { var n = 10; var s = 'hello'; return function() { ++n; console.log(n); } })(); f(); 运行时在“console.log(n);”这一行加个断点,查看作用域中的值,其中只有n没有s: 结论: 外层函数中那些未在闭包函数中使用的变量,对闭包函数是不可见的。在这个例子中,闭包函数没有引用过变量s,因此其作用域中只有n。也就是说,对闭包函数来说,其可以访问的外层函数的变量实际上只是真正的外层函数变量的一个子集。 程序7 这个程序用来通过数据证明“程序6”的结论。程序稍微有点复杂,后面会先对其做简单说明。 var funArr = []; var LENGTH = 500; var ALPHABET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; function getStr( ) { var s = ''; for (var i=0; i s += ALPHABET[Math.floor(Math.random( ) * 62)]; } return s; } function getArr( ) { var a = new Array(LENGTH); for (var i=0; i a[i] = Math.random( ); } } var f = function( ) { var n = 10; var s = getStr( ); var a = getArr( ); funArr.push(function( ) { console.log(n, s, a); // --- 1 console.log(n); // --- 2 }) } for (var i=0; i<; ++i) { f( ); } 程序分析: 本程序的重点是for循环和函数f。for循环中调用了函数f 2000次,每次调用都会创建一个数字和两个长度为500的字符串和数组,所以2000次函数调用所创建的局部变量的规模还是比较可观的,程序用这种方法以便于后面做分析时对结果进行比较。 f中的局部变量会被一个闭包函数所引用,以此观察未被引用的局部变量是否会被回收。 分别运行该程序两次,第一次使用语句1(引用了f中的所有局部变量),第二次使用语句2(只引用了数字变量n)。对运行所得到的结果1和结果2分别采集堆快照(Heap Snapshot): 划分与传递闭包 证明了集合的任意两个划分的和导出的等价关系是这两个划分导出的等价关系的并集的.传递闭包,任意两个划分的积导出的等价关系是这两个划分导出的等价关系的交集. 胡予濮(西安电子科技大学,通信工程学院,陕西,西安,710071)篇5:Javascript闭包的一些研究
篇6:划分与传递闭包
篇7:asp 数据库连接函数代码介绍
以下是SQL连接代码:
复制代码 代码如下:
Function Open_conn
dim Conn,Strconn
set Conn=server.createobject(“adodb.connection”)
Strconn = “Provider = Sqloledb; User ID = 数据库登录帐号; Password = 数据库登录密码; Initial Catalog = 数据库名称; Data Source = (local);”
Conn.open Strconn
set Open_conn=Conn
If Err Then
err.Clear
Conn.close:set Conn=nothing
Response.Write “对不起,数据库连接出错。”
Response.End
End If
End Function
调用方法:
将原来的
复制代码 代码如下:
rs.open sql,conn
改成
复制代码 代码如下:
rs.open sql,Open_conn()
以下是ACCESS连接代码:
复制代码 代码如下:
Function Open_conn()
dim Dbpath,Conn
Dbpath=server.MapPath(“数据库路径”)
set Conn=server.createObject(“ADODB.connection”)
Conn.open “data source=”&dbpath&“;provider=microsoft.Jet.OLEDB.4.0;”
set Open_conn=Conn
If Err Then
err.Clear
Conn.close:set Conn=nothing
Response.Write “对不起,数据库连接出错。”
Response.End
End If
End Function
调用方法:
将原来的
复制代码 代码如下:
rs.open sql,conn
改成
复制代码 代码如下:
rs.open sql,Open_conn()
[asp 数据库连接函数代码介绍]
篇8:闭包算子格及其分配性
闭包算子格及其分配性
基于对闭包运算的性质研究,引入了闭包算子以及同一集合上的闭包算子之间的通常序关系概念,构造出同一集合上的闭包算子关于通常序的.上下确界,使得同一集合上的所有闭包算子关于定义的算子间的通常序构成完备格(闭包算子格).同时证明了闭包算子格不满足分配性.
作 者:崔艳丽 吴洪博 CUI Yan-li WU Hong-bo 作者单位:陕西师范大学数学与信息科学学院,陕西,西安,710062 刊 名:云南师范大学学报(自然科学版) ISTIC英文刊名:JOURNAL OF YUNAN NORMAL UNIVERSITY(NATURAL SCIENCES EDITION) 年,卷(期): 29(6) 分类号:O189.1 关键词:拓扑 闭包算子 完备格 闭包算子格 分配格篇9:简单讲解Python中的闭包
这篇文章主要介绍了Python中的闭包,是Python入门学习中的基础知识,需要的朋友可以参考下
闭包并不是什么新奇的概念,它早在高级语言开始发展的年代就产生了,闭包(Closure)是词法闭包(Lexical Closure)的简称。对闭包的具体定义有很多种说法,这些说法大体可以分为两类:
一种说法认为闭包是符合一定条件的函数,比如参考资源中这样定义闭包:闭包是在其词法上下文中引用了自由变量的函数。
另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。比如参考资源中就有这样的的定义:在实现深约束时,需要创建一个能显式表示引用环境的东西,并将它与相关的子程序捆绑在一起,这样捆绑起来的整体被称为闭包。
就像这样:
#python 中的闭包... def func(data):... count = [data]... def wrap():... count[0] += 1... return count[0]... return wrap... ... a = func(1)>>> a()5: 2>>> a()6: 3 def func(x):... return lambda y :y+x>>> b = func(1)>>> b(1)7: 2>>> b(2)8: 3>>> print b #这里b是个function 在ruby中是proc 简单说,闭包就是根据不同的配置信息得到不同的结果 python实例 看概念总是让人摸不着头脑,看几个python小例子就会了 例1 def make_adder(addend): def adder(augend): return augend + addend return adderp = make_adder(23)q = make_adder(44)print p(100)print q(100) 运行结果: 123144 分析一下: 我们发现,make_adder是一个函数,包括一个参数addend,比较特殊的地方是这个函数里面又定义了一个新函数,这个新函数里面的一个变量正好是外部make_adder的参数.也就是说,外部传递过来的addend参数已经和adder函数绑定到一起了,形成了一个新函数,我们可以把addend看做新函数的一个配置信息,配置信息不同,函数的功能就不一样了,也就是能得到定制之后的函数. 再看看运行结果,我们发现,虽然p和q都是make_adder生成的,但是因为配置参数不同,后面再执行相同参数的函数后得到了不同的结果.这就是闭包. 例2 def hellocounter (name): count=[0] def counter(): count[0]+=1 print ‘Hello,‘,name,‘,‘,str(count[0])+‘ access!‘ return counterhello = hellocounter(‘ma6174‘)hello()hello()hello() 执行结果 Hello, ysisl , 1 access!Hello, ysisl , 2 access!Hello, ysisl , 3 access! 分析一下 这个程序比较有趣,我们可以把这个程序看做统计一个函数调用次数的函数.count[0]可以看做一个计数器,没执行一次hello函数,count[0]的值就加1, 也许你会有疑问:为什么不直接写count而用一个列表?这是python2的一个bug,如果不用列表的话,会报这样一个错误: UnboundLocalError: local variable ‘count‘ referenced before assignment. 什么意思?就是说conut这个变量你没有定义就直接引用了,我不知道这是个什么东西,程序就崩溃了.于是,再python3里面,引入了一个关键字:nonlocal,这个关键字是干什么的?就是告诉python程序,我的这个count变量是再外部定义的,你去外面找吧.然后python就去外层函数找,然后就找到了count=0这个定义和赋值,程序就能正常执行了. python3 代码 def hellocounter (name): count=0 def counter(): nonlocal count count+=1 print ‘Hello,‘,name,‘,‘,str(count[0])+‘ access!‘ return counterhello = hellocounter(‘ma6174‘)hello()hello()hello() 例3 def makebold(fn): def wrapped(): return “” + fn() + “” return wrappeddef makeitalic(fn): def wrapped(): return “” + fn() + “” return wrapped@makebold@makeitalicdef hello(): return “hello world”print hello() 执行结果 hello world 简单分析 怎么样?这个程序熟悉吗?这不是传说的的装饰器吗?对,这就是装饰器,其实,装饰器就是一种闭包,我们再回想一下装饰器的概念:对函数(参数,返回值等)进行加工处理,生成一个功能增强版的一个函数。再看看闭包的概念,这个增强版的函数不就是我们配置之后的函数吗?区别在于,装饰器的参数是一个函数或类,专门对类或函数进行加工处理。 python里面的好多高级功能,比如装饰器,生成器,列表推到,闭包,匿名函数等,开发中用一下,可能会达到事半功倍的效果! 【flash AS3函数闭包代码】相关文章: 2.函数教案 3.函数课件 4.生活函数 5.函数数学教案 8.军训闭营仪式讲话 9.校长闭学式讲话稿 10.小学生闭学式发言稿






文档为doc格式