denysdovhan / wtfjs

🤪 A list of funny and tricky JavaScript examples
http://bit.ly/wtfjavascript
Do What The F*ck You Want To Public License
34.97k stars 2.55k forks source link

code does not what you think! Or am I the only one? #76

Closed L2L2L closed 3 years ago

L2L2L commented 6 years ago

Ran into this while coding... What do you think the below code will do?

var arr = [1,2,3,4,5,6,7,8,9];
function wtfJS(){
  let num, num2, els = arr, 
      len = els.length, 
      el = els[num = Math.floor(Math.random()*len)], 
      el2 = els[
        (num =! (num2 = Math.floor(Math.random()*len)))
        ?num2:num?--num:++num];
  console.log(num,num2,el, el2);
}

It'll either print out 1 # # 2 or true # # 1. The # # are other number that is not important. What is, is the print of "true" or "1" through the num variable which in turn give me either 1 or 2 through the el2 variable. I think it got something to do with coercer in the turner operand.

function okayJS(){
  let num, num2, els, len, el, el2, animLghts;
  els = arr; 
  len = els.length;
  num = Math.floor(Math.random()*len);
  el = els[num];
  num2 = Math.floor(Math.random()*len);
  if (num == num2) num2 = (num?--num:++num);
  el2 = els[num2];
  console.log(num,num2,el, el2);
}
elxris commented 6 years ago

You are not writting equivalent code, because in the first you are using the =! operator and store it in num variable. Then you use the ternary operator, and in the false condition of the operator you are using another ternary operator, but, if you are reaching the false side of the first operator you are always running ++n wich is leads something like false + 1 => 0 + 1 => 1. This is the actual rewrite of the first function:

function okayJS2() {
  let num, num2, els, len, el, el2;
  els = arr;
  len = els.length;
  num = Math.floor(Math.random()*len);
  el = els[num];
  num2 = Math.floor(Math.random()*len);
  num =! num2 // This is an assigment operator and coerces the value to boolean
  if (num) el2 = els[num2]
  else el2 = els[++num] // Wich always is the 1-index wich is the number 2
  console.log(num, num2, el, el2)
}