惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
P
Palo Alto Networks Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy & Cybersecurity Law Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
阮一峰的网络日志
阮一峰的网络日志
Recent Announcements
Recent Announcements
P
Proofpoint News Feed
H
Hacker News: Front Page
H
Help Net Security
云风的 BLOG
云风的 BLOG
H
Heimdal Security Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
L
Lohrmann on Cybersecurity
C
Check Point Blog
Google DeepMind News
Google DeepMind News
Forbes - Security
Forbes - Security
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
I
InfoQ
The GitHub Blog
The GitHub Blog
The Cloudflare Blog
I
Intezer
L
LINUX DO - 最新话题
K
Kaspersky official blog
Attack and Defense Labs
Attack and Defense Labs
C
CERT Recently Published Vulnerability Notes
aimingoo的专栏
aimingoo的专栏
S
SegmentFault 最新的问题
NISL@THU
NISL@THU
人人都是产品经理
人人都是产品经理
雷峰网
雷峰网
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Vercel News
Vercel News
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Threatpost
Y
Y Combinator Blog
S
Security Affairs
Latest news
Latest news
T
Threat Research - Cisco Blogs
T
Tailwind CSS Blog
C
Cisco Blogs
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
P
Privacy International News Feed
Jina AI
Jina AI
Apple Machine Learning Research
Apple Machine Learning Research
Cisco Talos Blog
Cisco Talos Blog
T
Troy Hunt's Blog
S
Securelist
MongoDB | Blog
MongoDB | Blog

博客园 - 绿叶

Suspicions about the new platform dynamic sorting expression builder How to create your own api with ACL in Magento 台服信长之野望全后台辅助外挂 SEO Elite ver 4.0 R93 Patcher Remove 5 seconds constraint in Garena(GGC) - 绿叶 Robot development framework in Mush Client (Lua) 巧用Marshal.GetDelegateForFunctionPointer--C#如何调用按键精灵插件dll Using .Net, Flex, and Red5 to create a flash web application 做了个C#的Hotkey简单封装,希望对大家有帮助 功夫世界外挂发布测试 我的第一个全后台CALL外挂-功夫世界外挂 通过修改Mutex来达到大航海OL多开 如何利用WPE对大航海Online进行港内瞬移,瞬时生产和快速进港 MonoRail PetShop Source Code Released MS PetShop3 -> MonoRail PetShop 完成移植 移植MSPetShop3到Castle MonoRail -Model与DAL层的移植(AR) 圈内Castle文章索引 利用Castle Framework发email是如此easy
对 "闭包-closure" 的一些见解
绿叶 · 2006-04-22 · via 博客园 - 绿叶

今天在群里面瞎谈,就谈到“闭包”上来了,何种语言支持闭包?自己g下吧,其中JavaScript是支持闭包概念的一种语言/脚本(?)。以下是我对他的见解(以javascript举例)。

先了解下在一个对象内如何声明变量,一下以Test对象为例:
Public变量:

function Test()
{
    
this.x = 1;
}

或者

Test.prototype.x = 1;

公共变量简而言之,外界对象可以对公共变量访问,并且公共变量可以在对象的构造函数中声明外,还可以在对象的prototype成员中声明。换句话说,你可以在任何时候添加公共变量(利用prototype)。prototype是一个特别的成员变量,js就是利用这个成员变量的特性来实现继承的。当一个成员被检索且没有在对象中发现的时候,那么它就会从对象构造器的prototype成员中获取他。如果要从外界调用这个对象的方法,或者是通过这个方法操作这个对象里面的所有成员,你可以通过prototype加入:

Test.prototype.Plus = function () {}

Private变量:

function Test()
{
    
var self = this;
    
    
var x = 1;
    
    
function Plus1() {}
    
    
var pPlus = function Plus2() {}
}

私有的变量只能由成员的私有方法或者是特权方法(Privileged,下面讲到)访问,需要注意的是,上面的Plus1()这个方法和pPlus()这个方法是一样的,只是声明的方式不通而已,他们都是私有方法,他和特权变量的声明方法很相似,只是少了个this多了个var,但是他们是不同的,应该特别注意。另外一点是,私有变量是在无法被外界访问的同时,他也不能由对象的公共方法访问。私有方法只是在构造函数内的内部方法。私有变量只能在构造函数中声明。

Privileged变量:

function Test()
{
    
this.pPlus = function () {}
}

什么叫Privileged(特权)变量呢?特权方法可以访问私有方法和私有变量,同时他对外界是可见的。你可以重新声明这个私有方法或者是删除他(重新对这个特权方法赋值,null值表示删除),但是不能改变他。特权变量也只能在构造函数中声明。

好了,对象声明介绍到这里,这些声明模式都是由js的closure(闭包)特性所支持的,下面介绍闭包。

在一个闭包内,你可以暂且(?)理解成在构造函数内,内部函数总是可以访问函数外部的变量和参数的。就算在内部函数return后,闭包内的所有变量都会被保存起来,就好像一个上下文一样。下面我以一个例子说明这个问题,例子来源在群内,由YOK提供(例子已经被修改,只是用来简单说明问题)。

说明:按test按钮输出相加的值,期望值为3。

<html>
    
<body>
        
<input type="button" id="test" value="test" />
        
<script>
function Test (x, y)
{
    
var x = x;
    
var y = y;
}
Test.prototype.add 
= function ()
{
    alert(
this.x + this.y);
}
var t = new Test(12);
document.getElementById('test').onclick 
= t.add;
        
</script>
    
</body>
</html>

运行例子,但是输出"NaN"。这是什么问题呢,我最初调试的时候,以为是this的问题,我原本理解成在add方法中this是指向test按钮(其实this指向window对象),而他不包含x和y的两个变量,所以输出错误。首先,这个理解是正确的,但是你要如何修改才能获取正确的结果呢。我们已经知道,在Test构造函数中,我们声明的x,y是两个私有变量,你不可能在外部访问到,所以必须另觅他路。我们利用特权变量来解决。

<html>
    
<body>
        
<input type="button" id="test" value="test" NAME="test"/>
        
<script>
function Test (x, y)
{
    
var x = x;
    
var y = y;
    
    
this.add = function ()    // 特权变量,可以访问私有变量,又对外公开
    {
        alert(x 
+ y);
    }
}
var t = new Test(12);
document.getElementById('test').onclick 
= t.add;
        
</script>
    
</body>
</html>

上面呈现的是闭包的其中一个特性,下面用来说他的另外一个特性。

<html>
    
<body>
        
<input type="button" id="test" value="test" NAME="test"/>
        
<script>
function Test ()
{
    
var z = 1;
    
    
this.add = function ()
    {
        alert(z
++);
    }
}
var t = new Test();
document.getElementById('test').onclick 
= t.add;
        
</script>
    
</body>
</html>

每次输出,值都会增加1,说明闭包内上下文就算add方法return后都会被保存。

最后说下怎么动态替换行为(这里是按钮click的行为)。

<html>
    
<body>
        
<input type="button" id="test" value="test" NAME="test"/>
        
<script>
function Test ()
{
    
var z = 1;
    
var self = this;
    
var pBtn = null;
    
    
this.selfSubtract = function ()
    {
        z
--;z--;
        alert(z);
        pBtn.onclick 
= self.selfPlus;
    }
    
    
this.selfPlus = function ()
    {
        z
++;
        alert(z);
        pBtn.onclick 
= self.selfSubtract;
    }
    
    
this.getFunction = function (btn)
    {
        pBtn 
= btn;
        
return self.selfSubtract;
    }
}
var t = new Test();
var btn = document.getElementById('test');
btn.onclick 
= t.getFunction(btn);
        
</script>
    
</body>
</html>

以上是我对他的一点见解,closure是js的一个特性而已,我们可以利用这个特性使设计更灵活,其他语言,我google到的好像叫Lua,不知道他是什么,他也支持。由于对js了解不深,请高手斧正确,enjoy it~~~ :)