var关键字的用途及使用(或省略)时机

var关键字的用途及使用(或省略)时机

技术背景

在JavaScript中,变量的声明方式会影响其作用域和生命周期。var 关键字是ES6之前用于声明变量的主要方式,理解其用途以及何时使用或省略它对于编写高质量的JavaScript代码至关重要。

实现步骤

全局作用域

在全局作用域中,使用 var 声明变量和不使用 var 直接赋值的区别不大,但存在一些细微差别。例如:

1
2
3
// 这些都是全局变量
var foo = 1;
bar = 2;

函数作用域

在函数内部,var 会创建一个局部变量,而不使用 var 会沿着作用域链查找变量,直到找到该变量或到达全局作用域(此时会创建该变量)。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 这些都是全局变量
var foo = 1;
bar = 2;

function test() {
var foo = 1; // 局部变量
bar = 2; // 全局变量

// 执行一个匿名函数
(function() {
var wibble = 1; // 局部变量
foo = 2; // 继承自上一级作用域(创建一个闭包)
moo = 3; // 全局变量
}())
}

非赋值情况

如果只是声明变量而不进行赋值,必须使用 var。例如:

1
var x; // 声明x

核心代码

示例1:展示局部变量和全局变量的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var local = true;
var global = true;

function test() {
var local = false;
var global = false;
console.log(local);
console.log(global);
}

test();

console.log(local);
console.log(global);

上述代码输出为 false, false, true, true,因为函数内部使用 var 声明的变量是局部变量,与外部变量相互独立。

示例2:不使用 var 时修改全局变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var local = true;
var global = true;

function test() {
local = false;
global = false;
console.log(local);
console.log(global);
}

test();

console.log(local);
console.log(global);

此代码输出为 false, false, false, false,因为不使用 var 时,直接使用并修改了全局变量。

示例3:异步环境下的差异

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 使用 let
function var_fun() {
let array = [];
return new Promise(resolve => resolve()).then(() => {
array.push('text');
return array;
})
}

[1,2,3].forEach(i => {
var_fun().then(result => {console.log(result)});
});

// 不使用 let
function var_fun() {
array = [];
return new Promise(resolve => resolve()).then(() => {
array.push('text');
return array;
})
}

[1,2,3].forEach(i => {
var_fun().then(result => {console.log(result)});
});

在异步环境中,不使用 let 声明变量会导致多个执行器共享同一个全局变量,从而产生意外结果。

最佳实践

  • 始终使用 var 声明变量:避免意外创建全局变量,减少命名冲突和内存泄漏的风险。
  • 优先使用 constlet:在ES6及以后的版本中,constlet 具有块级作用域,能更好地控制变量的作用域和可变性。对于大多数情况,推荐使用 const;如果需要重新赋值,则使用 let

常见问题

无限循环问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
one();

function one() {
for (i = 0; i < 10; i++) {
two();
alert(i);
}
}

function two() {
i = 1;
}
</script>

由于 i 没有使用 var 声明,它是全局变量,在 two 函数中被重置,导致循环无限执行。

变量提升问题

1
2
3
4
5
console.log(noErrorCase);
var noErrorCase = "you will reach that point";

console.log(runTimeError);
runTimeError = "you won't reach that point";

使用 var 声明的变量会被提升到当前作用域的顶部,但赋值不会提升,因此第一个 console.log 输出 undefined;而不使用 var 直接赋值的变量不会被提升,会抛出 ReferenceError


var关键字的用途及使用(或省略)时机
https://119291.xyz/posts/the-purpose-and-usage-of-var-keyword/
作者
ww
发布于
2025年5月29日
许可协议