搜索
首页web前端js教程javascript的闭包介绍(司徒正美)_javascript技巧

闭包的定义非常晦涩——闭包,是指语法域位于某个特定的区域,具有持续参照(读写)位于该区域内自身范围之外的执行域上的非持久型变量值能力的段落。这些外部执行域的非持久型变量神奇地保留它们在闭包最初定义(或创建)时的值(深连结)。简单来说,闭包就是在另一个作用域中保存了一份它从上一级函数或作用域取得的变量(键值对),而这些键值对是不会随上一级函数的执行完成而销毁。周爱民说得更清楚,闭包就是“属性表”,闭包就是一个数据块,闭包就是一个存放着“Name=Value”的对照表。就这么简单。但是,必须强调,闭包是一个运行期概念。
在Javascript中闭包(Closure),有两个特点:
作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态。
一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
现在比较让人认同的闭包实现有如下三种

复制代码 代码如下:

with(obj){
//这里是对象闭包
}

复制代码 代码如下:

(function(){
//函数闭包
})()

复制代码 代码如下:

try{
//...
} catch(e) {
//catch闭包 但IE里不行
}

几个有用的示例
复制代码 代码如下:

//*************闭包uniqueID*************
uniqueID = (function(){ //这个函数的调用对象保存值
var id = 0; //这是私有恒久的那个值
//外层函数返回一个有权访问恒久值的嵌套的函数
//那就是我们保存在变量uniqueID里的嵌套函数.
return function(){return id++;}; //返回,自加.
})(); //在定义后调用外层函数.
document.writeln(uniqueID()); //0
document.writeln(uniqueID()); //1
document.writeln(uniqueID()); //2
document.writeln(uniqueID()); //3
document.writeln(uniqueID()); //4

复制代码 代码如下:

//*************闭包阶乘*************
var a = (function(n){
if(nif(n==1){ return 1; }
else{ return n * arguments.callee(n-1); }
})(4);
document.writeln(a);

复制代码 代码如下:

function User( properties ) {
//这里一定要声明一个变量来指向当前的instance
var objthis = this;
for ( var i in properties ) {
(function(){
//在闭包内,t每次都是新的,而 properties[i] 的值是for里面的
var t = properties[i];
objthis[ "get" + i ] = function() {return t;};
objthis[ "set" + i ] = function(val) {t = val;};
})();
}
}
//测试代码
var user = new User({
name: "Bob",
age: 44
});
alert( user.getname());
alert( user.getage());
user.setname("Mike");
alert( user.getname());
alert( user.getage());
user.setage( 22 );
alert( user.getname());
alert( user.getage());

附上今天在无忧看到的问题:
要求:
让这三个节点的Onclick事件都能正确的弹出相应的参数。
复制代码 代码如下:


  • aa

  • aa

  • aa





[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

我的解释是,onclick的绑定函数 function(){alert(i)}的作用域为对应li对象,它里面alert的i的作用域为window,每次循环都是在重写window.i的值,因此循环完,i已是4,点击哪一个li元素都是4。
解决方法:
使用函数闭包。
复制代码 代码如下:

var lists = document.getElementsByTagName("li");
for(var i=0,l=lists.length; i lists[i].onclick = (function(i){//保存于外部函函数
return function(){
alert(i);
}
})(i);
}

复制代码 代码如下:

var lists = document.getElementsByTagName("li");
for(var i=0,l=lists.length; i lists[i].onclick = new function(){
var t = i;
return function(){
alert(t+1)
}
}
}


[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

利用事件代理
复制代码 代码如下:

var ul = document.getElementsByTagName("ul")[0];
ul.onclick = function(){
var e = arguments[0] || window.event,
target = e.srcElement ? e.srcElement : e.target;
if(target.nodeName.toLowerCase() == "li"){
alert(target.id.slice(-1))
}
}


[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

将暂时变量保留于元素节点上。
复制代码 代码如下:

var lists = document.getElementsByTagName("li");
for(var i=0,t=0,el; el = list[i++];){
el.i = t++
el.onclick = function(){
alert(this.i)
}
}


[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

使用with语句造成的对象闭包。
复制代码 代码如下:

var els = document.getElementsByTagName("li")
for(var i=0,n=els.length;iwith ({i:i})
els[i].onclick = function() { alert(this.innerHTML+i) };
}


[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

使用try...catch语句构造的异常闭包:
复制代码 代码如下:

var lists = document.getElementsByTagName("li");
for(var i=0,l=lists.length; i try{
throw i;
}catch(i){
lists[i].onclick = function(){
alert(i)
}
}
}


[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

复制代码 代码如下:

var els = document.getElementsByTagName("li");
(''+Array(els.length+1)).replace(/./g,function(a,i){
els[i].onclick=function(){alert(i)}
})
声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
一文浅析Golang中的闭包一文浅析Golang中的闭包Nov 21, 2022 pm 08:36 PM

闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。 换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。 闭包会随着函数的创建而被同时创建。

python闭包有哪些python闭包有哪些Oct 30, 2023 pm 04:53 PM

python闭包主要包括函数闭包和装饰器闭包。详细介绍:1、函数闭包是指在一个函数内部返回另一个函数,并且返回的函数能够访问到其内部变量。这样的返回函数就是函数闭包,函数闭包在程序中可以被反复使用,因此可以用来实现一些功能上的封装;2、装饰器闭包是指在使用装饰器时,被装饰的函数并没有直接被调用,而是被包装在一个函数内部,并返回一个新的函数。这个新的函数就是一个装饰器闭包等等。

如何利用PHP7的匿名函数和闭包实现更加灵活的代码逻辑处理?如何利用PHP7的匿名函数和闭包实现更加灵活的代码逻辑处理?Oct 21, 2023 am 10:21 AM

如何利用PHP7的匿名函数和闭包实现更加灵活的代码逻辑处理?在PHP7之前,我们经常使用函数来封装一段特定的逻辑,然后在代码中调用这些函数来实现特定的功能。然而,有时候我们可能需要在代码中定义一些临时的逻辑块,这些逻辑块没有必要创建一个独立的函数,同时又不想在代码中引入太多的全局变量。PHP7引入了匿名函数和闭包,可以很好地解决这个问题。匿名函数是一种没有名

Python中的闭包是如何实现的?Python中的闭包是如何实现的?Oct 21, 2023 am 10:33 AM

Python中的闭包是如何实现的?闭包是一种函数内部定义的函数,并且在函数内部引用了外部函数的变量。这种特性使得内部函数可以访问外部函数的变量,并且在外部函数执行完毕后,闭包仍然可以访问和操作外部函数的变量。闭包在Python中通过以下几个步骤来实现:定义外部函数,并在其中定义内部函数:首先,我们需要在外部函数内部定义一个内部函数。这个内部函数即是闭包。de

react有哪些闭包react有哪些闭包Oct 27, 2023 pm 03:11 PM

react有事件处理函数、useEffect和useCallback、高阶组件等等闭包。详细介绍:1、事件处理函数闭包:在React中,当我们在组件中定义一个事件处理函数时,该函数会形成一个闭包,可以访问组件作用域内的状态和属性。这样可以在事件处理函数中使用组件的状态和属性,实现交互逻辑;2、useEffect和useCallback中的闭包等等。

如何使用PHP7的匿名函数和闭包实现更加灵活和可复用的代码逻辑?如何使用PHP7的匿名函数和闭包实现更加灵活和可复用的代码逻辑?Oct 24, 2023 am 10:30 AM

如何使用PHP7的匿名函数和闭包实现更加灵活和可复用的代码逻辑?在PHP编程领域中,匿名函数和闭包是非常有价值和强大的工具。PHP7引入了一些新的语言特性,使得使用匿名函数和闭包更加方便和灵活。本文将介绍如何使用PHP7的匿名函数和闭包来实现更加灵活和可复用的代码逻辑,并提供一些具体的代码示例。一、匿名函数匿名函数是一种没有名称的函数。在PHP中,可以将匿名

怎么样减少闭包的产生怎么样减少闭包的产生Oct 27, 2023 pm 04:28 PM

减少闭包产生的方法有避免不必要的闭包、控制闭包的返回值、使用弱引用、减少不必要的全局变量、合理使用循环和递归、使用事件代理、编写单元测试、遵循设计原则和使用工具进行代码分析等。详细介绍:1、避免不必要的闭包,在很多情况下,闭包并非必需的,可以用模块模式来实现私有变量,避免使用闭包;2、控制闭包的返回值,在使用闭包时,应该尽量控制闭包的返回值,如果闭包返回的是基本数据类型等等。

如何解决Python的闭包错误?如何解决Python的闭包错误?Jun 24, 2023 pm 11:23 PM

Python是一种非常流行的编程语言,因为它非常易学易用,同时也具备了强大的功能。其中,闭包是Python中的一种函数,它可以在函数的内部定义另一个函数,并返回这个函数作为函数的返回值。尽管闭包非常方便,但有时会出现某些错误,比如闭包错误。本文将介绍如何解决Python的闭包错误。初步了解闭包在Python中,闭包是由一个内部函数和一个定义在内部函数之外的函

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具