Что означает "var FOO = FOO || {}" (назначить переменную или пустой объект этой переменной) в Javascript?
Глядя на исходный код в Интернете, я наткнулся на это в верхней части нескольких исходных файлов.
var FOO = FOO || {};
FOO.Bar = …;
Но я понятия не имею, что || {}
делает.
я знаю {}
равно new Object()
и я думаю, что ||
для чего-то вроде "если он уже существует, используйте его значение, иначе используйте новый объект.
Почему я вижу это в верхней части исходного файла?
8 ответов
Ваше предположение о намерении || {}
довольно близко
Этот конкретный шаблон, когда он виден вверху файлов, используется для создания пространства имен, то есть именованного объекта, в котором функции и переменные могут создаваться без чрезмерного загрязнения глобального объекта.
Причина, по которой он используется, заключается в том, что если у вас есть два (или более) файла:
var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func1 = {
}
а также
var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func2 = {
}
оба из которых имеют одинаковое пространство имен, тогда не имеет значения, в каком порядке загружены два файла, вы все равно получаете func1
а также func2
правильно определены в MY_NAMESPACE
объект правильно.
Первый загруженный файл создаст начальный MY_NAMESPACE
объект, и любой впоследствии загруженный файл будет дополнять объект.
Полезно, что это также позволяет асинхронную загрузку сценариев, которые используют одно и то же пространство имен, что может улучшить время загрузки страницы. Если <script>
теги имеют defer
набор атрибутов, вы не можете знать, в каком порядке они будут интерпретироваться, поэтому, как описано выше, это также решает эту проблему.
var AEROTWIST = AEROTWIST || {};
В основном эта строка говорит установить AEROTWIST
переменная к значению AEROTWIST
переменная, или установите его для пустого объекта.
Двойная труба ||
является оператором OR, а вторая часть OR выполняется только в том случае, если первая часть возвращает false.
Следовательно, если AEROTWIST
уже имеет значение, оно будет сохранено как это значение, но если оно не было установлено ранее, то оно будет установлено как пустой объект.
это в основном то же самое, что сказать это:
if(!AEROTWIST) {var AEROTWIST={};}
Надеюсь, это поможет.
Есть две основные части, которые 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
объект (и, следовательно, переопределяет существующий от Барта), поэтому он знает только о 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
(Ура!).
# 2 Определение нового объекта
Если вы прочитали первый пример, то уже сейчас знаете, какова цель || {}
,
Потому что, если не существует FOO
объект, тогда OR-case станет активным и создаст новый объект, так что вы можете назначить ему функции. Подобно:
var FOO = {};
FOO.skateboard = function() {
alert('I like skateboarding!');
};
Другое общее использование для || также установить значение по умолчанию для неопределенного параметра функции:
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') {
// ...
}
Если в AEROTWIST нет значения или оно равно нулю или не определено, значение, назначенное новому AEROTWIST, будет {} (пустой объект)
||
Оператор принимает два значения:
a || b
Если это правда, он вернется a
, В противном случае он вернется b
,
Ложные значения null
, undefined
, 0
, ""
, NaN
а также false
, Истинные ценности - это все остальное.
Так что если a
не было установлено (это undefined
) он вернется b
,
Для || операций, JS вернет ПЕРВОЕ "истинное" значение, которое он найдет (чтение слева направо):
var bob = false || undefined || 0 || null || "hi"
// ^ ^ ^ ^ ^
// nope nope nope nope yip
//
// => bob = "hi"
// --------------
// breaking
// --------------
var bob = false || "hi" || 0 || null || undefined
// ^ ^
// nope yip <-- stops here
// the rest are ignored
//
// => bob = "hi"
Еще одна хитрость - использовать && (и), чтобы убедиться, что что-то существует, прежде чем обращаться к нему.
Для операций && JS вернет ПОСЛЕДНЕЕ «правдивое» значение, которое он найдет (чтение слева направо).
Например, если вы пытаетесь прочитать свойство из многоуровневого объекта.
var obj = {
foo : {
bar : "hi"
}
}
var bob = obj && obj.foo && obj.foo.bar;
// ^ ^ ^
// yip yip use this
//
// => bob = "hi"
// --------------
// breaking:
// --------------
var bob = obj && obj.foo && obj.foo.sally && obj.foo.bar;
// ^ ^ ^
// yip yip nope <-- stops here,
// ^ and returns the last "yip"
// | the rest are ignored |
// '-----------------------------------------------'
//
// => bob = obj.foo
Оба || и операции && читаются слева направо ... поэтому у вас могут быть вещи, которые обычно могут вызывать ошибки в направлении правой стороны, поскольку JS просто перестанет читать слева направо, как только обнаружит истинное / ложное значение.
Обратите внимание, что в некоторых версиях IE этот код не будет работать должным образом. Поскольку var
переменная переопределяется и присваивается, поэтому - если я правильно помню проблему - у вас всегда будет новый объект. Это должно решить проблему:
var AEROTWIST;
AEROTWIST = AEROTWIST || {};