1. 立即执行函数
就是创建函数的同时立即执行。它没有绑定任何事件,也无需等待任何异步操作:
(function(){
// 主体代码
})()
function(){}是一个匿名函数,包围它的一对小括号将其转换为一个表达式,其后一对括号调用了这个函数。立即执行函数也可以理解为立即调用一个匿名函数。立即执行函数最常见的应用场景就是:将var变量的作用域限制于你们函数内,这样可以避免命名冲突。
2. 闭包
对于闭包(closure),函数嵌套函数,子函数拥有父函数的私有变量,当外部函数返回之后,内部函数依然可以访问外部函数的变量。
function test1() {
var cont = 0; // cont 是test1函数的局部变量
function test2() { // test2是test1函数的内部函数,是闭包
cont += 1; // 内部函数test1中使用了外部函数test1中的变量cont
console.log(cont);
}
return test2;
}
var result = test1();
result(); // 输出1
result(); // 输出2
result(); // 输出3
代码中,js引擎开始扫描代码,并创建全局执行上下文,将1-8行的代码添加到执行栈中,第9行开始外部函数test1被调用并创建函数执行上下文并将其压入执行栈栈顶开始执行其内部代码块此时遇到内部函数test2,开始创建内部函数执行上下文将其压入执行栈栈顶进行执行,执行完毕返回内部函数,销毁其代码,开始执行外部函数,执行完毕销毁代码块并赋值与result变量,结果变量cont 设为0,并将内部函数test2赋值给了变量result。由于外部函数test1已经执行完毕,其代码在内存中被清除,变量cont 设为0存储在闭包作用域内存中,我们每次调用result的时候都会执行其类似test1函数的内部代码包括test2函数,只不过是内存清理器把刚才执行完毕的代码清理了,但因为刚才已经把test1整体及执行结果返回了赋值给了变量result,因此内存保存的是刚才执行过后的结果即cont累加1。每次调用都会执行代码累加,这就是闭包的神奇之处了!这就是为啥他还一直存在,因为有result在调用,只有不在调用,内存垃圾回收器才会回收清理,
(注: 方法内嵌套函数,调用时需要使用变量接收,因为他相当于只是调用执行了外层的函数返回了内部函数,同时代码执行完毕就被内存清理了,也就访问不到私有变量了,用变量接收,相当于吧作用域链及内存指向与该变量,):
3. 利用闭包的特性定义私有变量
其实不应该说利用闭包的特性,应该说js的块级作用域,可以让开发者很好的很安全的编写定义变量初始化数据,因为js规则规定块级作用变量,函数只在{括号内有效},外部不直接访问和改变其内部的值,这涉及到js是原型的链式作用域(查找数据只能由底向上查找)反之不行,这就为啥函数嵌套函数外部函数不能读取子涵数的值而子函数可以引用父函数的变量,
function test() {
var name="";
this.setName = function(value) {
name = value;
};
this.getName = function() {
return name;
};
}
var p = test();
p.setName("xiaoming");
console.log(p.name); // 输出undefined
console.log(p.getName()); // 输出xiaoming
上面代码中可以看出name是test的私有变量,因为有作用域私有保护,如想获取可以在function使用return返回使用变量接收
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
博主灵感丢失其余知识点后续再更新路上!