JavaScript中的变量

本文深入探讨JavaScript中的作用域概念,包括全局与局部执行环境的区别、变量提升现象及其背后的执行原理。通过多个实例,帮助读者理解变量声明、函数声明在JavaScript中的行为表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

懂点编程的都知道,执行环境的类型总共只有两种:全局和局部

var color ="blue";
function changeColor() {
    var num =10;
    console.log(num);
console.log(color);
}
changeColor();


console.log(num);

在这个例子中,color是全局变量,num是局部变量,color能被函数内部访问,但是num不能被外部访问。因此会输出 10 blue 第三句会报错 num is not defined。

我们再来看例子分析 从例子中发现问题,引出原理,解决问题。

var num = 10;
function changeNum() {
    console.log(num);
}
changeNum(); 

毫无疑问,一定输出 10 。函数执行的过程你知道吗?
当执行函数changeNum()的时候,先在函数体内部查找是否有变量num 的声明,如果没有,就往外层去找。本例子中,函数体内部并没有var声明的变量num,因此会找到函数体外面的num。因此最后会输出10。
再来看一个例子

var num = 10;
function changeNum() {
    console.log(num);
    var num = 9;
    console.log(num);

}
changeNum();

在本例子,你猜结果会输出什么?
第一个输出undefined
第二个输出 9
为什么会这样呢? 先来看函数的执行过程,因为要输出num,先来查看函数体内部是否有var 声明的变量num,结果发现,在函数体内第二行有个var num =9;也就是找到了变量num的var声明,这个时候函数是不会再往外层去寻找num了,会把当前的num声明放在函数体内的最顶端,即var num;但是不赋值,故输出undefined。此时,var num =9;也就变成了num=9;故第二个输出会输出9.
上面的例子就是如下:

var num =10;

function changeNum() {
    // 先声明变量num;
    var num;
    console.log(num); // undefined
    // 再赋值
     num = 9;
    console.log(num);// 9
}

函数变量的提升,我在这篇博客javascript变量知识小梳理中有提到过。
因此在这里再啰嗦一遍:
如果在函数体内有变量声明,会将此变量的声明放在函数体内最顶端,只是声明(如var num;),并不赋值。
其实这是js中作用域的问题

深度剖析:
Js中的作用域分析,作用域其实就是起作用的范围。在js中唯一能产生作用域的东西就是函数了,js中没有块级作用域(这个稍后讲解)
• Js中程序在执行中,会先进行一个预解析,分析预解析的过程,即:
 程序在执行过程, 会先将代码读取到内存中检查. 会将所有的声明在此时进行标记. 所谓的标记就是让 js 解释器知道有这个名字, 后面在使用名字的时候, 不会出现未定义的错误. 这个标记过程就是提升.
 声明
变量的声明, 标识符的声明
变量的声明就是让我们的解释器知道有这个名字
变量没有任何数据与之对应,即不先给其赋值
函数的声明
函数声明包含两部分
函数声明与函数表达式有区别, 函数声明是单独写在一个结构中, 不存在任何语句, 逻辑判断等结构中
首先函数声明告诉解释器有这个名字存在. 该阶段与名字声明一样
告诉解释器, 这个名字对应的函数体是什么(函数名和函数体绑定链接)
• 再进行代码执行过程

知道这些,所以变量的提升并不难理解了吧!
刚才有提到函数没有块级作用域的问题,这是什么意思呢?
先上代码,看看

if (true){
    var num = 8;
}
console.log(num);

你猜会num会输出什么? 答案是8.
这里再一个if语句中定义了变量num。如果是在C C++ 或Java中,num会在if语句执行完毕后被销毁。但在JavaScript中,if语句的变量声明会将变量添加到当前的执行环境中(这里是全局环境)中。因此会输出8。在使用for语句时,尤其要牢记这一点。看例子:

for(var i =0;i<10;i++) {
   var str = "你猜会输出什么";
}
console.log(i);

由于js没有块级作用域,由for语句创建的变量i即使在for循环执行结束后,也依旧会存在于循环外部的执行环境中。所以最后会输出10.

来看牛客网上一道题

现有如下html结构





    <ul>
 <li>click me</li>
 <li>click me</li>
 <li>click me</li>
 <li>click me</li>
</ul>
运行如下代码:






        var elements=document.getElementsByTagName('li');
    var length=elements.length;
    for(var i=0;i<length;i++){
        elements[i].onclick=function(){
        alert(i);
    }
 }
依次点击4li标签,哪一个选项是正确的运行结果()?
结果依次弹出  4 4 4 4

Js的块级作用域现在ES6中已经有了定义,其实用闭包也可以实现
ES6的块级作用域:用let为JavaScript新增了块级作用域

for(let i =0;i<10;i++) {
   var str = "你猜会输出什么";
}
console.log(i);
结果会报错 i is not defined
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值