作用域与闭包

来源:互联网 发布:sqlserver 字符串截取 编辑:程序博客网 时间:2024/05/17 09:34

作用域与闭包

1.作用域

几种常常容易误解的例子

<script type="text/javascript">    alert(a);   // undefined   声明提前    var a = 20;  </script>//所有的全局变量的声明都会提前到JavaScript的前端声明。也就是所有的全局变量都是先声明的,并且早于其他一切代码。但是变量的赋值的位置并不会变,仍然在原位置赋值//以上代码等同于<script type="text/javascript">   var a; //声明提前    alert(a);       a = 20;  //赋值仍在原来的位置</script>--------------------------------------------------------var a=10;    if(a>20){        var b=20;    }    console.log(b);   //undefined  声明提前,不然就会报错*/--------------------------------------------------------------------------------------------var a = 10;    function foo(){        cnosole.log(a);   //访问的是局部变量,声明提前        var a = 20;    }    foo();   //undefined--------------------------------------------------------------------------------------------    var a = 10;    function foo(){        console.log(a);    //10        a = 20;        console.log(a);    //20    }    foo();   --------------------------------------------------------------------------------------------    console.log(a);   //报错    console.log(typeof a)  //undifined,虽然没有声明    function foo(){        a = 20;    }    foo();    //执行后,没有定义的a会自动变成全局变量    console.log(a);    //访问全局变量 结果为undefined--------------------------------------------------------------------------------------------

2.闭包

闭包

广义的闭包:

一个函数访问了它外部的变量

狭义的闭包:

如果一个函数,访问了它的外部变量函数的局部变量,那么这个函数就是一个闭包

闭包的特点:

闭包可以访问它的外部函数作用域内的任何的变量,而且访问到的变量的值一定是最新的值,

即使外部函数执行结束,也仍然可以访问外部函数的局部变量

var a =10;    function foo(){        var a =20;        function inner(){            console.log(a);        }        a =30;        return inner;    }    var f = foo();    f();               //30

使用闭包封装对象

function foo(){        var p = {                //将对象放入函数中,使得对象无法被更改            name : "Tom",            age : 22        }        return {            getName : function(){                return p.name;            },            getAge : function(){                return p.age;            },            setName : function(name){                return p.name = name;            },            addAttr : function(key,value){                return p[key] = value;            }           }    }    var f = foo();    f.getName()  //"Tom"

for循环的经典问题

<!doctype html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title></head><body>    <button>按钮1</button>    <button>按钮2</button>    <button>按钮3</button>    <script type="text/javascript">    var btns = document.querySelectorAll("button");//解决方案一:匿名函数的自调用    for (var i=0; i<btns.length; i++){        // 匿名函数自调用        btns[i].onclick = (function(i){                    return function(){                        alert(i);                    }        })(i)//解决方案二: 利用属性存储i的值        btns[i].index = i;        btns[i].onclick = function(){            alert(this.index);        }    }//解决方案三:利用ES6的新方法,let    for (let i=0; i<btns.length; i++){        btns[i].onclick = function(){            alert(i);        }    }    </script></body></html>
原创粉丝点击