Meaning of (x => x) in JavaScript arrow function using array.every() method

Viewed 136

looking for an explanation on this line of code. I understand arrow functions to a degree. The purpose of this code snippet/challenge is; "Given any number of parameters, return true if none of the arguments are falsy." I've seen the solution like this:

const nothingIsNothing = (...args) => args.every(x => x)

Examples of arguments and the expected results are:

nothingIsNothing(0, false, undefined, null) ➞ false

nothingIsNothing(33, "Hello",  true,  []) ➞ true

nothingIsNothing(true, false) ➞ false

I just don't understand how the section (x => x) evaluates to either truthy or falsy. Can someone explain how this works? I hope this makes sense lol. Thanks!

5 Answers

With .every, if any of the return values from the callback are falsey, the .every evaluates to false, otherwise it evaluates to true. So x => x as a callback means: take every value in the array and return it immediately. If all are truthy, the whole .every evaluates to true, else false.

It's doing the same logic as this:

const nothingIsNothing = (...args) => {
  for (const arg of args) {
    if (!arg) return false;
  }
  return true;
};

Or, implementing something similar to .every yourself:

// don't do this in real code, this is just an example

Array.prototype.myEvery = function(callback) {
  for (const item of this) {
    if (!callback(item)) return false;
  }
  return true;
};

console.log([1, 2, 3].myEvery(x => x));
console.log([1, 2, 3, 0].myEvery(x => x));

Its a combinations of a couple of things

  1. Javascript implicit return statement.

getVal = a => a;

is the same as

function getVal(a) { return a }
  1. every web API method run until it encounters a falsy (not false) value. Below is a quote from MDN.

The every method executes the provided callback function once for each element present in the array until it finds the one where callback returns a falsy value. If such an element is found, the every method immediately returns false. Otherwise, if callback returns a truthy value for all elements, every returns true.

param => param is the same as (param) => { return param }

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

These are all the falsy values in JavaScript: https://developer.mozilla.org/en-US/docs/Glossary/Falsy

The documentation for the return value of every states the following:

true if the callback function returns a truthy value for every array element. Otherwise, false.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every

So something like this will be false as not all elements are truthy

const x = ['test', 0, null, -0].every(el => el);
console.log(x);

But something like this will return true as all elements are truthy values

const x = ['test', 1, 'hi', 10].every(el => el);
console.log(x);

As per the docs the every() method tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value i.e true if the callback function returns a truthy value for every array element. Otherwise, false.

const nothingIsNothing = (...args) => args.every(x=>x) can be expanded to:

const nothingIsNothing = (...args) => args.every(function(x){
if(x)
  return true
else 
  return false
})

Here is another version which will help you understand the shorthand better. The value x is typecasted to a boolean and true/false is returned.

const nothingIsNothing = (...args) => args.every(Boolean)
console.log(nothingIsNothing(0, false, undefined, null))
console.log(nothingIsNothing(33, "Hello",  true,  []))

The Array.prototpe.every() does the heavy lifting here.

The every() method tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value.

The PolyFil following the ECMA-262, 5th specification, assuming Object and TypeError have their original values, and that callbackfn.call evaluates to the original value of Function.prototype.call, demonstrate the internal behavior nicely:

Array.prototype.PolyFillEvery = function(callbackfn, thisArg) {
  'use strict';
  var T, k;

  if (this == null) {
    throw new TypeError('this is null or not defined');
  }

  // 1. Let O be the result of calling ToObject passing the this 
  //    value as the argument.
  var O = Object(this);

  // 2. Let lenValue be the result of calling the Get internal method
  //    of O with the argument "length".
  // 3. Let len be ToUint32(lenValue).
  var len = O.length >>> 0;

  // 4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  if (typeof callbackfn !== 'function' && Object.prototype.toString.call(callbackfn) !== '[object Function]') {
    throw new TypeError();
  }

  // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
  if (arguments.length > 1) {
    T = thisArg;
  }

  // 6. Let k be 0.
  k = 0;

  // 7. Repeat, while k < len
  while (k < len) {

    var kValue;

    // a. Let Pk be ToString(k).
    //   This is implicit for LHS operands of the in operator
    // b. Let kPresent be the result of calling the HasProperty internal 
    //    method of O with argument Pk.
    //   This step can be combined with c
    // c. If kPresent is true, then
    if (k in O) {
      var testResult;
      // i. Let kValue be the result of calling the Get internal method
      //    of O with argument Pk.
      kValue = O[k];

      // ii. Let testResult be the result of calling the Call internal method 
      // of callbackfn with T as the this value if T is not undefined 
      // else is the result of calling callbackfn 
      // and argument list containing kValue, k, and O.
      if(T) testResult = callbackfn.call(T, kValue, k, O); 
      else testResult = callbackfn(kValue,k,O)

      // iii. If ToBoolean(testResult) is false, return false.
      if (!testResult) {
        return false;
      }
    }
    k++;
  }
  return true;
};

const arFalsey = [0, false, undefined, null];
const arTruthy = [33, "Hello",  true,  []];

console.log(arFalsey.PolyFillEvery(x=>x)); //false
console.log(arTruthy.PolyFillEvery(x=>x)); //true
console.log([true,false].PolyFillEvery(x=>x)); //false

The crucial part is if-clause in the inside of the loop:

// iii. If ToBoolean(testResult) is false, return false.
if (!testResult) {
  return false;
}

As soon as one of the elements is not tested truthy false is returned; the spread (...) expression is simply used to iterate the array and instead of a traditional function an arrow function x => x is used to feed (via return) each element as is to the test in the every function.

Related