var

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

var 语句用于声明一个函数作用域或全局作用域的变量,并且可以选择将其初始化为一个值。

尝试一下

var x = 1;

if (x === 1) {
  var x = 2;

  console.log(x);
  // Expected output: 2
}

console.log(x);
// Expected output: 2

语法

js
var name1;
var name1 = value1;
var name1 = value1, name2 = value2;
var name1, name2 = value2;
var name1 = value1, name2, /* …, */ nameN = valueN;
nameN

要声明的变量的名称。必须是有效的 JavaScript 标识符解构绑定模式

valueN 可选

变量的初始值。可以是任何合法的表达式。默认值为 undefined

描述

var 声明的变量的作用域是最靠近并包含 var 语句的以下花括号闭合语法结构的一个:

如果不是以上这些情况则是:

  • 当前模块,如果代码以模块模式运行
  • 全局作用域,如果代码以脚本模式运行
js
function foo() {
  var x = 1;
  function bar() {
    var y = 2;
    console.log(x); // 1(`bar` 函数闭包中引用了 `x`)
    console.log(y); // 2(`y` 在作用域内)
  }
  bar();
  console.log(x); // 1(`x` 在作用域内)
  console.log(y); // ReferenceError,`y` 的作用域限定在 `bar` 内
}

foo();

重要的是,其他块级结构,包括块语句try...catchswitch 以及其中一个 for 语句的头部,对于 var 并不创建作用域,而在这样的块内部使用 var 声明的变量仍然可以在块外部被引用。

js
for (var a of [1, 2, 3]);
console.log(a); // 3

在脚本中,使用 var 声明的变量将被添加为全局对象的不可配置属性。这意味着它的属性描述符无法被修改,也无法使用 delete 删除。JavaScript 具有自动内存管理机制,因此在全局变量上使用 delete 运算符是没有意义的。

js
"use strict";
var x = 1;
Object.hasOwn(globalThis, "x"); // true
delete globalThis.x; // 在严格模式下,将抛出 TypeError,否则静默失败。
delete x; // 在严格模式下,将抛出 SyntaxError,否则静默失败。

在 NodeJS CommonJS 模块以及原生 ECMAScript 模块中,顶层变量声明的作用域仅限于模块中,而不会作为属性被添加到全局对象中。

var 关键字后面的列表被称为绑定列表,用逗号分隔,其中逗号不是逗号运算符= 号也不是赋值运算符。后续变量的初始化可以引用前面的变量,并获得初始化的值。

提升

var 声明,无论它们出现在脚本中的什么位置,都会在执行脚本中的任何代码之前进行处理。在代码中的任何位置声明变量都相当于在顶部声明它。这也意味着变量可以在其声明之前被使用。这种行为被称为提升,因为变量声明似乎被移动到发生该行为的函数、静态初始化块或脚本源代码的顶部。

备注: var 声明仅提升到当前脚本的顶部。如果在一个 HTML 文件中有两个