43

I searched through the internets but could not find a relevant search criteria so I thought this would be the best place to ask.

I have a JS statement saying

document.location.hash = this.slug = this.sliceHashFromHref(href)

How does this work??

aioobe
  • 413,195
  • 112
  • 811
  • 826
amit
  • 10,133
  • 22
  • 72
  • 121

6 Answers6

74

How does this work??

a = b can be seen as both a statement and an expression.

The result of the expression is b.

In other words,

a = b = c;

which can be written as

a = (b = c);

is equivalent to

b = c;
a = b;

Thus your code is equivalent to:

this.slug = this.sliceHashFromHref(href);
document.location.hash = this.slug;
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 2
    If the result of the expression `a = b` is `b`, then the expression `a = (b = c)` should be equivalent to `b = c; a = c;` (but this does not mean that `a = b = foo()` will call `foo` twice!). I wonder how `a = b = c` will operate in case `a`, `b` and `c` have getters and setters. The getter of `c` will be called once and then the setter of `b` will be called - will the getter of `b` be called to fetch the value for the setter of `a`? – Oren Oct 22 '15 at 13:32
29

Be aware of the variables scope!!

var A = B = C = 3; //A is local variable while B & C are global variables;
var A = 3 , B = 3, C = 3;// A B C are local variables;
Ma Jerez
  • 4,887
  • 3
  • 23
  • 21
  • this should probably be upvoted more, or incorporated into the accepted answer, since it is not entirely apparent that this is what you may be doing to your global scope – one stevy boi Aug 09 '18 at 16:56
  • 1
    Was going to write the exact answer, be very careful about this pitfall! `typeof A !== 'undefined'`, `typeof B !== 'undefined'` and `typeof C !== 'undefined'` will yield **A undefined** and **B undefined** and **C defined**. Use 'use strict' to get an error so you won't get unexpected behaviors. – Coffee Dec 10 '19 at 19:09
10

It gets evaluted from right to left. i.e.

document.location.hash = this.slug = this.sliceHashFromHref(href)

means the output/value of this.sliceHashFromHref(href) is assigned to this.slug and then to document.location.hash.

Let Me Tink About It
  • 15,156
  • 21
  • 98
  • 207
Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
  • 4
    I mean no offence by this, but I feel as if @aioobe's answer should be accepted as it has been voted better by the community, is more through and (in my opinion) explains it better. I'm sorry if this is taken the wrong way. – David Archibald Dec 16 '16 at 05:49
  • This answer is just wrong... how a value can be assigned to an expression (a = b)? – Max May 25 '18 at 12:55
5

Quite easy... It assigns the result from the call to this.sliceHashFromHref(href) to both document.location.hash and this.slug, so both properties (variables) contain the same value after the line has been executed.

Stefan Gehrig
  • 82,642
  • 24
  • 155
  • 189
4

In Javascript (and several other languages that derive their syntax from C) an assignment evaluates the item to the right of the = symbol and assigns it to the variable on the left. The item on the right can itself be an assignment with an = operator. What happens is the rightmost expression is evaluated, the value assigned to the middle variable, and then that value is assigned to the variable on the left.

In short, it's simply a way to assign a value to multiple variables at once.

GordonM
  • 31,179
  • 15
  • 87
  • 129
2

Actually Ma Jerez's answer makes a very important point here. also this answer refers to this similar question: this question involves a few things:

  1. hoist: variables are hoisted before block code execution;
  2. = assignment order: it goes from right to left;
  3. global context: in non-strict mode, when a variable isn't defined, it goes to the global context; but will throw in 'use strict' mode;

example1:

;(function Anonymous(){
  var a = b = {};
  console.log(a==b); //true
})();
  1. a was hoisted in the Anonymous execution scope.

  2. b is going to be assigned as {}, but because b is not defined, b is assigned to the global context window, then window.b is assigned {}; then window.b = {} returns {}.

  3. local variable a is assigned as {}.

Therefore, a few interesting things happen here: the local variable a and the global variable b both point to the same object {}, so they are == and ===; remember that {}=={} gives false otherwise.

Note: if in strict mode:

;(function Anonymous(){
  'use strict'
  var a = b = {}; //Uncaught ReferenceError: b is not defined
})();

this consecutive assignment won't work the same way...

MartianMartian
  • 1,753
  • 1
  • 18
  • 26