4
\$\begingroup\$

I'm writing a simple function to transform functions by logging the result before returning it.

The function as written by me:

function loggerise(f) {
   return function() {
      const r = f(...arguments)
      console.log(r)
      return r
   }
}

(fiddle: https://jsfiddle.net/df54npug)

But I'm planning to use it quite heavily, so...

  • Alternatives? Am I doing something stupid?
  • Are there contexts where it won't work? I'm thinking of whether 'this' is preserved for example...

Update 18 June: after testing, the context of the function is not preserved and that is a problem for javascript objects. Full discussion on SO: https://stackoverflow.com/questions/68040912/javascript-write-a-higher-order-function-to-use-the-context-of-the-object-from

But the gist of it is, pass context explicitly:

function loggerise(f) {
   return function() {
      const r = f.apply(this,arguments)
      console.log(r)
      return r
   }
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I don't know if you thought about this, but you can do it also like this:

function logI(f) {
   return function(...arguments) {
      const res = f(...arguments)
      console.log(res)
      return res
   }
}

function func(a1, a2) {
  return a1 + a2
}

logI(func)(12,2)

const obj = {
  m: logI(func)
}

obj.m(12, 2)

which avoids weird apply and context passing. If you need to preserve the context of this, pass fat arrow function into logI.

Edit: Let's dive a little deeper.

class Something {
  private secret = "S"
  public doThings = logI((salt) => this.secret + salt)
}

What doThings actually looks like is this:

class Something {
  private secret = "S"
  public doThings = function(...arguments) {
      const res = ((salt) => this.secret + salt)(...arguments)
      console.log(res)
      return res
   }
}

When you call doThings, this is happening:

something.doThings("salty")

/*
function("salty") {
      const res = ((salt) => this.secret + salt)("salty") --> 
          Basicly you pass the argument directly in the arrow function from the class. 
          Because the origin of the function is the class, the class context of "this" is preserved.
      console.log(res)
      return res
   }
*/
```
\$\endgroup\$
5
  • \$\begingroup\$ +1, but why? And also: why, javascript, why? \$\endgroup\$
    – boisvert
    Jun 20, 2021 at 11:58
  • \$\begingroup\$ @boisvert Do you need a deeper explanation? \$\endgroup\$
    – Blaž Mrak
    Jun 20, 2021 at 13:25
  • \$\begingroup\$ I'm struggling to work out how using function(...arguments) rather than function() would change the context of the call. \$\endgroup\$
    – boisvert
    Jun 20, 2021 at 19:35
  • 1
    \$\begingroup\$ I've extended the answer a bit. Hopefully it answers your question. \$\endgroup\$
    – Blaž Mrak
    Jun 20, 2021 at 20:22
  • \$\begingroup\$ Thanks! Makes sense... insofar as "this" ever does \$\endgroup\$
    – boisvert
    Jun 21, 2021 at 11:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.