1. 什么是闭包
闭包就是一个函数, 两个函数彼此嵌套, 内部函数就是闭包。
形成闭包条件是内部函数需要通过return给返回出来.
① 闭包允许我们在全局作用域中访问局部变量
② 闭包可以让局部变量一直驻留在计算机的内存中
<script type="text/javascript">
//简单闭包机制声明
function f1(){
function f2(){
document.write('I am f2');
}
return f2;
}
//如下代码的本质:f2函数对象 对 ff变量进行赋值
//其实引用传递
//执行的结果就是同一个function先后有两个名字进行指引
var ff = f1(); //闭包使用
ff(); //I am f2
</script>
2. 闭包特点
闭包有权利调用其父级环境的变量信息。
<script type = "text/javascript" >
//闭包特点:可以调用父级环境的变量信息
function f1() {
var addr = "中关村";
function f2() {
return '地址:' addr;
}
f2(); //可以视为多余语句
return f2;
}
var ff = f1();
document.write(ff());
</script>
地址:中关村(addr的信息在外部环境被访问出来了)
为什么闭包可以在外部环境调用内部环境的变量
以上代码f2是局部的, ff是全局的
因此可以使得"ff"在外部环境访问function函数
我们在外部环境并没有直接访问addr变量
而是通过ff调用function访问到的
此时addr早早地已经"固化"为function内部"AO的成员"了
因此闭包允许在外部访问内部环境的变量信息
3. 闭包使用规则
同一个闭包机制可以创建多个闭包函数出来, 它们彼此没有联系, 都是独立的。
并且每个闭包可以保存自己个性化的信息。
<script type="text/javascript">
//闭包规则:同一个闭包机制可以生成许多闭包函数
// 并且这些函数彼此独立、没有联系
// 每个函数内部也有保留自己“个性化”的信息
function f1(num){
function f2(){
document.write('数字:' num);
}
return f2;
}
var fa = f1(100); // 生成一个闭包函数
var fb = f1(120); // 生成一个闭包函数
var fc = f1(140); // 生成一个闭包函数
fa(); //数字:100
fc(); //数字:140
fb(); //数字:120
</script>
4. 闭包案例: 闭包生成数组元素
(1) 失败案例:
<script type = "text/javascript">
//闭包 创建数组元素
/*
arr[0]= function(){document.write(0)}
arr[1]= function(){document.write(1)}
arr[2]= function(){document.write(2)}
arr[3]= function(){document.write(3)}
*/
var arr = new Array();
for(var i = 0; i < 4; i ) {
arr[i] = function() {
document.write(i);
}
}
//真实结果 与 期望结果 不一致
//以上for循环执行完毕后会给arr数组赋值4个元素,下标分别为0 1 2 3
//4个元素的值都是function,它们内部访问了同一个i变量,值为4
arr[2](); //4
arr[3](); //4
</script>
(2)成功案例
<script type = "text/javascript" >
//闭包 创建数组元素
/*
arr[0]= function(){document.write(0)}
arr[1]= function(){document.write(1)}
arr[2]= function(){document.write(2)}
arr[3]= function(){document.write(3)}
*/
var arr = new Array();
for(var i = 0; i < 4; i ) {
//arr[i] = 闭包机制;
//在此处通过for循环会依次调用f1()闭包机制, 共调用4次
//也就会创建4个彼此"独立的函数"分别赋予给每个元素, 并且每个函数内部有"个性化"信息供访问
arr[i] = f1(i);
}
function f1(n) {
function f2() {
document.write(n);
}
return f2;
}
arr[2](); //2
arr[3](); //3
arr[0](); //0
arr[1](); //1
</script>
闭包优化:
<script type="text/javascript">
var arr = new Array();
for(var i=0;i<4;i ){
arr[i] = (function(n){
function f2(){
document.write(n);
}
return f2;
})(i);
}
arr[2]();
arr[3]();
</script>
5 闭包事件操作
(1) 失败案例
<ul>
<li>标题一</li>
<li>标题二</li>
<li>标题三</li>
</ul>
<script type="text/javascript">
window.onload = function(){
var lis = document.getElementsByTagName('li');
for(var k=0; k<lis.length; k ){
//给每个li设置mouseover和mouseout事件
//在javascript或jquery里边,在事件处理函数内部的this关键字,
//大部分情况下都代表“元素节点对象”
lis[k].onmouseover = function(){
//this.style.backgroundColor = "lightgray";
lis[k].style.backgroundColor = "lightgreen";
}
lis[k].onmouseout = function(){
//this.style.backgroundColor = "";
lis[k].style.backgroundColor = "";
}
/*
上述事件设置执行失败
每个function内部访问的k不是本身"个性化"信息,而是一个外部变量
该外部变量在for循环执行完毕后永远定格为“3”的信息
因此每个事件触发都是在调用lis[3],因此系统提示没有定义
*/
}
}
</script>
(2) 成功案例
<ul>
<li>标题一</li>
<li>标题二</li>
<li>标题三</li>
<li>标题四</li>
</ul>
<script type="text/javascript">
window.onload = function(){
var lis = document.getElementsByTagName('li');
for(var k=0; k<lis.length; k ){
//给每个li设置mouseover和mouseout事件
//通过over()和out()闭包机制给每个li都设置一个独立的、有个性化信息访问的时间处理函数
lis[k].onmouseover = over(k);
lis[k].onmouseout = out(k);
}
function over(n){
function f2(){
lis[n].style.backgroundColor = "lightblue";
}
return f2;
}
function out(n){
function f2(){
lis[n].style.backgroundColor = "";
}
return f2;
}
}
</script>
进一步优化
<script type="text/javascript">
window.onload = function(){
var lis = document.getElementsByTagName('li');
for(var i=0;i<lis.length;i ){
(function(j){//形参
lis[j].onmouseover = function(){
lis[j].style.backgroundColor = "lightgreen";
}
lis[j].onmouseout = function(){
//this.style.backgroundColor = "";
lis[j].style.backgroundColor = "";
}
})(i);//实参
}
}
</script>
6 闭包优化
window.onload = function(){
var lis = document.getElementsByTagName('li');
for(var i=0; i<lis.length; i ){
lis[i].onclick = clk(i);
function clk(n){
return function (){
alert(lis[n].firstChild.nodeValue);
}
}
}
</script>
以上代码优化为:
<script type = "text/javascript">
window.onload = function() {
var lis = document.getElementsByTagName("li");
for (var i = 0; i < lis.length; i ) {
lis[i].onclick = (function(n) {
return function() {
alert(lis[n].firstChild.nodeValue);
}
})(i);
}
}
</script>
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved