var、let与const

 


变量作用域

  在引入关键字letconst之前,由关键字var声明的变量的作用域只有全局作用域函数作用域,是没有块作用域的。这意味着,变量在声明它们的函数体内以及这个函数体嵌套的其他函数体内都是有定义的。

复制代码
window.onload=test;
function test(o){
    var i=0;                 //i在整个函数体内均是有定义的
    if(typeof o=="object"){
        var j=0;            //j在整个函数体内也是有定义的,若没有进入if语句,那么控制台输出的j将会是undefined,意味着它是有定义但没有初始化的
        for(var k=0;k<10;k++){
            console.log(k);//k在整个函数体内也是有定义的,不仅仅在循环体内
        }
        console.log(k);
    }
    console.log(j);
    console.log(o);//这里可以发现o是Event对象,指的是加载页面这一事件,因此它的类型是“object”,意味着虽然没有传入参数但它也可以进入if语句。
}    
复制代码

声明提前  

  另外,JavaScript有“声明提前(hoisting)”这一特性,函数里var声明的所有变量(但不涉及赋值)都被“提前”至函数顶部。这步操作是在JavaScript 引擎的“预编译”时进行的。值得注意的是,let声明的变量不会在作用域中被“提前”,在let声明之前的执行瞬间被称为“暂时性死区”,在此阶段引用任何后面才声明的变量都会抛出ReferenceError。 而const声明变量时要求必须同时初始化变量,且后面尝试修改const声明的变量会导致运行时错误,可以理解为“常量声明”。

var scope="global"; //定义全局变量
window.onload=test;
function test(){
    console.log(scope); //并不会输出我们以为的"global",因为这里的scope指的是局部变量。由于此时局部变量scope还未初始化,因此会输出undefined。
    var scope = "local";
    console.log(scope);//输出"local"
}

 

面代码便是使用了JavaScript的“声明提前”特性,实际是相当于下面代码:

var scope="global";
window.onload=test;
function test(){
    var scope; //将局部变量scope的声明提前至此
    console.log(scope);
    var scope = "local";
    console.log(scope);
}

 

全局声明

  使用var关键字声明的全局变量,会成为window对象的一个属性,且该属性是不可配置的,无法使用delete删除。与var关键字不同,使用let在全局作用域声明的变量不会成为window对象的属性,但由于该变量的声明是在全局作用域发生的,因此它仍会在页面的生命周期内存续。

var i=0;
let j=1;
console.log(window.i);//输出0
console.log(window.j); //输出undefined
console.log(this.j);//同样输出undefined,这里的this指向window对象
console.log(j); //输出1

 

遗漏的声明

var truevar = 1;
fakevar = 2; //给一个未声明的变量赋值
delete truevar // false,变量没有被删除
delete fakevar //true,变量被删除

  在非严格模式下,给一个未声明的变量赋值也相当于创建一个全局变量,但以这种方式创建的变量是全局对象的可配置属性,可以删除。

 

使用var声明的弊端

  • 使用var关键字声明的变量会作为全局对象window的一个属性添加进去,容易造成属性命名冲突;
  • var声明的变量允许重复声明以及声明提前,容易引起问题;
  • var声明的变量没有块级作用域;
posted @   ˙鲨鱼辣椒ゝ  阅读(36)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示