标签:
闭包:
一. 原理
1. 概念: 所有对象都是一个闭包; 对象是闭包最大的使用; 闭包只能通过函数调用来产生.(理解不太透)
2. 作用: 延长变量的作用域,使变量能够在非自身作用域的其他作用域内被使用.
例子: 函数A里的变量a被函数B引用,当函数A被调用完成后,按常理,函数A的上下文环境就出栈被销毁掉,但是
因为函数B里面引用到了函数A内的变量a(即函数B依赖于函数A中的变量a),且函数B未被执行完,所以函数A的上下文还没有被销毁,当函数B也执行完后,那么此时函数A和B的上下文都被释放掉(即出栈销毁).
3. 自我理解: 闭包就是作用域和上下文环境相互结合来分析一个作用域内的变量到底是存在于哪一个作用域.
二. 闭包的典型示例
1. 函数作为返回值
function fn1(){
var max = 10;
return function (x) {
if(x > max){
console.log(x);
}
}
}
var fn2 = fn1();
fn2(20);
说明: 1.fn1这个函数的返回值为一个匿名函数function;
2. 当调用fn1()时,用一个变量来接收fn1的返回值;
1. 首先创建全局上下文:
fn1 被声明并赋值整个函数块(并确定其内部的匿名函数的自由变量的作用域为fn1作用域;这是自我的理解)
fn2 undefined
2. 执行代码,给fn2赋值(赋的是fn1的函数块);
3. 当读到调用fn1()时,创建fn1这个作用域的上下文环境:
max undefined
4. 执行fn1里面的代码,给max赋值为10, 并把返回值付给fn2;此时fn1已被调用完,按常理应该出栈被销毁,但是因为fn1中的max被fn2引用,所以fn1的上下文还没有被销毁.
5. fn2接收到返回值后,调用fn2,进入fn2这个函数,在执行fn2的函数体之前,创建fn2的上下文环境;
x(参数) 20
arguments [20]
6. fn2执行完后, fn2的上下文被销毁,fn1也被销毁(当fn1里的max被fn2(其他作用域)引用完之后,fn1出栈被销毁).
2. 函数作为参数
var max = 10;
function fn(x){
if(x > max){
console.log(x);
}
}
//匿名函数,最后的(fn)表示调用这个匿名函数
(function(f){
var max = 100;
f(15);
})(fn);
说明: 1.(function(f){ var max = 100;f(15);})(fn); 这句表示一个匿名函数,(fn)表示调用这个匿名函数;
2.首先创建全局上下文环境(注意:这里就确定了fn函数内的自由变量max的作用域为全局的),之后给全局里的变量赋值,然后执行代码,当执行到(fn)时,表示调用对应的匿名函数;
3.进入匿名函数,首先创建匿名函数的上下文环境,之后给匿名函数的作用域里的变量赋值,然后执行里面的代码;
4.当读到f(15),这句时,进入fn函数,首先创建fn函数的上下文环境,之后给fn函数里的变量赋值,然后执行里面的代码;
5.当fn函数执行完后,fn的上下文环境销毁;当匿名函数执行完后,匿名函数的上下文销毁,最后代码执行完毕;
标签:
原文地址:http://www.cnblogs.com/Hrbacity/p/4820659.html