JavaScript 自执行函数(闭包)


1. 全局污染

在变量声明的时候有一个规则:重复声明无效
var num = 123;
var num = 'abc';
重复声明的代码不会报任何错误,但是其声明特征就没有了,会转换成普通赋值语句
故,上述代码与下面代码等价
var num = 123;
num = 'abc';
例:




2. 闭包

起因:在函数内部声明的数据,在函数外是不能够直接访问的。
闭包含义:就是包裹、包装的意思。闭表示封闭,即不可访问。
    所谓的闭包就是一个具有封闭的特性,同时具有包裹的特性的一种结构。
    从代码的角度说,所谓的闭包就是函数。
① 函数内声明的变量,外界无法访问,即封闭性。
② 函数本身又是一个封装单位,利用函数可以封装代码,因此一个函数也是一个包裹结构。
因此函数既有包裹的特性,也有封闭的特性,因此可以直接称呼函数为闭包 (closure)
凡是函数要执行,就会分配内存空间以供函数执行
如果函数执行结束,内存会被释放,即可以重复使用
这个定义是有缺陷的。
如果函数内部将数据的引用返回到外部,那么就可以保证数据被一直占用。
function foo(){
    var num = 123;
    function func(){
        return num;
    }
    return func;
}
var f = foo(); 
// f指向func,foo不可以被释放,因为func
// num不能被释放,因为f会返回该数据


3. 所谓的闭包就是函数,其特点是函数内定义的变量,在函数外是无法访问的。

但是闭包需要解决的问题是如何间接的访问到这些数据。
如何访问函数中的数据?
① 最简单的访问方式:返回
function foo(){
var num = 123;
return num;
}
var res1 = foo();
var res2 = foo();
//但两次访问的并不是同一个数据

② 多次访问,f 只允许调用一次
var res1 = foo();
var res2 = res1;

③ 使得函数返回一个函数,利用函数返回数据
function f(){
var num = 123;
return function(){
        //作用域访问规则,是可以访问num的
    return num;
    };
}
var foo = f();//先执行,只调用了一次
var res1 = foo();//获取num的值
var res2 = foo();//访问的是同一个值

将2级链返回到0级链中,利用2级链可以访问1级链的特性,使得0级链间接的访问到1级链。

因此这个数据是不能被销毁的,即不能被释放。

小结:
所谓的闭包,就是一个函数,因为函数中声明的变量,外界无法访问,函数就构成了封闭结构,因此成为闭包。
同时如果需要访问函数中的数据,可以考虑利用函数返回一个函数,使用返回的函数操作函数内的数据,以使得函数外可以通过这个函数内返回的函数,访问内部的数据。



4. 补充:内存释放
在 js 中凡是不被使用的数据,可以被释放


5. 闭包的用法

(1)作为沙箱模式

沙箱:就是一个独立的与外界隔离的运行环境(function)
(function(){
    //此处的代码,对外隔离,外界无法访问,但是可以执行
})();

暴露方式:
var foo = (function(){
function foo(){}
    return foo;
})();

(2)带有缓存功能的函数

var func = (function(){
    //私有数据
    return function foo(){
    };
})();
//func带有私有数据

递归中,为什么性能低?
因为重复的太多了,将已经计算好的存储起来,如果没有计算,就递归,但是算完以后还是存起来。








你可能感兴趣的:(JavaScript)