a = a || function(){...}
- это идиома, которая очень распространена в Javascript. Он опирается на две концепции, которые, хотя и не уникальны для Javascript, но, возможно, еще не знакомы с вами.
1. Оператор короткого замыкания
Короткое замыкание оператора [wikipedia] - это оптимизация компилятора, разработанная для предотвращения ненужной оценки.
Чтобы продемонстрировать это, давайте предположим, что мы хотим определить, является ли человек подростком, то есть имеет ли возраст человека включительно от 13 до 19 лет.
var isTeenager = person.age >= 13 && person.age <= 19;
Теперь давайте предположим, что код выполняется, и выясняется, что человек моложе 13 лет. Первое условие будет оценено и вернет false. Поскольку программе теперь известно, что левая часть оператора &&
равна false
, а поскольку &&
требует, чтобы обе стороны были true
, чтобы вычислить до true
, она знает, что вычисление правой сторона рук бессмысленна.
Другими словами, программа, увидев, что возраст человека не превышает 13 лет, уже знает, что он не подросток, и не заботится о том, меньше ли ему 19 лет.
Тот же принцип применяется к оператору ||
. Предположим, мы хотели узнать, может ли человек ездить на автобусе бесплатно, то есть, если ему более 70 лет или он инвалид.
var canRideFree = person.age >= 70 || isHandicapped(person);
Если человеку за 70, программа уже знает, что он может ездить бесплатно. На данный момент программе не важно, является ли он инвалидом или нет, и, таким образом, он не оценивает вызов функции isHandicapped
. Если, с другой стороны, человек был моложе 70 лет, то canRideFree
будет установлено на то, что isHandicapped
вернет.
2. Истинные и ложные значения
Значения правдивости и ложности [блог случайного человека] - это логические оценки объектов. В Javascript каждый объект оценивается как «истинное» или «ложное» значение.
Выражение «falsy», если его значение равно одному из следующих:
false, null, undefined, 0, "", NaN
Все остальное правдиво.
Люди используют тот факт, что нулевая или неопределенная переменная оценивается как false
. Это означает, что вы можете проверить, существует ли переменная очень легко:
if (a) { /* a exists and is not a falsy value */ }
Объединяя то, что мы знаем
Оператор ||
замыкает цепь и возвращает значение последнего выражения, которое он оценивает . Этот принцип сочетается с правдивостью в этом единственном утверждении:
Object.keys = Object.keys || function() {...}
Если Object.keys
является правдивым, он будет оценен и назначен самому себе. В противном случае, Object.keys
будет присвоено функции. Это очень распространенная идиома в Javascript для проверки, если значение уже существует, и присвоение его чему-то другому, если оно не существует.
Некоторые другие языки, такие как C #, которые не имеют правдивости, имеют нуль-объединяющий оператор [MSDN] , имеющий аналогичное назначение.
object Value = PossiblyNullValue ?? ValueIfNull;
В этом коде Value
будет присвоено PossiblyNullValue
, если оно не равно нулю, и в этом случае оно будет присвоено ValueIfNull
.
Если вы не удосужились прочитать что-то, что я сказал выше, все, что вам нужно знать, это то, что a = a || function() {...}
в основном делает то, что делает этот код:
if (exists(Object.keys)) {
Object.keys = Object.keys;
} else {
Object.keys = function() {...};
}
function exists(obj) {
return typeof obj !== "undefined" &&
obj !== null &&
obj !== false &&
obj !== 0 &&
obj !== "" &&
!isNaN(obj);
}