What does “this._events || (this._events = {});” m

2019-07-02 00:12发布

I have started learning Backbone.js. Currently my JavaScript skills are not too good. I have started to examine the backbone.js file and have come across a strange line of code whose purpose I can not figure out. Code sample (if you need more context, manually download backbone.js for developers and see line 80):

var Events = Backbone.Events = {

  // Bind an event to a `callback` function. Passing `"all"` will bind
  // the callback to all events fired.
  on: function(name, callback, context) {
    if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
    this._events || (this._events = {});
    var events = this._events[name] || (this._events[name] = []);
    events.push({callback: callback, context: context, ctx: context || this});
    return this;
  },

What does the line this._events || (this._events = {}); mean? For me, _events looks like an inner variable, but is (this._events = {}) used for assignment or is it an or comparison? Or is || a completely different operation in this context?

3条回答
冷血范
2楼-- · 2019-07-02 00:33

What line “this._events || (this._events = {});” means?

The logical OR (||) executes the first expression this._events and if falsy executes the second expression (this._events = {}).

In essence it checks if this._events is falsy and if so then assigns a new empty object to it.

That way no matter what this._events will always be at least an empty object and the code following will be able to execute without issues.

查看更多
做个烂人
3楼-- · 2019-07-02 00:37

It is a trick that uses javascripts "falsy" evaluation. It is the same as:

if (this._events) {
    // do nothing, this._events is already defined
} else {
    this._events = {};
}

The same goes for the line var events = this._events[name] || (this._events[name] = []); which could be translated to

var events;
if (this._events[name]) {
    events = this._events[name];
} else {
    this._events[name] = [];
    events = this._events[name];
}
查看更多
干净又极端
4楼-- · 2019-07-02 00:45

It's a way to write

if (!this._events) {
    this._events = {};
}

In my opinion it's bad practice to use that kind of short hand, and I think the following line

var events = this._events[name] || (this._events[name] = []);

is even worse. Mixing assignment, of the events with the creation of this._events[name] is quite short, but it's also hard to read. If you don't know what you're doing you might introduce subtle errors that way. That doesn't outweigh the benefits of having it all in one line.

And in the end it will be minified anyway. Let the minifiers take care of stuffing everything in one line. No need to do it yourself.

查看更多
登录 后发表回答