作用域与闭包

作用域与闭包

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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值