第一单元 闭包、this、作用域
1.1 闭包的概念
在函数内部声明的函数,可以访问函数的局部变量。闭包就是能够读取其他函数内部变量的函数。
有权访问另一个函数作用域中的变量的函数。就是拿到本不该属于他的东西。
作用:闭包可以用在许多地方。它的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,延长生命周期。
1.1.1 变量作用域
一段代码在程序中起作用的范围-就是变量作用域。
变量作用域:局部变量和全局变量
局部变量:在函数内部使用var声明的变量为局部变量,只能在函数内使用
全部变量: 在函数外声明的变量为全局变量或者在函数内部不使用var声明 的变量也是全局变量,作用范围是当前网页,
JS不存在块级作用域,在写for 时注意变量的使用。
在函数外不能读取局部变量
1.1.2 作用域链
概念:在一个函数中嵌套多个函数,当函数访问变量时,就形成了作用域链。
查找顺序:从当前函数开始查找,如果没有找到,向上一级函数开始查找,直到找到为止,如果一直没有找到,则说明该变量未定义。
在函数内部嵌套多个函数,当内部的函数访问某个变量时,从当前函数开始查找,如果没有找到,向上一级函数开始查找,直到找到为止,如果一直没有找到,则说明该变量未定义,这样类似链条,我们叫作用域链。
简言之 ----- 根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问就是作用域链。
1.1.3 闭包的好处和问题
好处:
1.希望一个变量长期驻扎内存
2.避免全局变量的污染
3.私有成员的存在
问题:
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。
1、占内存 (不能及时释放内存)
2、对捕获的变量是引用,不是复制
3、父函数每调用一次,会产生不同的闭包
1.1.4 闭包实现
实现步骤:
1、把一个个功能封装在不同的函数中
2、把所有功能函数封装在一个自运行函数中,同时自运行函数要赋给一个变量,方便外部通过该变量名访问内部的功能。
3、自运行函数末尾一定有 return语句,把各个功能函数以返回值的形式返回给json格式的数据。
注意: 这样内部的函数就可在外部以对象方法的形式调用。
var circle = (function(){
var r = 3; //私有成员,不能被外部访问,但可以被内部子函数调用
function c(){
var result=2Math.PIr;
alert(“周长是:”+result);
}
function s(){
var result=Math.PIrr;
alert(“面积是:”+result);
}
return {
zc:c, //json结构
mj:s
}
})();
circle.zc(); //2
circle.mj(); //3
1.2 垃圾回收机制
1.2.1 标记清除
标记清除:垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,然后,它会去掉环境中的变量的标记和被环境中的变量引用的变量的标记,此后,如果变量再被标记则表示此变量准备被删除。
2008年为止,IE,Firefox,opera,chrome,Safari的javascript****都用使用了该方式;
1.2.2 引用计数
引用计数:跟踪记录每个值被引用的次数,当声明一个变量并将一个引用类型的值赋给该变量时,这个值的引用次数就是1,如果这个值再被赋值给另一个变量,则引用次数加1。相反,如果一个变量脱离了该值的引用,则该值引用次数减1,当次数为0时,就会等待垃圾收集器的回收
注意:除了一些极老版本的IE,目前市面上的JS引擎基本采用标记清除的方式实现垃圾回收。
1.3 this 指向
事件处理程序里面this的指向 ----Window
如果有对象调用事件 – this 指向 当前对象。
return false 的作用是什么?
1、阻止默认事件
2、阻止冒泡
3、退出函数