Что означает "var FOO = FOO || {}" (назначить переменную или пустой объект этой переменной) в Javascript? - PullRequest
93 голосов
/ 22 июня 2011

Глядя на исходный код в Интернете, я натолкнулся на это в верхней части нескольких исходных файлов.

var FOO = FOO || {};
FOO.Bar = …;

Но я понятия не имею, что делает || {}.

Я знаю, {} равно new Object(), и я думаю, || для чего-то вроде "если оно уже существует, используйте его значение, иначе используйте новый объект.

Почему я вижу это в верхней части исходного файла?

Ответы [ 7 ]

146 голосов
/ 22 июня 2011

Ваше предположение о намерении || {} довольно близко.

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

Причина, по которой используется , заключается в том, что если у вас есть два (или более) файла:

var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func1 = {
}

и

var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func2 = {
}

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

Первый загруженный файл будет создавать исходный MY_NAMESPACE объект, а любой впоследствии загруженный файл будет увеличивать объект.

Полезно, что это также позволяет асинхронную загрузку сценариев, которые используют одно и то же пространство имен, что может улучшить время загрузки страницы. Если теги <script> имеют атрибут defer, вы не можете знать, в каком порядке они будут интерпретироваться, поэтому, как описано выше, эта проблема также решается.

21 голосов
/ 22 июня 2011
var AEROTWIST = AEROTWIST || {};

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

Двойная труба || является оператором OR, а вторая часть OR выполняется только в том случае, если первая часть возвращает false.

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

это в основном то же самое, что сказать это:

if(!AEROTWIST) {var AEROTWIST={};}

Надеюсь, это поможет.

5 голосов
/ 21 августа 2015

Есть две основные части, которые охватывает var FOO = FOO || {};.

# 1 Предотвращение переопределений

Представьте, что ваш код разделен на несколько файлов и ваши коллегитакже работают над объектом под названием FOO.Тогда это может привести к тому, что кто-то уже определит FOO и назначит ему функциональность (например, функцию skateboard).Тогда вы переопределите его, если не проверяете, существует ли он уже.

Проблемный случай:

// Definition of co-worker "Bart" in "bart.js"
var FOO = {};

FOO.skateboard = function() {
  alert('I like skateboarding!');
};

// Definition of co-worker "Homer" in "homer.js"
var FOO = {};

FOO.donut = function() {
  alert('I like donuts!');
};

В этом случае функция skateboard пропадет, если вы загрузите файл JavaScript homer.js после bart.js в свойHTML, потому что Гомер определяет новый объект FOO (и, таким образом, переопределяет существующий объект из Bart), поэтому он знает только о функции donut.

Поэтому вам нужно использовать var FOO = FOO || {};, что означает "FOOбыть назначенным на FOO (если он уже существует) или на новый пустой объект (если FOO еще не существует).

Решение:

var FOO = FOO || {};

// Definition of co-worker Bart in bart.js
FOO.skateboard = function() {
  alert('I like skateboarding!');
};

// Definition of co-worker Homer in homer.js
var FOO = FOO || {};

FOO.donut = function() {
  alert('I like donuts!');
};

Потому что Барт иТеперь Гомер проверяет наличие FOO, прежде чем они определят свои методы, вы можете загружать bart.js и homer.js в любом порядке, не переопределяя методы друг друга (если у них разные имена). Таким образом, вы всегда получите FOO объект, который имеет методы skateboard и donut (Yay!).

# 2 Определение нового объекта

Если вы прочиталиПервый пример, то вы уже сейчас, какова цель || {}.

Потому чтоесли не существует FOO объекта, тогда OR-case становится активным и создает новый объект, так что вы можете назначить ему функции.Как:

var FOO = {};

FOO.skateboard = function() {
  alert('I like skateboarding!');
};
5 голосов
/ 18 ноября 2011

Еще одно распространенное использование для ||также установить значение по умолчанию для неопределенного параметра функции:

function display(a) {
  a = a || 'default'; // here we set the default value of a to be 'default'
  console.log(a);
}

// we call display without providing a parameter
display(); // this will log 'default'
display('test'); // this will log 'test' to the console

Эквивалент в других программах обычно:

function display(a = 'default') {
  // ...
}
3 голосов
/ 22 июня 2011

Если в AEROTWIST нет значения или оно равно нулю или не определено, значение, назначенное новому AEROTWIST, будет {} (пустой объект)

1 голос
/ 22 июня 2011

Оператор || принимает два значения:

a || b

Если a равно truey , оно вернет a.В противном случае он вернет b.

Ложные значения: null, undefined, 0, "", NaN и false.Истинные значения - это все остальное.

Так что, если a не было установлено (это undefined), он вернет b.

0 голосов
/ 14 марта 2012

Обратите внимание, что в некоторых версиях IE этот код не будет работать должным образом.Поскольку var, переменная переопределяется , а назначается так - если я правильно помню проблему - у вас всегда будет новый объект.Это должно решить проблему:

var AEROTWIST;
AEROTWIST = AEROTWIST || {};
...