js中var用与不用的区别

本文深入探讨了JavaScript中使用var关键字声明变量与直接对属性赋值之间的区别,解释了变量声明与属性赋值的概念,并通过代码实例展示了两者在作用域上的差异。同时介绍了ECMAScript5标准中的'严格模式',如何防止意外的全局变量属性创造。

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

Javascript声明变量的时候,虽然用var关键字声明和不用关键字声明,很多时候运行并没有问题,但是这两种方式还是有区别的。可以正常运行的代码并不代表是合适的代码。

var num = 1;

是在当前域中声明变量. 如果在方法中声明,则为局部变量(local variable);如果是在全局域中声明,则为全局变量。

而 num = 1;

事实上是对属性赋值操作。首先,它会尝试在当前作用域链(如在方法中声明,则当前作用域链代表全局作用域和方法局部作用域etc。。。)中解析 num; 如果在任何当前作用域链中找到num,则会执行对num属性赋值; 如果没有找到num,它才会在全局对象(即当前作用域链的最顶层对象,如window对象)中创造num属性并赋值。

注意!它并不是声明了一个全局变量,而是创建了一个全局对象的属性。

即便如此,可能你还是很难明白“变量声明”跟“创建对象属性”在这里的区别。事实上,Javascript的变量声明、创建属性以及每个Javascript中的每个属性都有一定的标志说明它们的属性----如只读(ReadOnly)不可枚举(DontEnum)不可删除(DontDelete)等等。

由于变量声明自带不可删除属性,比较var num = 1 跟 num = 1,前者是变量声明,带不可删除属性,因此无法被删除;后者为全局变量的一个属性,因此可以从全局变量中删除


详情看如下代码:
// num1为全局变量,num2为window的一个属性  
                      var num1 = 1; 
                      num2 = 2; 
                      // delete num1;  无法删除 
                      // delete num2;  删除 
                      function model(){ 
                             var num1 = 1; // 本地变量 
                             num2 = 2;     // window的属性 
                             // 匿名函数 
                             (function(){ 
                                    var num = 1; // 本地变量 
                                    num1 = 2; // 继承作用域(闭包) 
                                    num3 = 3; // window的属性 
                             }()) 
                      }
 


PS. 在ECMAScript5标准中,有一种“严格模式”(Strict Mode)。在严格模式中,为未声明的标识符赋值将会抛引用错误,因此可以防止意外的全局变量属性的创造。目前一些浏览器的新版本已经支持。

<think>嗯,用户想了解JavaScript中var和let关键字的区别,特别是作用域和生命周期方面。首先,我得回忆一下自己对这些概念的理解。根据之前学过的知识,var是ES5引入的变量声明方式,而let是ES6新增的。作用域方面,var是函数作用域,而let是块级作用域。这意味着用var声明的变量在函数内部都有效,而let只在最近的{}块内有效。比如在for循环中,用var的话,循环结束后变量仍然存在,但用let的话,变量只在循环体内有效。 生命周期的话,可能涉及到变量提升的问题。var声明的变量会提升到函数或全局作用域的顶部,但赋值会提升,所以变量在声明前访问会得到undefined。而let虽然也有提升,但存在暂时性死区,声明之前访问会报错。这应该也是区别之一。 然后,用户提到的引用中有几个点需要注意。引用[3]提到var的作用域是函数体内部,而let是块级作用域,也就是大括号内。同时,var存在变量提升,而let有暂时性死区。引用[4]指出var可以重复声明,而let行,重复声明会报错。这些都需要在回答中涵盖。 用户的问题可能还隐含着对实际应用场景的关注,比如为什么let更适合循环或者块级作用域的情况。可能需要举例子说明,比如在循环中使用var和let的同表现,或者if语句中的变量作用域差异。 另外,生命周期方面,虽然变量本身的作用域同,但它们的生命周期可能和作用域绑定。var变量的生命周期在函数执行期间存在,而let变量的生命周期仅限于块级作用域执行期间。过具体细节可能需要查证,比如垃圾回收是否在块结束后立即回收,或者是否有其他机制。 还要注意是否需要提到严格模式下的同,或者ES6的其他相关特性,比如const,但用户只问了var和let,所以可以暂时忽略const,除非对比有帮助。 总结一下,回答的结构应该包括:作用域的区别(函数作用域 vs 块级作用域)、变量提升和暂时性死区、重复声明的允许否,以及可能的示例说明。同时引用提供的资料来支持每个点,比如引用[3]和[4]中的内容。最后生成相关问题,帮助用户进一步学习。</think>### JavaScript中varlet关键字的区别 #### 1. **作用域** - **`var`**:具有函数作用域(或全局作用域)。变量在声明它的整个函数内可见,受块级(如`if`、`for`等)限制。 ```javascript function exampleVar() { if (true) { var a = 10; // 在整个函数内可见 } console.log(a); // 输出10 } ``` 引用[^3]:*“局部作用域仅限于函数体内部,而块级作用域是一切大括号内部使用let/const声明的变量”*。 - **`let`**:具有块级作用域。变量仅在声明它的块(如`{}`内部)中有效。 ```javascript function exampleLet() { if (true) { let b = 20; // 仅在if块内可见 } console.log(b); // 报错:b未定义 } ``` #### 2. **变量提升暂时性死区** - **`var`**:存在变量提升,声明会被提升到作用域顶部,但赋值保留原位。声明前访问会得到`undefined`。 ```javascript console.log(c); // 输出undefined var c = 5; ``` 引用:*“var显示变量提升,在声明前可以访问变量,获取的是undefined”*。 - **`let`**:存在暂时性死区(TDZ)。声明前访问会报错,但变量仍会在编译阶段被“绑定”到块作用域。 ```javascript console.log(d); // 报错:未初始化 let d = 15; ``` 引用:*“let隐式变量提升,声明前可访问变量,会报错”*。 #### 3. **重复声明** - **`var`**:允许重复声明同一变量,后声明的值会覆盖前者。 ```javascript var e = 1; var e = 2; // 合法,e最终为2 ``` 引用[^4]:*“var变量能够重复声明,而let变量无法重复声明”*。 - **`let`**:禁止重复声明,同一作用域内重复声明会触发语法错误。 ```javascript let f = 1; let f = 2; // 报错:标识符已声明 ``` #### 4. **生命周期** - **`var`**:生命周期从函数执行开始到结束,即使变量在块内声明。 - **`let`**:生命周期仅限块执行期间,块结束后变量可能被垃圾回收。 --- ### 示例对比 **场景:循环中的变量** ```javascript // 使用var(变量i泄漏到全局) for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i)); // 输出3次3 } // 使用let(每个i独立) for (let j = 0; j < 3; j++) { setTimeout(() => console.log(j)); // 输出0,1,2 } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值