【JavaScript学习笔记】3:变量作用域

局部变量

在函数体内用var声明的是局部变量,在函数结束即销毁:

<!DOCTYPE HTML>
<HTML>
<BODY>
</BODY>
<HEAD>
    <meta charset="utf-8">
    <script>
        //console.log(x); //函数外不可见
        myfun(); //函数执行
        //console.log(x); //函数外不可见
        /*函数声明*/
        function myfun(){
            var x=10;
            console.log(x);
        }
    </script>
</HEAD>
</HTML>

输出

10

在函数体外尝试输出函数内定义的局部变量x会报错。

全局变量

首先,在函数体外声明使用的变量一定是全局变量,在页面关闭时才销毁:

<!DOCTYPE HTML>
<HTML>
<BODY>
</BODY>
<HEAD>
    <meta charset="utf-8">
    <script>
        var y=20; //全局变量
        console.log('y='+y);
        myfun(); //调用函数
        function myfun(){
            var x=10; //局部变量
            console.log('x='+x);
            console.log('y='+y);
        }
    </script>
</HEAD>
</HTML>

输出

y=20
x=10
y=20

其次,没有使用var声明就直接使用的变量,不论在哪里都被视为全局变量:

<!DOCTYPE HTML>
<HTML>
<BODY>
</BODY>
<HEAD>
    <meta charset="utf-8">
    <script>
        //console.log('y='+y); //函数调用之前这个变量还是不存在的
        myfun(); //调用函数
        console.log('y='+y); //函数调用以后全局变量y就存在了
        function myfun(){
            var x=10; //局部变量
            y=20; // 全局变量
            console.log('x='+x);
            console.log('y='+y);
        }
    </script>
</HEAD>
</HTML>

输出

x=10
y=20
y=20

全局变量都是window的成员变量,所以上面的全局变量y其实也就是window.y

块级变量

let声明的块级变量只能在其声明的最小子块中使用,而不会去操作块外的同名变量。如果let不是在语句块里声明的,那么声明出来的变量作用域是全局的,但却并不是window的成员变量:

<!DOCTYPE HTML>
<HTML>
<BODY>
    <p id='ok'></p>
</BODY>
<HEAD>
    <meta charset="utf-8">
    <script>
        "use strict"; //目前在严格模式下才能用ES6的let声明和使用块级变量
        let x=0; //这个块级变量x作用域是全局的
        //var x=0; //实实在在的全局变量
        myfun(); //调用函数
        function myfun(){
            let x=10; //只在myfun()里有效
            //var x=10; //实实在在的局部变量
            if(1===1){
                let x=20; //只在这个if里有效
                console.log(x); //输出这个if里的块级变量x看一下
            }
            console.log(x); //输出myfun()里的块级变量x看一下
        }
        console.log(window.x); //尝试访问window下的变量x
        console.log(x); //访问全局作用域的块级变量x
    </script>
</HEAD>
</HTML>

输出

20
10
undefined
0

一些有意思的现象

在声明块级变量后,又声明局部变量,会和这个块级变量冲突:

"use strict";
myfun();
function myfun(){
    let x=10; //块级变量
    if(1===1){
        var x=20; //尝试声明局部变量
        console.log(x);
    }
    console.log(x);
}

报错

Uncaught SyntaxError: Identifier 'x' has already been declared

如果是声明了局部变量之后,再声明并初始化一次,那么会覆盖掉前面的那个局部变量的值:

"use strict";
myfun();
function myfun(){
    var x=10; //局部变量
    if(1===1){
        var x=20; //尝试重新初始化局部变量
        console.log(x);
    }
    console.log(x);
}

输出

20
20

但是如果仅仅是重复声明,是不会改变这个局部变量的值的:

"use strict";
myfun();
function myfun(){
    var x=10; //局部变量
    if(1===1){
        var x; //尝试重新声明局部变量,不初始化
        console.log(x);
    }
    console.log(x);
}

输出

10
10

所以可以把初始化看成声明+赋值的过程(难道js里不分初始化记号和赋值号这样的说法吗),即对局部变量的重复声明无效,但是不报错:

"use strict";
myfun();
function myfun(){
    var x=10; //局部变量
    if(1===1){
        var x; //尝试重新声明局部变量,不初始化
        console.log(x+3);
    }
    console.log(x-3);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值