//匿名立即调用函数
(function(){//把a,b,f全部隐藏在函数中,外部访问不到,
var a = 5;
var b = 6;
function f(){
alert(a);
}
window.f = f;//为了让外部能够访问,把变量a,b隐藏了防止了变量名冲突。保证内成函数使用的变量仅仅是外层函数包括的变量,防止了变量重名。
})();
f();
//自己的scope属性 == 父级的环境,
//自己的scope属性 == 自己的环境
//闭包:
//函数的嵌套相当于类的继承,函数相当于类,外部函数的变量也是内部函数的,内部函数可以使用,并且变量可以重写(类似于方法的重写)
//作用域链、闭包:函数的嵌套,不是外部类与内部类的关系,是父类与子类的关系,函数是类,内部函数是子类。
//在js层面,只有函数嵌套才会产生闭包。(闭包和全局window对象在浏览器里面都可以查看)。
//闭包的本质是因为js支持作用域链和函数的嵌套。要有函数嵌套才会产生闭包。(词法作用域==静态作用域==闭包)
function f1(){
var a = 10;
var b = 20;
function f2(){//运行在这里的时候就创建了f2的闭包,并且把a,b放在f2的闭包中,所以f2中可以访问a,b.
console.log(a);//可以访问a,b
}
f2();
}
f1(); function f1(){
var a = 10;
var b = 20;
return function f2(){
console.log(a);
}
}
var r = f1();
r();//可以访问a,b,由于f2函数(子类)可以访问外部函数(父类)的变量,所以f2函数(子类)运行的时候就会少传递参数(因为可以直接使用父类的成员,包括父级函数的形参)。 function f1(){
var m = 10;
function f2(){
console.log('a');//f2函数没有用到外部函数的变量,不会产生闭包。
}
f2();
}
f1(); function f1(){
var m = 10;
function f2(){
var n = 20;
function f3(){
console.log(m);//f3不用父级的成员,用父级的父级的成员,会产生闭包
}
}
f2();
}
f1(); ----------------------------------------------------------
不用全局变量,使得调用一个函数多次可以使得一个变量累加。
function add(){
var a= 0;
return function(){
a++;
ALERT(a)
};
}
var f = add();
f();f();f(); //使用闭包注意点:
//捕获的父级的变量只是一个引用,不是复制
function f(){//父类
var num = 1;
function g(){//子类
alert(num);
}
num++;
g();//子类对象执行
}
f();// //
分析闭包的时候,把函数通过小括号f()执行,不当成c++的函数通过地址调用,当成java的匿名对象执行,分析闭包作用域。
父函数每执行一次产生不同的闭包,函数通过地址调用多次,会产生多个独立的作用域,类似于java多个对象产生
function f(){
var num = 1;
return function(){//把子类对象return出去,每return一次都是一个新的对象
num++;
alert(num);
}
}
var r1 = f();
r1();//
r1();// var r2 = f();//2个对象
r2();//
r2();// <div id='1'></div>
<div id='2'></div>
<div id='3'></div>
for(var i = 1;i<3;i++){//js没有块作用域,等价于var i ;声明在for的外面,i是一个全局变量,
var d = document.getElementById(i); //这里的i已经使用了,所以i对应是0,1,2
d.onclick = function(){
alert(i);//每次都是4,可以通过this,这里i没有使用,一直是i,最后使用的时候i是4了,
}
}
//改写,通过闭包(函数嵌套来解决)
for(var i = 1;i<3;i++){
var d = document.getElementById(i);
d.onclick = (function(id){ //匿名函数并且立即执行,这里i使用了所以是0,1,2,
return function(){ //onclick = 3个不同的子类函数对象,3个子类对象的id值不一样
alert(id);
}
})(i); //i作为参数传递给id
}
</script>

d.onclick函数每执行一次就会产生一个独立的闭包,互不影响,闭包类似于一个对象,互不影响。

分析闭包的时候,把函数通过小括号f()执行,不当成c++的函数通过地址调用,当成java的匿名对象产生了,子函数就是子对象,分析闭包作用域。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type=text/javascript charset=utf-8>
var name = "xiao A";
var obj = {
name : "xiao B" ,
getName: function(){
return function(){
return this.name;
}
}
};
var k = obj.getName(); //函数结构体return function(){returnthis.name;},这个函数返回后就是全局window的了。
alert(typeof k); // function类型
alert(k());//xiao A
alert(obj.getName()()); //xiao A ,obj.getName()执行后函数就是window的了, var name = "xiao A";
var obj = {
name : "xiao B" ,
getName: function(){
// this总是指向调用者
var o = this;//this是调用getName的对象
return function(){
return o.name;//o是this,子对象的o永远是父对象的
}
}
};
alert(obj.getName()());
var k = obj.getName();//xiao B
alert(k()); // 闭包:一个函数 可以访问另外一个函数作用域中的变量
// 封闭性 : private 起到一个保护变量的作用
// 1
function f(x){ // 2
var temp = x ; //局部变量 //temp已经没有被使用
return function(x){ // 3 (function 有了一个执行域 var obj)
temp += x ; // 又被使用了
alert(temp);
}
}
var a = f(50); //父类只有一个
alert(a); a(5); //子对象1,55
a(10);//子对象2,65
a(20); //子对象3,85
</script>
</head>
<body>
</body>
</html>

最新文章

  1. 032. asp.netWeb用户控件之一初识用户控件并为其自定义属性
  2. CSS 使用小结
  3. HTML+CSS基础学习笔记(2)
  4. uva 11354 - Bond(树链拆分)
  5. go实现排序的链表
  6. 生成report由Eamil定時寄出
  7. $.ajax()方法详解 jquery
  8. SpringCloud实战-Hystrix请求熔断与服务降级
  9. 【css】一行或者多行文字垂直水平居中
  10. elasticsearch批量修改,批量更新某个字段
  11. 深入源码理解ThreadLocal和ThreadLocalMap
  12. pip 更改国内镜像
  13. day39数据库之基本数据类型
  14. java实现word转pdf在线预览(前端使用PDF.js;后端使用openoffice、aspose)
  15. NULL - AUTO_INCREMENT
  16. 62. Unique Paths不同路径
  17. Round545div2B(1138B)
  18. 为什么使用Reazor
  19. FPGA学习网站
  20. php 内存分配

热门文章

  1. Wow C++11
  2. java9新特性-14-多分辨率图像 API
  3. IIS 7.5 配置
  4. UVa 12661 Funny Car Racing【 dijkstra 】
  5. Ubuntu14.04下tensorflow安装
  6. 安装Debugging Tools时出现错误Setup could not find the file WinSDK_amd64的处理
  7. opencv3.4.1和vs2017配置
  8. Python学习七步走
  9. mac打包python3程序
  10. C++ 输出缓冲区的管理