ChatGPT解决这个技术问题 Extra ChatGPT

在 JavaScript 中声明多个变量

在 JavaScript 中,可以像这样声明多个变量:

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

...或者像这样:

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

一种方法比另一种更好/更快吗?

至于 faster,使用 this jsperf 我无法看到使用一种方法或另一种方法获得一致的速度增益。
let one=1,tow=2,three=3;

K
Kate Orlova

第一种方式更容易维护。每个声明都是一行中的单个语句,因此您可以轻松地添加、删除和重新排序声明。

使用第二种方式,删除第一个或最后一个声明很烦人,因为它们分别从 var 关键字开始并以分号结束。每次添加新声明时,都必须将最后一个旧行中的分号替换为逗号。


如果您正在编写您希望稍后压缩或打包的代码,则第二种方式允许压缩器(如 YUI 压缩器)为您提供更压缩的版本。如果大小是一个考虑因素,那么我建议尽可能多地遵循 JSLint 的建议。
jslint 声称第二种方式更正确,但我不同意。
第二种方式是微优化。所有的 var 声明都是一次处理的,而不是一次处理一个。这在现代浏览器/现代计算机中并不重要。
@0xc0de:我希望看到在一个语句中声明所有变量为“有效”的证明。如果您仅根据节省的几个字节来衡量效率,那么也许可以。但是如果你考虑到可读性和可维护性,我想你会发现过早的优化通常是错误的方法,特别是因为现代浏览器会在预执行过程中收集和初始化作用域中的所有变量。就个人而言,我发现将所有变量都声明在一行或一条语句中,以使快速理解代码变得更加困难且更容易出错。
关于效率,uglifyjs 和 google 闭包编译器都会自动将连续的 var 语句压缩为一个,从而使这一点变得毫无意义(据我所知,YUI 不会这样做,但我没有进行广泛的测试)。
P
Peter Mortensen

除了可维护性之外,第一种方法消除了意外创建全局变量的可能性:

(function () {
var variable1 = "Hello, World!" // Semicolon is missed out accidentally
var variable2 = "Testing..."; // Still a local variable
var variable3 = 42;
}());

虽然第二种方式不那么宽容:

(function () {
var variable1 = "Hello, World!" // Comma is missed out accidentally
    variable2 = "Testing...", // Becomes a global variable
    variable3 = 42; // A global variable as well
}());

好点子。如果它们很短,那么写在一行上可以避免这个问题:var variable1 = "Hello World!", variable2 = "Testing...", variable3 = 42;。缺少的 , 会崩溃,但我同意这样做有风险
如果您使用的是严格模式,则无论如何都无法创建这样的全局变量。
我喜欢在一行上声明多个变量,因为我认为它看起来更干净。也就是说,意外声明全局变量是一个真正的危险。在寻找内存泄漏时,我遇到了多个实例,我不小心一次声明了多个全局变量,因为我使用了分号而不是逗号。
如果我错过了昏迷,我的文本编辑器会给我一个 Possible Fatal Error,为我欢呼!
J
Jason Stackhouse

这样做时它更具可读性:

var hey = 23;
var hi = 3;
var howdy 4;

但是这样占用更少的空间和代码行:

var hey=23,hi=3,howdy=4;

它可以是节省空间的理想选择,但让 JavaScript 压缩器为您处理它。


s
spencer.sm

通常使用 one var statement per scope 进行组织。所有“范围”的方式都遵循类似的模式,使代码更具可读性。此外,无论如何,发动机都会将它们全部“提升”到顶部。因此,将您的声明放在一起可以更紧密地模仿实际发生的事情。


您可以将声明放在一起,而不会使它们共享相同的“var”声明。我理解并接受 jslint(你的链接)给出的解释,但我不同意这个结论。如上所述,风格比其他任何事情都重要。在 Java 世界(以及其他)中,为了可读性,建议使用相反的(每行一个声明)。
更具可读性?人们将它们放在一行的唯一原因是您提到的特定于 JS 的原因:JS 将所有声明移到顶部。如果它不这样做,我们都将声明我们的变量最接近它们的使用点。
G
General Grievance

ECMAScript 2015 介绍了 destructuring assignment,效果很好:

[a, b] = [1, 2]

a 将等于 1b 将等于 2


它没有回答这个问题,但它可以成为两种描述方法的更好选择。
如果您有很长的变量列表,我认为您的方法实际上并不可行。很难说哪个变量与哪个值相关,而且您没有防止错误的保护是错误合并的情况,在此期间您可能会不小心从数组中删除一个元素。示例:let [aVar, bVar, cVar, xVar, yVar, zVar] = [10, 20, 30, 40, 50]; 所以,我个人不推荐它。
如果您想设置许多具有相同值的变量,则很方便。例如,用于在循环中重置为零。
是的!这就是我要找的。特别是如果您想定义一个二维对或多维值,而不是数组。
B
Brian Campbell

这只是个人喜好问题。这两种方式之间没有区别,除了如果去掉空格,第二种形式会保存几个字节。


第二个节省了几个字节。
如果去掉空格,则 'var foo="hello",bar="world";'声明占用的字符少于 'var foo="hello";var bar="world";'如果您有一个受欢迎的网站,在 JS 上保存几个字节会有所帮助(您还希望最小化变量名等)
由于 JavaScript minifiers 的兴起,特别是 Google Closer Compiler 的(所谓的)简单模式,我认为此时保存的字节无关紧要。
这是一个不正确的陈述——运行时引擎处理它们的方式有所不同(至少在旧浏览器中,不确定现代浏览器)。我可以发誓我用 Zakas 的高性能 Javascript 阅读它,但我现在很难找到它。当我得到它时,我会睁大眼睛并用参考来检查。无论如何,这并不是一个主要的区别——只是我记得的一个性能(以及一个微小的微观性能差异)。
@webnesto 当语法的语义相同时,语法永远不会有任何性能。一个人不会立即执行代码,而是首先对其进行解析并进行语义分析——这是两种声明风格均等的地方。
P
Peter Mortensen

也许像这样

var variable1 = "Hello, World!"
, variable2 = 2
, variable3 = "How are you doing?"
, variable4 = 42;

除了更改第一个或最后一个变量时,它易于维护和读取。


通常,使用逗号优先时,分号会换行以防止出现该问题。 var variable1 = "hello world"\n , variable2 = 2\n , variable3 = "你好吗"\n , variable4 = 42\n ;\n
这是 Haskell 语法。我觉得不知何故在javascript中不推荐/常见做法
P
Peter Mortensen

使用 ES6 destructuring assignment:它将数组中的值或对象中的属性解压缩到不同的变量中。

让 [variable1 , variable2, variable3] = ["Hello, World!", "Testing...", 42];控制台.log(变量1); // 你好世界!控制台.log(变量2); // 测试... console.log(variable3); // 42


这是一个糟糕的主意,尤其是当您需要分配大约 10 个变量时。
P
Peter Mortensen
var variable1 = "Hello, World!";
var variable2 = "Testing...";
var variable3 = 42;

比以下更具可读性:

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

但他们做同样的事情。


使用更少的“文件空间”?我想你有一些解释要做。
@JoshStodola 对我来说看起来是相同的文件空间。因为不是 var<space>,而是它的 <space><space><space><space>
@WORMSS 除非它是 var<space>var<tab> vs <tab>。在很大程度上仍然没有实际意义。
s
shawn

避免使用单语句版本(单变量)的另一个原因是调试。如果在任何分配行中引发异常,则堆栈跟踪仅显示一行。

如果您使用逗号语法定义了 10 个变量,您将无法直接知道哪个是罪魁祸首。

个人陈述版本不受这种歧义的影响。


P
Peter Mortensen

我唯一但必不可少的用于逗号的是在 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");

一时间我不确定,在语言之间切换。


P
Peter Mortensen

尽管两者都是有效的,但使用第二个会阻止没有经验的开发人员将 var 语句放在所有地方并导致提升问题。如果每个函数只有一个 var,在函数的顶部,那么更容易调试整个代码。这可能意味着声明变量的行并不像某些人所希望的那样明确。

我觉得权衡是值得的,如果这意味着让开发人员放弃在他们喜欢的任何地方删除“var”。

人们可能会抱怨 JSLint,我也这样做,但其中很多不是为了解决语言问题,而是为了纠正编码人员的坏习惯,从而防止他们编写的代码出现问题。所以:

“在具有块作用域的语言中,通常建议在第一次使用的地方声明变量。但由于 JavaScript 没有块作用域,因此在函数顶部声明函数的所有变量更为明智。它是建议每个函数使用单个 var 语句。” - http://www.jslint.com/lint.html#scope


该链接(实际上)已损坏-它重定向到通用页面。
P
Peter Mortensen

我认为这是个人喜好问题。我更喜欢通过以下方式做到这一点:

   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 */;

P
Peter Mortensen

可维护性问题可以很容易地通过一些格式化来克服,如下所示:

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

我严格按照个人喜好使用这种格式。当然,对于单个声明,我会跳过这种格式,或者它只是把工作搞砸了。


你格式化的要点是什么? let 和自己的行上的分号?或者是其他东西?它以何种方式帮助解决可维护性问题?什么是可维护性问题? (这些不是反问。)最好的回答是editing your answerwithout“编辑:”、“更新:”或类似的),不在评论中。
S
Schalton

正如每个人所说,它主要是偏好和可读性,但我会在线程上发表评论,因为我没有看到其他人分享这种想法

我认为这个问题的答案很大程度上取决于您设置的变量以及它们之间的关系。我尝试根据我创建的变量是否相关来保持一致;我的偏好通常看起来像这样:

对于不相关的变量

我将它们单线排列,以便以后可以轻松移动它们;我个人绝不会以任何其他方式声明不相关的项目:

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);

我说通常是因为如果输入参数足够长以至于变得不可读,我会将它们分开。

我同意其他人关于使用严格的评论


P
Peter Mortensen

cohesion over coupling”的概念可以比对象/模块/函数更广泛地应用。它也可以在这种情况下使用:

OP 建议的第二个示例将所有变量耦合到同一个语句中,这使得不可能在不破坏内容的情况下将其中一条线移动到其他地方(高耦合)。他给出的第一个示例使变量分配彼此独立(低耦合)。

来自 Coupling

低耦合通常是结构良好的计算机系统和良好设计的标志,当与高内聚相结合时,支持高可读性和可维护性的总体目标。

所以选择第一个。


我看不出这与耦合或内聚有何关系。需要详细说明吗?
OP 建议的第二个示例将所有变量耦合到同一个语句中,这使得不可能在不破坏内容的情况下将其中一条线移动到其他地方(高耦合)。他给出的第一个示例使变量分配彼此独立(低耦合)。
耦合是关于不同模块/对象/函数之间的相互依赖关系,而不是代码行!
最初它是关于模块的,是的,但是这个概念可以更广泛地应用,甚至你自己将对象/函数包含在定义中也表明了这一点。
P
Peter Mortensen

我相信在我们开始使用 ES6 之前,使用单个 var 声明的方法既不好也不坏(以防你有 linter 和 'use strict'。这确实是一种口味偏好。但现在对我来说情况发生了变化。这些是我的支持多行声明的想法:

现在我们有了两种新的变量,而 var 已经过时了。在您真正需要 let 之前,在任何地方都使用 const 是一种很好的做法。因此,您的代码通常会在代码中间包含带有赋值的变量声明,并且由于块作用域,您经常会在块之间移动变量以防发生小的变化。我认为使用多行声明更方便。 ES6 语法变得更加多样化,我们得到了析构函数、模板字符串、箭头函数和可选赋值。当您大量使用所有这些功能与单个变量声明时,它会损害可读性。


P
Peter Mortensen

我认为第一种方法(多个变量)是最好的,否则你可能会得到这个(来自使用 KnockoutJS 的应用程序),我认为这很难阅读:

    var categories = ko.observableArray(),
        keywordFilter = ko.observableArray(),
        omniFilter = ko.observable('').extend({ throttle: 300 }),
        filteredCategories = ko.computed(function () {
            var underlyingArray = categories();
            return ko.utils.arrayFilter(underlyingArray, function (n) {
                return n.FilteredSportCount() > 0;
            });
        }),
        favoriteSports = ko.computed(function () {
            var sports = ko.observableArray();
            ko.utils.arrayForEach(categories(), function (c) {
                ko.utils.arrayForEach(c.Sports(), function (a) {
                    if (a.IsFavorite()) {
                        sports.push(a);
                    }
                });
            });
            return sports;
        }),
        toggleFavorite = function (sport, userId) {
            var isFavorite = sport.IsFavorite();

            var url = setfavouritesurl;

            var data = {
                userId: userId,
                sportId: sport.Id(),
                isFavourite: !isFavorite
            };

            var callback = function () {
                sport.IsFavorite(!isFavorite);
            };

            jQuery.support.cors = true;
            jQuery.ajax({
                url: url,
                type: "GET",
                data: data,
                success: callback
            });
        },
        hasfavoriteSports = ko.computed(function () {
            var result = false;
            ko.utils.arrayForEach(categories(), function (c) {
                ko.utils.arrayForEach(c.Sports(), function (a) {
                    if (a.IsFavorite()) {
                        result = true;
                    }
                });
            });
            return result;
        });

A
Ajay Sahu

有c背景的人肯定会用第二种方法

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

上面的方法更像是c语言