javascript基础知识:闭包(closure)

(1)
javascript的变量特点:函数内部可以直接读取全局变量,但是在函数外部无法读取函数内部的局部变量。
在函数内部声明变量的时候,一定要使用var命令。如果不用的话,声明的是一个全局变量!

闭包就是有权访问另一个函数作用域内变量的函数
函数能够记住自己定义时所处的作用域的环境
闭包的用途:可以读取函数内部的变量,让这些变量的值始终保持在内存中,不会在调用后被自动清除。
使用闭包的注意事项:
正常的情况下函数调用结束之后函数的执行环境离开环境栈,定义的变量会被垃圾回收机制回收,变量对象会被销毁,内存释放。但是因为闭包的作用,函数的变量有可能再被引用,垃圾收集机制不会将变量废弃,在内存中保留的相应的变量对象。这样就加大了对内存的占用。造成网页的性能问题。解决方法,在退出函数之前,将不使用的局部变量删除。

eg:
function myfuntion(){
  var n=1;
}
alert(n);
//Uncaught ReferenceError: n is not defined(…)
在函数外部,无法读取函数内部的局部变量
funtion outer(){
  var a=1;
  function inner(){
    console.log(a);
  }
  return inner;
}
var innerFunction=outer();
innerFunction();// 1
//函数内部,在定义一个函数。里面可以访问a,outer执行的时候将inner,作为返回值。
//innerFunction(),执行就是inner执行。
eg:
var inner;
function outer(){
  var a = 1;
  var b = 2;
  inner = function(){
    console.log(a);
    console.log(b);
  }
}
outer(); //执行的时候 内部函数赋值给全局的inner
var a = 2;
var b = 3;
inner(); //调用的时候。先去找自己定义时候的作用域 a=1;b=2
console.log(a);
console.log(b);
//1
//2
//2
//3
eg:
function outer(x){
  function inner(y){
    console.log(x + y);
  }
  return inner;
}
var innerFunction = outer(1); //x是1
innerFunction(2); //3 y是2
innerFunction(3); //4 y是3
innerFunction(4); //5 y是4
innerFunction(5); //6 y是5
(2) 重新引用函数的时候闭包是全新的闭包
通过return返回的每一个闭包内的活动对象都是独立的
innerFunction1、innerFunction2中的变量count是独立的,存储在各自的作用域里,互不干涉
function outer(){
  var count = 0;
  function inner(){
    count++;
    console.log(count);
  }
  return inner;
}
var innerFunction1 = outer();
var innerFunction2 = outer();
innerFunction1();
innerFunction1();
innerFunction2();
innerFunction2();
innerFunction1();
innerFunction1();
//1
//2
//1
//2
//3
//4
(3)闭包中this值
函数中this指向调用该函数的对象,若无明确调用对象则指向window对象。
var name="xiao A";
var obj={
  name:"xiao B",
  getName:function(){
    return function(){
      return this.name;
    }
  }
}
alert(obj.getName()());
//xiao A
//obj.getName()执行的时候返回的是一个函数(匿名函数)
//function(){
// return this.name;
//}
//var k=obj.getName()=function(){
// return this.name;
// };
//全局作用域。()执行的话。 this是window
(4)
var name="xiao A";
var obj={
  name:"xiao B",
  getName:function(){
    var o=this;
    return function(){
      return o.name;
    }
  }
}
alert(obj.getName()());
//xiao B
//obj.getName()执行的时候返回的是一个函数(匿名函数)
//function(){
// return o.name;
//}
//var k=obj.getName()=function(){
// return o.name;
// };
//()执行的话。 o就是this是obj
(5):
var name = ‘global‘;
var obj = {
  name : ‘obj‘,
  dose : function(){
    this.name = ‘dose‘;
    return function(){
      return this.name;
    }
  }
}
alert(obj.dose().call(this))
//obj.dose().call(this) call(this)相当于将函数运行环境中的this对象替换成window
//window.name
//‘global‘
(6)
function f(x){
  var temp=x; //局部变量
  return function(x){
    temp+=x;
    alert(temp);
  }
}
var a=f(50);
//a即function(x){
// temp+=x;
// alert(temp);
// }
a(5); //55
a(10); //65
a(20); //85
(7)
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);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1); c.fun(2); c.fun(3);
//undefined 开始的时候fun(0); 没传值,所以o是undefined
//0 n=0;a.fun(1);m=1;fun(m,n); fun(1,0);
//0 同上
//0 同上
//undefined fun(0); 没传值,所以o是undefined n=0
//0 fun(0).fun(1); m=1;fun(m,n);fun(1,0); n=1;
//1 fun(0).fun(1).fun(2); m=2; fun(m,n);fun(2,1); n=2;
//2 同上
//undefined 开始的时候fun(0); 没传值,所以o是undefined
//0 fun(0).fun(1); m=1;fun(m,n);fun(1,0); n=1;
//1 c.fun(2); m=2;n=1;fun(m,n);fun(2,1);
//1 c.fun(3); m=3;n=1;fun(m,n);fun(3,1);
(8)
//for循环执行完后。result被垃圾回收,但是i不会。还有用处
//i = 10;
//funcs = result;
//result = null;
function myfuntion(){
  var result = new Array();
  for (var i=0; i < 10; i++){
    result[i] = function(){
      return i;
    };
  }
  return result;
}
var funcs = myfuntion();
for (var i=0; i < funcs.length; i++){
  console.log(funcs[i]());
}
//输出的是10个10
//函数带()才是执行函数
//result[0] = function(){ return i; };
//...
//result[9] = function(){ return i; }; //没执行函数,函数内部不变i!
//函数内部for循环完了之后i = 10;
//funcs[0]() return i;
(9)解决内存问题
function example(){
  var ele=document.getElementByID("someElement");
  ele.onclick = function() {
    alert("This is a leak!");
  }
  ele= null; //变量设置为null
}
//ele.id 的一个副本保存在一个变量中
function example(){
  var ele= document.getElementById("someElement");
  var id = ele.id;
  ele.onclick = function(){
    alert(id);
  };
  ele = null;
}

垃圾回收机制回收

时间: 2024-11-07 16:05:16

javascript基础知识:闭包(closure)的相关文章

javaScript基础之闭包

不管是Jquery还是EXTJS,现代的js框架中大量应用了js的一些特性,比如:匿名函数,闭包等等,导致源代码非常难以阅读. 不过要想真正的使用好前台的UI技术,还是需要去深入的理解这些概念.   在这里推荐几篇比较好的文章介绍javaScript基础: 当JavaScript从入门到提高前需要注意的细节:闭包部分:http://msdn.microsoft.com/zh-cn/library/hh968324.aspx 学习Javascript闭包(Closure):http://www.r

javascript基础知识拾遗

1 下面列出的值被当作假 false null undefined '' 0 NaN 其它所有值被当作是真 console.log(undefined || true); //true console.log(0||true); //true console.log(''||true); //true console.log(false||true); //true console.log(null||true); //true console.log(NaN||true); //true co

Javascript基础知识5

不要把相等运算符(==)与赋值运算符(=)搞混. 以&&运算符隔开的两个条件中的前者为错,则不会检测第二个条件的真假.利用这一点,可以提高脚本的速度. 使用带switch的多个条件 if(button=="next") window.location = "next.html"; else if(button=="previous") window.location = "pre.html"; else if(

javascript 基础知识

javascript 基础知识编程规范注释 //驼峰对象化编程 数据类型字符串.数字.布尔.数组.对象.Null.Undefined定义 var carname=new String; var x= new Number; var y= new Boolean; var cars= new Array; var person= new Object; 字符串 var word = "Hello World!"; 数字 var x1 = 34.00; //使用小数点来写 var x2 =

JavaScript基础知识梳理--数组

JavaScript基础知识梳理--数组 1.创建方法 空数组:var obj=new Array(); 指定长度数组: var obj=new Array( size ); 指定元素数组 :  var obj=new Array( 元素1,元素2,....): 单位数组:var obj=new Array[ 元素1,元素2,元素3,...,元素N]; 多维数组:var a=new Array( [数组1],[数组2],[数组3],...,[数组N] ); 2.基本操作 存取数组元素: 单维数组

(1)JavaScript基础知识

Javascript基础知识 1.如何使用JavaScript (1).通过<script></script>中直接编写 (2).通过<script src='目标文档的URL'></script>链接外部的Js文件 ① <script  src="URL" type="text/javascript" charset="utf-8"></script> (3).作为某个元素

Javascript基础知识4

字符串大小写转换 toUpperCase()将所有的字符串转换成大写 toLowerCase()将所有的字符串转换成小写 substring(x,y)返回字符串的一部分,从x开始到y结束 charAt(x)获取第x个字符 indexOf("",x)查找字符串, 第一个内容是字符串,第二个是从第x开始 得到的值为这个字符串是从第几个字符开始的 同样lastindexOf()从最后开始查找 split("")分离字符串,内容为以什么分离, 得到的是一个数组 同理,将一个

JavaScript基础知识梳理----正则表达式

JavaScript基础知识梳理----正则表达式 1.创建 方式:---字面量:var 变量名=/表达式/模式修饰符 ---构造函数:var 变量名=new RegExp(“表达式”,“模式修饰符”) 说明: 表达式 单个字符和数字 . 匹配除换行符之外的任意字符 [a-z0-9] 匹配方括号中的任意字符 [^a-z0-9] 匹配不在方括号中的任意字符 \d 匹配数字 \D 匹配非数字 \w 匹配字母 \W 匹配非字母 空白字符 \0 匹配null字符 \b 匹配空格符 \f 匹配进纸符 \n

javascript 基础知识1 数据类型

首先javascript是一种具有面向对象能力的,解释型程序设计语言. js对大小写敏感,一定要采取一致的字符大小写形式,在js中的结束分号(:)是可选的,为了避免JS语句错误,我们还是要注意添加,养成良好的编写习惯. 下面看看数据类型和值. JS有7种数据类型:字符串.数字.布尔.数组.对象.Null.Undefined 字符串类型:由Unicode字符,数字,标点符号组成的序列,可以为多个字符,也可以为0个字符. 1 <script> 2 // var用于声明一个变量 3 var stri

JavaScript基础知识3

JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里 JavaScript基础知识3