JavaScript中声明多个变量

409
在JavaScript中,可以像这样声明多个变量:
var variable1 = "Hello, World!";
var variable2 = "Testing...";
var variable3 = 42;

...或者像这样:

var variable1 = "Hello, World!",
    variable2 = "Testing...",
    variable3 = 42;

这两种方法中哪一种更好/更快?


7
关于“更快”的问题,使用 这个 jsperf 我没有看到一种方法比另一种更快。 - Majid Fouladpour
9
让我们来翻译这句话:let one=1,two=2,three=3;将其翻译为中文:定义变量one等于1,变量two等于2,变量three等于3; - Omar bakhsh
22个回答

7

我唯一、但至关重要的使用逗号的场合是在 for 循环中:

for (var i = 0, n = a.length; i < n; i++) {
  var e = a[i];
  console.log(e);
}

我来这里查看JavaScript中是否可以这样做。

即使看到它起作用了,一个问题仍然存在,那就是n是否局限于该函数中。

这证实了n是局部的:

a = [3, 5, 7, 11];
(function l () { for (var i = 0, n = a.length; i < n; i++) {
  var e = a[i];
  console.log(e);
}}) ();
console.log(typeof n == "undefined" ?
  "as expected, n was local" : "oops, n was global");

有一瞬间,我不确定该用哪种语言来交流。

这段内容与IT技术无关,但已按要求进行了翻译。

6

众所周知,这取决于个人偏好和可读性,但我会在本帖中分享想法。

我认为这个问题的答案很大程度上取决于你正在设置什么变量以及它们之间的关系。根据这一点,我尽量保持一致,划分是否相关来确定变量的声明方式。我的偏好通常如下:

对于不相关的变量

我把它们放在同一行,以便稍后轻松移动; 我个人绝不会用其他方法声明不相关的变量:

const unrelatedVar1 = 1;
const unrelatedVar2 = 2;
const unrelatedVar3 = 3;

相关内容(实用工具)

如果我正在创建新的变量,我会将它们声明为一个块 -- 这可以作为属性归属于一起的提示。

const
  x = 1,
  y = 2,
  z = 3
;

// or
const x=1, y=2, z=3;

// or if I'm going to pass these params to other functions/methods
const someCoordinate = {
  x = 1,
  y = 2,
  z = 3
};

这对我来说,感觉更符合解构的一致性:
const {x,y,z} = someCoordinate;

在某些场景下,使用类似于(我不会这样做)的方法可能会显得笨拙。

const x = someCoordiante.x;
const y = someCoordiante.y;
const z = someCoordiante.z;

相关内容(建设)

如果使用相同的构造函数创建多个变量,我通常也会将它们分组在一起;个人认为这样更易读。

而不是像这样做(我通常不这样做

const stooge1 = Person("moe");
const stooge2 = Person("curly");
const stooge3 = Person("larry");

我通常会这样做:

const [stooge1, stooge2, stooge3] = ["moe", "curly", "larry"].map(Person);

我使用“通常”这个词是因为如果输入参数太长而使其难以阅读,我会将它们拆分出来。

我同意其他人关于使用"use strict"的评论。


6
避免使用单语句版本(单个 var )的另一个原因是调试。如果在分配行中的任何一行中抛出异常,则堆栈跟踪仅显示该行。
如果您使用逗号语法定义了10个变量,则无法直接知道哪个变量是罪魁祸首。
单独的语句版本不会遭受这种歧义。

5
我认为这是个人偏好问题。我更喜欢以下方式进行:

   var /* Variables */
            me = this, that = scope,
            temp, tempUri, tempUrl,
            videoId = getQueryString()["id"],
            host = location.protocol + '//' + location.host,
            baseUrl = "localhost",
            str = "Visit W3Schools",
            n = str.search(/w3schools/i),
            x = 5,
            y = 6,
            z = x + y
   /* End Variables */;

5

通过一些简单的格式化,就可以很容易地解决可维护性问题,如下所示:

let
  my_var1 = 'foo',
  my_var2 = 'bar',
  my_var3 = 'baz'
;

我严格地使用这种格式仅仅是出于个人偏好。当然,在单个声明中或者它只是导致问题的时候,我会跳过这种格式。


你的格式化主要是什么?是 let 变量和独立分号的行吗?还是其他什么?它在哪些方面有助于解决可维护性问题?什么是可维护性问题?这些问题并非修辞性问题。最好的回答应该是编辑你的回答,而不是在评论中回复(不要加上“编辑:”、“更新:”或类似的字眼)。 - Peter Mortensen

2
"内聚性优于耦合性"的概念不仅适用于对象/模块/函数,也适用于此情况:第二个示例将所有变量耦合到同一个语句中,这使得将其中一行移动到其他位置时会破坏其他代码(高耦合)。而第一个示例将变量赋值相互独立(低耦合)。根据耦合性的定义,低耦合通常是良好结构化计算机系统和良好设计的标志,与高内聚性相结合,支持高可读性和可维护性的总体目标。因此选择第一个示例。"

1
我没有看出这与耦合或内聚有任何关系。你能详细说明一下吗? - Edson Medina
OP提出的第二个例子将所有变量耦合到同一语句中,这使得无法将其中一行移动到其他地方而不破坏代码(高耦合)。他给出的第一个例子使变量赋值彼此独立(低耦合)。 - Magne
耦合是指不同模块/对象/函数之间的相互依赖关系,而不是代码行数! - Edson Medina
1
最初它是关于模块的,没错,但这个概念可以更普遍地应用,正如您将对象/函数包含在定义中所示。 - Magne

1
我认为,在我们开始使用ES6之前,单个var声明的方法既不好也不坏(如果您有代码检查工具和'use strict')。这真的只是一种口味偏好。但现在对我来说情况发生了变化。以下是我支持多行声明的想法:
1. 现在我们有了两种新类型的变量,而var已经过时了。到处使用const是一个好习惯,直到您真正需要let。因此,您的代码中经常会包含中间带有赋值的变量声明,并且由于块作用域,在进行小的更改时经常会在块之间移动变量。我认为使用多行声明更加方便。
2. ES6语法变得更加多样化,我们获得了解构器、模板字符串、箭头函数和可选赋值。当您大量使用所有这些功能与单个变量声明时,它会影响可读性。

0
一个有 C 语言背景的人肯定会使用第二种方法。
var variable1 = "Hello, World!",
variable2 = "Testing...",
variable3 = 42;

上述方法更像是用C语言编写


0
我们可以使用所有的方法,没有必要只选择其中一种。应用不同的方法可以使代码更易于阅读。
我将展示来自我的Vue.js 3项目之一的真实示例:
示例1
const [store, route] = [useStore(), useRoute()]
        
const    
   showAlert = computed(() => store.getters['utils/show']),
   userIsLogged = computed(() => store.getters['auth/userIsLogged']),
   albumTitle = computed(() => store.getters['albums/title']);

示例2

const    
   store = useStore(),
   username = ref(''),
   website = ref(''),
   about = ref('');

const 
   isAppFirstRender = computed(() => store.getters['utils/isAppFirstRender']),
   showToast = ref(false);

如上所述,我们可以有小块的变量声明。没有必要声明大块的变量。如果我有12个变量,我可以以一种有意义或更易于阅读的方式对它们进行分组,而不需要冗长:

const
  numberOne = 5,
  numberTwo = 10,
  numberThree = 15;

const
  stringOne = 'asd',
  stringTwo = 'asd2',
  stringThree = 'asd3';

let [one, two, three] = [1,2,3]

当然,每个人都有自己的风格。这是我的个人偏好,使用了所有方法的混合。

我个人不喜欢啰嗦。我喜欢只包含必要内容的代码。


0

这是一个非常好的功能,没有理由避免使用。随着技术的发展,我们必须不断进化自己。这个功能在一些语言中已经存在很长时间,比如Perl。例如构建WebGL网格,新的JavaScript风格。

   //initialize vertices with some calculated points
   [verts[ix],     verts[iy],     verts[iz]]     = ps[0];
   [verts[ix + 3], verts[iy + 3], verts[iz + 3]] = ps[1];
   [verts[ix + 6], verts[iy + 6], verts[iz + 6]] = ps[2];
   //initializing normals with cross products
   [norms[ix],     norms[iy],     norms[iz]]     = cr;
   [norms[ix + 3], norms[iy + 3], norms[iz + 3]] = cr;
   [norms[ix + 6], norms[iy + 6], norms[iz + 6]] = cr;

事实上,旧式的代码要比上面这种方式更难调试,更难理解和找到任何错误。这个例子只是简化了很多。大量重复的例程妨碍了真正的逻辑,使代码看起来像某种魔法一样。与上述相同,但是古老的风格:
      //initialize vertices with some calculated points
      verts[ix]     =  ps[0][0];
      verts[iy]     =  ps[0][1];
      verts[iz]     =  ps[0][2];
      verts[ix + 3] =  ps[1][0];
      verts[iy + 3] =  ps[1][1];
      verts[iz + 3] =  ps[1][2];
      verts[ix + 6] =  ps[2][0];
      verts[iy + 6] =  ps[2][1];
      verts[iz + 6] =  ps[2][2];
      //initializing normals with cross products
      norms[ix]     =  cr[0];
      norms[iy]     =  cr[1];
      norms[iz]     =  cr[2];
      norms[ix + 3] =  cr[0];
      norms[iy + 3] =  cr[1];
      norms[iz + 3] =  cr[2];
      norms[ix + 6] =  cr[0];
      norms[iy + 6] =  cr[1];
      norms[iz + 6] =  cr[2];

注意,当我将我的代码迁移到新的风格时,我不仅大量删除了例行代码块,而且还很容易发现了许多代码审查中被忽略的不一致之处,这是因为我使代码更易于可视化、更简洁和逻辑导向,而不是例行导向。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接