Читая код leaflet.js, я наткнулся на метод с этой строкой, которую я не совсем понимаю:
var events = this._leaflet_events = this._leaflet_events || {};
которую можно упростить как
var a = b = b || {};
Насколько я понимаю, эта инструкция является множественной левой присвоение, которое является правильным ассоциативным, что означает, что сначала будет выполняться JavaScript
b = b || {} //if b exists, returns b, else return an empty object
, затем
a = b // returns the output of the preceding instruction
Что для меня не имеет смысла. Почему бы не написать вместо этого:
a = b || {};
Полный контекст:
addEventListener: function( /*string*/ type, /*function */ fn, /*(optional) object*/ context){
var events = this._leaflet_events = this._leaflet_events || {};
events[type] = events[type] || {};
events[type].push({
action: fn,
context: context || this
});
return this;
}
Я подозреваю, что это трюк со ссылками, поскольку я не вижу, как this._leaflet_events
иначе модифицируется методом.
Думая об этом, пишем var a = b = b || {}
на самом деле является уловкой для назначения var a
ссылки на b
, независимо от того, определено ли b
или нет. Изменение a
теперь изменяет b
.
Назад к Листовке. С
var events = this._leaflet_events = this._leaflet_events || {};
this._leaflet_events
либо существует, либо инициализируется как {}
.
events
назначается this._leaflet_events
по ссылке. Значение ссылки может быть {}
, но по-прежнему this._leaflet_events
изменяется при изменении events
.
Наоборот, писать
var events = this._leaflet_events || {};
было бы ошибкой, так как если this._leaflet_events
не определено, events
теперь будут указывать на вновь созданный объект, значение которого будет {}
. Изменение events
изменит новый объект, но не изменит значение this._leaflet_events
.
Одинаковые внешние значения, разные ссылки. Вот в чем дело.