全局变量、局部变量、闭包详解
1.全局变量和局部变量
1.在函数中的局部变量和全局变量重名,局部变量会覆盖全局变量。
2.变量提升: Javascript在执行前会对整个脚本文件的声明部分做完整分析(包括局部变量),先获取所有被声明的变量再逐一执行,所有变量的声明语句都会被提升到当前代码块的头部,但是不能对变量定义做提前解析。 注:代码块指的是function的一个{},通常的if、while、for的{}中变量不会提升。
全局变量的优点:
1.可以减少变量的个数,减少由于实参和形参的数据传递带来的时间消耗。
缺点:
1.全局变量保存在静态存储区,程序开始运行时为其分配内存,程序结束运行时释放其内存。相比较而言生命周期长,且数量较多时,会占用较大的内存。
2.使用全局变量会破坏函数的封闭性和独立性,导致函数的可移植性降低。
3.当一个全局变量多次被不同的语句(函数)操作,全局变量的值容易变得不清晰,这便降低了程序的可读性,不利于在编码后进行调试和查错之类的操作。
局部变量的优点:
1.局部变量是程序动态分配内存的,所以生命周期短,不会造成长时间占用过多内存的情况。
2.局部变量定义在函数内部,限于函数内部调用,故能够有效的保证函数的封闭性。
3.即使在多个函数内部定义了多个同名局部变量,它们之间也不会相互影响。
缺点:
1.局部变量中的数据在函数执行完后就会消失,故不利于数据的保留。
2.局部变量的使用范围有限,仅限于所属函数的内部。
2.闭包
其实就是一个层级关系,假设函数parent里面没有返回函数child,那么,你就访问不到函数child。这就形成了一个闭包。
注意一定要先访问父函数,才能访问到子函数,假设父函数没有执行子函数,也一样访问不到子函数。
子函数继承父函数变量, b2函数里的++i可以获得i的值变为1000, 父函数不可以读取子函数变量。
如果当window通过b1可以直接访问到++i的值了,就说明是闭包了
闭包一般都是必须有return 返回值的
闭包的时候,因为是引用关系,b2执行时,必须要有b1的i变量,而当执行b1函数的时候,是引用关系,所以,这是2个函数中的变量是互相使用的,系统不会删除变量。
所以,闭包的最好的理解就是:函数内部变量(局部变量)可以被外部读取的函数,称为闭包。
循环中的闭包
输出数字 10 十次,当 console.log 被调用的时候,匿名函数保持对外部变量 i 的引用(函数内部的变量都是局部变量,函数执行后,就会被系统删除),此时 for循环已经结束, i 的值被修改成了 10.
输出0到9
外部的匿名函数会立即执行,并把 i 作为它的参数,此时函数内 e 变量就拥有了 i 的一个拷贝。当传递给 setTimeout 的匿名函数执行时,它就拥有了对 e 的引用,而这个值是不会被循环改变的。
使用闭包需要注意以下两点:
1.由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2.闭包会在父函数外部,改变父函数内部变量的值。