原型模式故事链(5)--JS变量做用域、做用域链、闭包

上一章 JS执行上下文、变量提高、函数声明 传送门:https://segmentfault.com/a/11...javascript

本次咱们主要讲讲变量做用域和闭包
变量做用域:
顾名思义:变量起做用的范围。
变量分为全局变量和局部变量。
全局变量:在任何地方都能用,在全部函数以外。
局部变量:只能在定义它的函数中,以及它的子函数中使用。html

当前做用域没有定义的变量,称为自由变量。java

举例子:segmentfault

<!DOCTYPE html>
<html>
<head>
    <title>dsfg</title>
</head>
<body>
<script type="text/javascript">
    var g = 'globle';
    function fn(){
        var p = 'part';    
        console.log(g);//globle
        console.log(p);//part
    }
    fn();
    console.log(g);//globle
    console.log(p);//报错: p is not defined
</script>
</body>
</html>

在上述例子中,g是全局变量,不存在于任何函数中,能在任何地方使用。
p则是局部变量,只能在fn函数中使用。在外部使用则会报错。闭包

做用域链:
函数的变量在寻找做用域时,不看在哪执行,只看在哪定义。异步

举例子:函数

<!DOCTYPE html>
<html>
<head>
    <title>dsfg</title>
</head>
<body>
<script type="text/javascript">
    var a = 100;
    function fn1(){
        var b = 200;
        
        function fn2(){
            var c = 300;
            console.log(a);//100
            console.log(b);//200
            console.log(c);//300
        }
        fn2();
    }
    fn1();
</script>
</body>
</html>

以变量a来解析,上述例子中体现的做用域链。当执行console.log(a)时,先在fn2中寻找变量a,找不到则去到fn2的父级fn1中寻找,也找不到。再到fn1的父级中寻找,也就是全局变量中寻找,终于找到了。像这样一层一层向上查找,就叫变量做用域链。
若是在其中任何一层找到了,则不会继续向上查找。线程

闭包:
下个定义:能够访问另外一个函数做用域变量的函数。因此闭包实际上是个函数。code

为何要用闭包呢?
局部变量没法共享和长久的保存,全局变量则很容易形成变量污染。闭包则能长久保存变量,又不会污染。
闭包特色:占用更多内存,不容易被释放。
闭包使用场景:1.函数做为返回值(retrun 一个函数)htm

2.函数做为参数传递到另外一个函数中。

举例子:

<!DOCTYPE html>
<html>
<head>
    <title>lalala</title>
</head>
<body>
<script type="text/javascript">
    function fn(){
        var a = 100;
        return function(){
            console.log(a);
        }
    }
    var f1 = fn();
    var a = 200;
    f1();//100
</script>
</body>
</html>

1.定义外层函数,封装被保护的局部变量。
2.定义内层函数,执行对外部函数的变量操做。
3.外层函数返回内层函数的对象,且外层函数被调用时,结果保存在一个全局变量中。

执行f1()时,a在当前函数中未定义,往父级查找fn中a=100,因此a=100;
函数变量做用域不看在哪执行,只看在哪定义

好啦好啦,jS三座大山翻过两座了,还剩一个异步,单线程~

相关文章
相关标签/搜索