Объявление нескольких переменных в JavaScript

В JavaScript можно объявить несколько переменных следующим образом:

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

... или вот так:

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

Один метод лучше / быстрее другого?


person Steve Harrison    schedule 29.03.2009    source источник
comment
Что касается быстрее, используя этот jsperf, я не смог Я не вижу стабильного прироста скорости при использовании того или иного метода.   -  person Majid Fouladpour    schedule 17.03.2014


Ответы (18)


Первый способ проще в обслуживании. Каждое объявление представляет собой отдельный оператор в одной строке, поэтому вы можете легко добавлять, удалять и переупорядочивать объявления.

При втором способе удаление первого или последнего объявления раздражает, потому что они начинаются с ключевого слова var и заканчиваются точкой с запятой соответственно. Каждый раз, когда вы добавляете новое объявление, вы должны заменять точку с запятой в последней старой строке запятой.

person Paige Ruten    schedule 29.03.2009
comment
Если вы пишете код, который предполагается минимизировать или упаковать позже, второй способ позволяет компрессорам (например, YUI Compressor) предоставить вам более миниатюрную версию. Если размер важен, я бы посоветовал последовать как можно большему количеству предложений JSLint. - person Lane; 19.08.2011
comment
jslint утверждает, что второй способ более праведен, но я не согласен. - person ThatGuy; 08.09.2011
comment
Второй способ - это микрооптимизация. Все объявления var обрабатываются одновременно, а не по одному. Это не имеет большого значения в современных браузерах / современных компьютерах. - person webnesto; 14.04.2012
comment
Второй способ на самом деле более эффективен. - person 0xc0de; 16.07.2013
comment
@ 0xc0de: я хотел бы увидеть доказательство того, что все переменные в одном операторе объявлены эффективными. Если вы измеряете эффективность только по нескольким сохраненным байтам, возможно. Но если вы примете во внимание удобочитаемость и ремонтопригодность, я думаю, вы обнаружите, что преждевременная оптимизация - обычно неправильный путь, тем более что современные браузеры будут собирать и инициализировать все переменные в области видимости на этапе предварительного выполнения. Лично я считаю, что все переменные, объявленные в одной строке или операторе, затрудняют быстрое понимание кода и делают его более подверженным ошибкам. - person ogradyjd; 03.09.2013
comment
Что касается эффективности, как uglifyjs, так и компилятор закрытия Google автоматически сжимают последовательные операторы var в один, делая эту точку спорной (насколько я могу судить, YUI не будет этого делать, однако я тщательно не тестировал). - person bhuber; 17.02.2014
comment
Просто хочу добавить ссылку на очень интересное сообщение в блоге Бена Алмана, которое в конечном итоге убедило меня использовать несколько операторов var: benalman.com/news/2012/05/multiple-var-statements-javascript - person clement g; 22.07.2014
comment
FWIW, когда моя команда пробовала подход single-var, мы, казалось, столкнулись с большим количеством проблем слияния в git. В этом есть смысл, поскольку, как указывается в статье Бена Алмана, вам нужно редактировать больше строк кода, когда вы что-либо меняете. Мы вернулись к использованию нескольких var. - person Chris Jaynes; 06.08.2014
comment
Я создал простой jsperf, чтобы увидеть, насколько это изменилось для меня (64-разрядная версия Chrome на 64-разрядной версии Ubuntu), и я был удивлен, увидев, что несколько ключевых слов var на самом деле номинально быстрее. Но они оба настолько близки, что на самом деле это должно быть вопросом личных предпочтений. Я лично считаю, что несколько ключевых слов var более удобны в обслуживании и менее подвержены ошибкам. Ссылка на jsperf: jsperf.com/var-declaractions-single-or-multiple. Jsperf, опубликованный под вопросом OP (jsperf.com/multi-vars-vs-single- var) показывает, что одна переменная на 6% медленнее, чем несколько переменных. Мой jsperf минимален. - person bmacnaughton; 25.01.2015

Помимо ремонтопригодности, первый способ исключает возможность случайного создания глобальных переменных:

(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
}());
person Kenny Ki    schedule 12.09.2011
comment
Хорошая точка зрения. Если они короткие, то запись в одну строку позволит избежать этой проблемы: var variable1 = "Hello World!", variable2 = "Testing...", variable3 = 42;. Отсутствующий , приведет к сбою, но я согласен, что это рискованно - person Aram Kocharyan; 16.01.2012
comment
Если вы используете строгий режим, вы все равно не сможете создавать такие глобальные объекты. - person Danyal Aytekin; 24.10.2012
comment
Мне нравится объявлять несколько переменных в одной строке, потому что это выглядит чище. Тем не менее, случайное объявление глобальных переменных представляет собой реальную опасность. При поиске утечек памяти я встречал несколько случаев, когда я случайно объявлял сразу несколько глобальных переменных, потому что использовал точку с запятой вместо запятой. - person smabbott; 06.03.2013
comment
Мой текстовый редактор дает мне Possible Fatal Error, если я пропускаю кому, ура мне! - person ; 03.02.2015

Это гораздо удобнее для чтения, если сделать это таким образом:

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

Но для этого требуется меньше места и строк кода:

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

Он может быть идеальным для экономии места, но пусть компрессоры JavaScript справятся с этим за вас.

person Jason Stackhouse    schedule 03.06.2012

Обычно используется один оператор var на каждую область видимости. для организации. То, как все «области» следуют аналогичному шаблону, что делает код более читабельным. Вдобавок двигатель все равно «поднимает» их всех наверх. Таким образом, объединение ваших заявлений более точно имитирует то, что на самом деле произойдет.

person Community    schedule 20.11.2009
comment
Вы можете хранить объявления вместе, не используя одно и то же объявление var. Я понимаю и принимаю объяснения, данные на jslint (ваша ссылка), но не разделяю вывод. Как было сказано выше, это больше вопрос стиля, чем чего-либо еще. В мире Java (среди прочего) для удобства чтения рекомендуется обратное (одно объявление на строку). - person PhiLho; 19.05.2011
comment
Более читабельный? Единственная причина, по которой люди помещают их в одну строку, - это указанная вами причина, связанная с JS: JS перемещает все объявления наверх. Если бы этого не было, мы бы все объявляли наши вары ближайшими к месту их использования. - person Danyal Aytekin; 24.10.2012

ECMAScript 2015 представил деструктурирующее назначение, которое работает довольно хорошо:

[a, b] = [1, 2]

a будет равно 1, а b будет равно 2.

person Nir Naor    schedule 21.07.2016
comment
он не отвечает на вопрос, но может быть лучшей альтернативой обоим описанным подходам. - person svarog; 22.09.2016
comment
Я думаю, что ваш подход не очень жизнеспособен в случае, если у вас есть длинные списки переменных. Трудно сказать, к какой переменной связано какое значение, а также у вас нет защиты от ошибок - это случай плохого слияния, во время которого вы случайно могли удалить один элемент из массива. Пример: let [aVar, bVar, cVar, xVar, yVar, zVar] = [10, 20, 30, 40, 50]; Так что лично я не рекомендую это делать. - person Kirill Reznikov; 22.05.2017
comment
это удобно, если вы хотите установить множество переменных с одинаковыми значениями. Используется, например, для сброса на ноль в цикле. - person Nick; 19.11.2018
comment
Да! это то, что я искал. Особенно, если вы хотите определить двухмерную пару или многомерные значения, но не массивы. - person Eugene Kardash; 15.08.2019

Это просто вопрос личных предпочтений. Между этими двумя способами нет никакой разницы, кроме нескольких байтов, сохраненных во второй форме, если вы удалите пробелы.

person Brian Campbell    schedule 29.03.2009
comment
Второй экономит пару байтов. - person Sophie Alpert; 29.03.2009
comment
Если вы удалите пробелы, то тогда 'var foo = hello, bar = world;' объявление занимает меньше символов, чем var foo = hello; var bar = world; Если у вас популярный сайт, может помочь экономия нескольких байтов на JS (вы также можете минимизировать имена переменных и т. Д.) - person Brian Campbell; 29.03.2009
comment
Я считаю, что эти сохраненные байты неактуальны в настоящее время из-за появления минификаторов JavaScript, в частности (так называемого) простого режима компилятора Google Closer. - person 700 Software; 27.03.2012
comment
Это неверное утверждение - есть разница в том, как их обрабатывает движок времени выполнения (по крайней мере, в старых браузерах, не уверенных в современных браузерах). Я мог бы поклясться, что прочитал его в High Performance Javascript от Закаса, но сейчас мне трудно его найти. Я буду держать глаза открытыми и вернусь со ссылкой, когда она у меня будет. В любом случае, это не большая разница - просто производительность, насколько я помню (и небольшая разница в производительности). - person webnesto; 14.04.2012
comment
@webnesto никогда не будет никакой производительности от синтаксиса, если семантика синтаксиса одинакова. Вы не будете выполнять код сразу, а сначала проанализируете его и проведете семантический анализ - здесь оба стиля объявления выравниваются. - person Esailija; 04.08.2013

Может вот так

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

За исключением изменения первой или последней переменной, ее легко поддерживать и читать.

person joe nerdan    schedule 19.12.2011
comment
Как правило, при использовании первой запятой точка с запятой ставится на новую строку, чтобы предотвратить эту проблему. var переменная1 = привет, мир \ n, переменная2 = 2 \ n, переменная3 = как у вас дела \ n, переменная4 = 42 \ n; \ n - person BrianFreud; 31.01.2012
comment
Это синтаксис Haskell. Я чувствую, что почему-то это не рекомендуется / обычная практика в javascript - person shamanSK; 21.06.2018

Используйте деструктурирующее присвоение: оно распаковывает значения из массивов или свойства из объектов в отдельные переменные.

let [variable1 , variable2, variable3] =
["Hello, World!", "Testing...", 42];

console.log(variable1); // Hello, World!
console.log(variable2); // Testing...
console.log(variable3); // 42

person Rohit Jindal    schedule 25.05.2017
comment
Это ужасная идея, особенно если вам нужно назначить около 10 переменных. - person Kirill Reznikov; 02.03.2018

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

читаемее, чем:

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

Но они делают то же самое.

person Kevin Crowell    schedule 29.03.2009
comment
Использует меньше файлового пространства? Я думаю, тебе нужно кое-что объяснить. - person Josh Stodola; 29.03.2009
comment
@JoshStodola мне кажется, что это то же файловое пространство. Поскольку вместо var<space>, это <space><space><space><space> - person WORMSS; 18.05.2018
comment
@WORMSS, если только это не var<space> или var<tab> против <tab>. По-прежнему в значительной степени спорный вопрос. - person mpag; 18.08.2018

Еще одна причина избегать версии с одним оператором (single var) - это отладка. Если исключение выбрасывается в любой из строк назначения, трассировка стека показывает только одну строку.

Если у вас было 10 переменных, определенных с помощью синтаксиса запятой, у вас нет возможности напрямую узнать, какая из них была виновата.

Версия отдельного утверждения не страдает этой двусмысленностью.

person shawn    schedule 10.07.2016

Единственное, но важное, что я использую запятую - это цикл 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");

На мгновение я не был уверен, переключаюсь между языками.

person codelion    schedule 08.02.2013

Хотя оба варианта допустимы, использование второго не позволяет неопытным разработчикам размещать операторы var повсюду и вызывать проблемы с подъемом. Если для каждой функции есть только одна переменная в верхней части функции, то отладить код в целом будет проще. Это может означать, что строки, в которых объявлены переменные, не такие явные, как некоторым может показаться.

Я считаю, что компромисс того стоит, если он означает, что разработчика нужно отучить от использования слова «var» везде, где они захотят.

Люди могут жаловаться на JSLint, я тоже, но многие из них ориентированы не на исправляя проблемы с языком, но исправляя вредные привычки кодировщиков и, следовательно, предотвращая проблемы в коде, который они пишут. Следовательно:

В языках с блочной областью видимости обычно рекомендуется объявлять переменные на сайте первого использования. Но поскольку JavaScript не имеет области видимости блока, разумнее объявить все переменные функции в верхней части функции. Рекомендуется использовать один оператор var для каждой функции. - http://www.jslint.com/lint.html#scope.

person Wade Harrell    schedule 08.09.2014
comment
Ссылка (фактически) не работает - она ​​перенаправляет на общую страницу. - person Peter Mortensen; 30.10.2020

Я думаю, это дело личных предпочтений. Я предпочитаю делать это следующим образом:

   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 */;
person v1r00z    schedule 10.02.2015

Проблема ремонтопригодности может быть довольно легко преодолена с помощью небольшого форматирования, например:

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

Я использую это форматирование исключительно в соответствии с личными предпочтениями. Я, конечно, пропускаю этот формат для отдельных объявлений или для случаев, когда он просто склеивает работу.

person Beau    schedule 03.05.2019
comment
В чем суть вашего форматирования? let и точку с запятой в собственных строках? Или что-то другое? Каким образом это помогает решить проблему ремонтопригодности? В чем проблема ремонтопригодности? (Это не риторические вопросы.) Лучшим ответом было бы редактирование ответа (без Edit :, Update: или подобное), а не здесь, в комментариях. - person Peter Mortensen; 30.10.2020

Концепция единства по связанность может применяться не только к объектам / модулям / функциям. Также он может служить в этой ситуации:

Второй пример, предложенный OP, объединил все переменные в один и тот же оператор, что делает невозможным взять одну из строк и переместить ее в другое место без нарушения работы (высокая связь). В первом примере, который он привел, назначения переменных независимы друг от друга (низкая связь).

Из Coupling:

Низкая взаимосвязь часто является признаком хорошо структурированной компьютерной системы и хорошего дизайна, а в сочетании с высокой степенью согласованности поддерживает общие цели высокой удобочитаемости и ремонтопригодности.

Так что выберите первый.

person Magne    schedule 27.02.2014
comment
Я не понимаю, как это связано с сцеплением или сплоченностью. Хотите уточнить? - person Edson Medina; 27.01.2015
comment
Второй пример, предложенный OP, объединил все переменные в один и тот же оператор, что делает невозможным взять одну из строк и переместить ее в другое место без нарушения работы (высокая связь). В первом примере, который он привел, назначения переменных независимы друг от друга (низкая связь). - person Magne; 27.01.2015
comment
Связь - это взаимозависимость между различными модулями / объектами / функциями, а НЕ строки кода! - person Edson Medina; 28.01.2015
comment
Первоначально речь шла о модулях, да, но эту концепцию можно применить и в более общем плане, как показывает даже ваше собственное включение объектов / функций в определение. - person Magne; 28.01.2015

Я считаю, что до того, как мы начали использовать ES6, подход с одним объявлением var не был ни хорошим, ни плохим (в случае, если у вас есть линтеры и 'use strict'. Это действительно было вкусовое предпочтение. Но теперь все изменилось для меня. Это мои мысли в пользу многострочного объявления:

  1. Теперь у нас есть два новых вида переменных, и var устарели. Хорошая практика - использовать const везде, пока let вам действительно не понадобится. Поэтому довольно часто ваш код будет содержать объявления переменных с присваиванием в середине кода, и из-за области видимости блока вы довольно часто будете перемещать переменные между блоками в случае небольших изменений. Я думаю, что это удобнее делать с многострочными объявлениями.

  2. Синтаксис ES6 стал более разнообразным, появились деструкторы, строки шаблонов, стрелочные функции и необязательные присваивания. Когда вы интенсивно используете все эти функции с объявлениями одной переменной, это ухудшает удобочитаемость.

person Kirill Reznikov    schedule 22.05.2017

Я думаю, что первый способ (несколько переменных) лучше всего, так как в противном случае вы можете получить это (из приложения, которое использует 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;
        });
person vegemite4me    schedule 27.01.2014

Как все заявили, это в основном предпочтение и удобочитаемость, но я брошу комментарий в ветке, так как я не видел, чтобы другие разделяли мысли в этом ключе.

Я думаю, что ответ на этот вопрос во многом зависит от того, какие переменные вы устанавливаете и как они связаны. Я стараюсь быть последовательным, основываясь на том, связаны ли создаваемые мной переменные или нет; мои предпочтения обычно выглядят примерно так:

Для несвязанных переменных

Я выделяю их одной линией, чтобы их можно было легко переместить позже; Я лично никогда не объявлял бы несвязанные предметы другим способом:

const unrelatedVar1 = 1;
const unrelatedVar1 = 2;
const unrelatedVar1 = 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

person Schalton    schedule 02.07.2021