7

Can anyone explain what this statement means?

e = e || x

Specifically,

e = e || window.event

This appears in a chunk of code I am looking at.

I'm not at a complete loss, however My understanding is that it assigns both e and window.event (or x/whatever) to e. It's only natural, right?

But what is the value in assigning e to e? Shouldn't e = window.event be enough? Perhaps is depends on how it is used?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
muiiu
  • 507
  • 1
  • 4
  • 11
  • Isn't `||` a boolean operator? So `e` should be either `true` or `false` after this? – Cobra_Fast Jul 15 '13 at 15:42
  • 1
    it's "use e if it's already defined/available, otherwise use x". It's a nice bit of syntactical sugar in javascript, in pseudo-code, "if (exists e) then return e else return x". – Marc B Jul 15 '13 at 15:43
  • 5
    @Cobra_Fast `||` doesn't return true / false in javascript, it returns the first object that is "truthy". – Matthew Jul 15 '13 at 15:44
  • IE doesn't pass the event argument to the handler – dandavis Jul 15 '13 at 15:45
  • 2
    possible duplicate of [JavaScript OR (||) variable assignment explanation](http://stackoverflow.com/questions/2100758/javascript-or-variable-assignment-explanation) – Quentin Jul 15 '13 at 15:46
  • possible duplicate of [In Javascript, what does it mean when there is a logical operator in a variable declaration?](http://stackoverflow.com/questions/3088098/in-javascript-what-does-it-mean-when-there-is-a-logical-operator-in-a-variable) (The possible dupe was itself a possible dupe!) – Evan Davis Jul 15 '13 at 17:27

10 Answers10

18

e = e || x assigns x to e if e evalutes to false.

This is the same as:

if (!e) {
  e = x;
}
// or
e = e ? e : x

Here is a table which shows which values evalute to false: https://stackoverflow.com/a/7615236/603003

The most important values are: null and undefined.


What does it mean in your context? You probably have some sort of this code:
function handler(e) {
  e = e || window.event;
}

Where handler is an event listener attached to a DOM element. Since older versions of IE did not pass the event object as a parameter, one had to check if the parameter was undefined. If the latter was the case, one assigns the global window.event object (which IE supplied) to e.

Community
  • 1
  • 1
ComFreek
  • 29,044
  • 18
  • 104
  • 156
6

It doesn't assign both to "e", just the one that's not either undefined, null, 0, NaN, "", or false. It prefers the original value of "e" to window.event because "e" is on the left side of ||, but if it's empty (one of those values I listed) then "e" will be assigned window.event.

It's done because Internet Explorer didn't pass the event reference as a parameter, instead simply binding to a global symbol. Event handlers were very often written:

function someHandler(e) {
  e = e || window.event;
  // ...
}

It would probably have been more rigorously "correct" to write:

function pedanticHandler(e) {
  if (e === undefined) // or arguments.length == 0 perhaps
    e = window.event;
  // ...
}
Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 2
    Specifically, if e has a value, it keeps its value. If it is undefined, we look elsewhere for a value. – Jon Kiparsky Jul 15 '13 at 15:42
  • @JonKiparsky yes, expanded :) – Pointy Jul 15 '13 at 15:43
  • 1
    @VivinPaliath Yes, it is! (... but only if someone in your team really declares the variable `undefined` ;) ). – ComFreek Jul 15 '13 at 15:50
  • @CrazyTrain I think he (including me) compared `typeof e === "undefined"` to `e === undefined`, not to `if (e)` in general. – ComFreek Jul 15 '13 at 15:54
  • Please take all extended discussions to chat. This is not a good place for them. If you have clarifications for the question or an answer, please edit that post with the relevant information. – George Stocker Jul 15 '13 at 16:41
  • @CrazyTrain [Chat is here](http://chat.stackoverflow.com/rooms/33502/testing-for-undefined) I am deleting my comments. – Vivin Paliath Jul 15 '13 at 18:02
4

You're misunderstanding operators.

This line assigns the expression e || x to the variable e.

The value of e || x is the first truthy value.
If e is truthy, that will be e; if e is falsy, it will be x.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
2

it is redundant to assign e = e, they do it as part of this statement because it is an idiom.

The statement checks if e is defined and if it is not then it initializes it with the expression that follows ||. This works because when || expression is evaluated the interpreter stops evaluation when the first true part (from the left) is found.

In particular, if e evaluates to true then evaluation stops right then and effectively you have e = e, which is redundant. But if e is undefined or evaluates to false then the right part of the || is evaluated and assigned to e.

I personally would use an if statement instead of being clever. Or restructure the code even more to avoid if altogether.

EDIT: I think the original code is buggy. Clearly the intention is check if e is already initialized. But here it can be reassigned to itself if it is already initialized and evaluates to true. This can have unwanted side effects.

akonsu
  • 28,824
  • 33
  • 119
  • 194
  • then why do you think it's redundant? have you drive an old IE lately? – dandavis Jul 15 '13 at 15:45
  • 4
    There's no misunderstanding of the code, it just looks that way from how the answer is phrased. It should have been written like this: "Of course it is redundant to assign `e` to `e`; that's not what this code does. Instead, the programmer is doing something else: namely assigning a value to `e` only if `e` is falsy. This idiom saves code over the longer `if (!e) e = x` style. – Ray Toal Jul 15 '13 at 15:47
  • The phrasing of this answer is poor. I'm sure akonsu knows what it does, but answering isn't just about knowing. It's about communicating. Basically, the first sentence makes no sense. If it's redundant, how is it saving code? –  Jul 15 '13 at 15:48
  • @CrazyTrain Very true. It's not a good answer by any means. I hope i t gets edited. I just wanted to share what I discovered after puzzling over it for a couple minutes, because it wasn't obvious even after several reads. :) – Ray Toal Jul 15 '13 at 15:51
  • I think this answer is valuable because it describes the purpose behind OPs code. – Cobra_Fast Jul 15 '13 at 15:53
  • `if e is defined then evaluation stops right then and effectively you have e = e` That is wrong! It must say: `if e is defined **and** evalutes to true`. – ComFreek Jul 15 '13 at 16:02
  • @akonsu But I don't think that such code is buggy or unintended. It is indeed a very useful technique IMHO. Major projects do use it, too, jQuery uses it for example in [this file](https://github.com/jquery/jquery/blob/6b5391508e7354076a32375c7f536f8eb91195ee/src/event.js). – ComFreek Jul 15 '13 at 17:16
2

If e is undefined (or null, or any other false value), it is initialized with x.

It is implicitly :

var e = e ? e : x;
AllTooSir
  • 48,828
  • 16
  • 130
  • 164
2

It doesn't assign both values to e. It's just a way of assigning x to e if the original value of e is null, undefined, 0, false, NaN, or an empty string (""). If the original value of e doesn't match any of the aforementioned conditions, it keeps the original value.

Basically, it's a shorthand form for:

if(!e) {
   e = x;
}
Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
2

The above answer (ComFreek) is correct. The reason it does this is because of lazy evaluation. The boolean x || y, evaluated lazily will check x first. If it evaluates to TRUE (i.e. is non-zero, non-null), then the expression stops and returns TRUE. If x evaluates to FALSE, it will return y.

This is clever code. Clever is stupid. (opinion) As a maintainer, I prefer to see

if (!e) {
    e = x;
}
ComFreek
  • 29,044
  • 18
  • 104
  • 156
  • Agreed. C# has a slightly better notation with e = e ?? x; The double quesiton mark makes it more clear that your checking whether something exists, rather than assigning a boolean. – Captain Kenpachi Jul 15 '13 at 16:01
1

It set e equal to either itself (if it is not null, undefined or false) otherwise window.event.

It is like saying

if (!e) e = window.event;
Richard Friend
  • 15,800
  • 1
  • 42
  • 60
1

In your example e = e || window.event; is equivalent to :

if(!e){
     e = window.event;
}
Yann
  • 2,211
  • 1
  • 15
  • 14
1

when you add an eventhandler to an element

document.addEventListener('click',handler,false);

in most browsers it passes the event as first parameter.

handler=function(e){// e is the event in some browsers
 e=e||window.event; // but in some old browsers the event is window.event
  // so you check if e(event) exists else you use window.event.
  // '||' means or...
  // e is already defined as a placeholder in the handler function
  // so you don't need to put var infront of it
}
Cobra_Fast
  • 15,671
  • 8
  • 57
  • 102
cocco
  • 16,442
  • 7
  • 62
  • 77