Search code examples
javascriptnode.jsfunctionloopsdeclare

Redeclare variables defined in global scope with a loop


I am trying to redeclare variables defined in global scope. I'd like to wrap each function

const {values, map, each} = require('lodash')

const wrapFnInLog = (fn) => (...input) => {
  console.log({name: fn.name, input})
  const possiblePromise = fn.apply(null, input)
  if (get(possiblePromise, 'then')) {
    return possiblePromise.then(output => {
      console.log({name: fn.name, output})
      return output
    })
  } else {
    console.log({name: fn.name, output: possiblePromise})
    return possiblePromise
  }
}

let a = (arr) => map(arr, i => i.name)
let b = (obj) => a(values(obj))

const provide = [a, b]

provide.forEach(fn => wrapFnInLog(fn))

const example = {
  personTom: {
    name: 'Tom'
  },
  personJerry: {
    name: 'Jerry'
  }
}

b(example)

I'd like the output to look like this:

{ name: 'b', input: [ { personTom: [Object], personJerry: [Object] } ] }
{ name: 'a', input: [ [ [Object], [Object] ] ] }
{ name: 'a', output: [ 'Tom', 'Jerry' ] }
{ name: 'b', output: [ 'Tom', 'Jerry' ] }

The only way I've been able to achieve this is without a loop and it's via deliberately overwriting each variable one by one.

a = wrapFnInLog(a)
b = wrapFnInLog(b)

I'm wondering if it's possible to loop over [a, b] and overwrite the function definition, while keeping them in global module scope.


Solution

  • as already commented, you can use a destructuring assignment to assign multiple variables at once

    let a = (arr) => map(arr, i => i.name);
    let b = (obj) => a(values(obj));
    
    [a,b] = [a,b].map(wrapFnInLog);
    

    but unlike a destructuring assignment in combination with a variable declaration (let [a,b] = ...) you have to be careful what you write before this assignment and that you properly seperate commands.

    Because with automatic semicolon insertation or, JS not inserting a semicolon where one should be,

    let a = (arr) => map(arr, i => i.name)
    let b = (obj) => a(values(obj))
    
    [a,b] = [a,b].map(wrapFnInLog)
    

    will be interpreted as

    let a = (arr) => map(arr, i => i.name);
    let b = (obj) => {
      return a(values(obj))[a,b] = [a,b].map(wrapFnInLog);
    }
    //or in other words
    let b = (obj) => {
      let tmp1 = a(values(obj));
      a; //the `a,` in something[a,b];
      let tmp2 = [a,b].map(wrapFnInLog);
      tmp1[b] = tmp2;
      return tmp2;
    }