函数
1.函数命名空间
在js中是无法声明只在一个代码块内可见的变量,基于这个原因我们常常简单地定义一个函数用作临时的命名空间,在这个函数内命名的变量都不会污染到全局命名空间。
function moduleA(){
//代码在这里写
//在这里声明的变量 都是局部变量 不会污染到全局命名空间
}
moduleA( ); //要调用
还可以使用匿名函数(常用写法)
(function( ){
// .to do
}( ))
//注意 : function 左边的括号 是需要的 . 如果不这样写 js 可能会将其解析为一个函数声明
2.作用域链
每一段JavaScript代码(全局代码或函数)都有一个与之关联的作用域链。这个作用域链是一个对象列表或者链表,这组对象定了这段代码‘作用域中’的变量。当javascript需要寻找变量a时 就会从作用域链上的对象按顺序寻找。
- js顶级代码:作用域链由一个全局对象组成。
- 无嵌套函数的函数体内 : 作用域链第一个对象为包含 函数参数,局部变量 的一个对象 , 第二个对象为 全局对象
- 有嵌套函数的函数体内 :最少会有3个对象
function a()
{
var size = 10;
var name = "snake";
function b()
{
var lable = 111;
}
}
//a 函数内声明的变量 对 b 函数都是可见的。但是 b 函数内的变量 对 a 函数是不可见的
3.闭包
抽象概念:函数对象可以通过作用域链相互关联起来,函数体内部的变量都可以保存在函数作用域内,这种特性在计算机科学文献中称为“闭包”。
简单的理解,闭包就是能够读取其他函数内部变量的函数
例子1
function a()
{
var i = 0;
function b()
{
reutrn i++;
}
return b;
}
var c = a(); // 正常情况下 , 在a函数调用完毕返回后 局部变量会被释放掉 。但是这里由于被b引用了,导致释放不了 。(这里也导致了a 也没释放)
c(); // 0
c(); // 1
c(); // 2
例子2
counter 返回了一个对象,包含了2个闭包函数。
c 和 d 都有各自的作用域链,互不影响。也就是说保存了2个局部变量 n
例子3
var name = "this is window";
var object = {
name : "this is object",
getName : function(){
return function(){
return this.name; // 注意 : 严格模式下 这里会报错 this 为 undefined
};
}
};
object.getName()() ; // 'this is window'
函数getName 的作用域链为 : object , 全局对象
函数getName 内的嵌套函数作用域链为 : 包含父函数局部变量和参数的对象 , 全局对象
(这个不知道理解得对不对 , 哈哈哈哈哈)
this 是关键字 , 不是变量
每个函数都有自己的this值 , 嵌套函数是无法访问父函数的 this 值的 , 这个时候可以在外部函数 声明一个变量引用父函数的this , 给嵌套函数使用 :
var self = this;
同理 arguments 参数 也是一样的 . 每个函数都有各自的arguments 值 . 因此如果嵌套函数要访问父函数的arguments 也可以使用以上方法。
var args = arguments
闭包的作用
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。