0

Bit of a weird one. I'm fascinated with the context object in Azure, although I have not been able to find the full source code for it.

When using it within Azure function apps, you can do both context.log and context.log.error. I'm trying to replicate this in a local mock like so:

let context = {
  log(message){
    console.log(message)
  },

  log: {
    info: console.log,
    error: console.error
  }
}

But clearly the second log property overrides the function so I can't do both context.log and context.log.error.

I also tried

let context = {
  'log': console.log,
  'log.error': console.error
}

But here, context.log.error is undefined, however context['log.error'] works.

Eventually, I found one that does work:


let context = {
  'log': console.log,
}
context.log['error'] = console.error
context.log['info'] = console.log

Which does do what i want:

context.log('message') // prints 'message'
context.log.error('message') // prints error 'message'

But I would like to understand why that last bit worked, and additionally, how I can declare all of it in one go instead of relying on context.log[error] = value

Darshan
  • 937
  • 3
  • 15
  • 27
  • 1
    In js, functions are objects. In other words, `function f() {}; f.myProperty = 0;` is valid. – ASDFGerte Apr 15 '21 at 14:32
  • 1
    Just as an additional mention to avoid pitfalls: an answer below already wrapped things in a new function. That's because in your last version, after your assignments, e.g. `console.log.error === console.error`, so you are bleeding into native APIs, which is often undesirable. That's to be expected, given that you assign on the function itself, but i better mention it anyways. – ASDFGerte Apr 15 '21 at 14:52
  • 1
    Oh that's a great catch, yeah. Just to make sure I'm getting this right: I assigned a native function (console.log) to context.log, then I added a property to it via ````context.log['error'] =```` . Which is why the answer below is instead creating a new function to which these properties are being passed, right? Nice! Thank you! – Darshan Apr 15 '21 at 15:08
  • I guess you are using Azure functions with Javascript and ran into this. – SijuMathew Jul 07 '21 at 08:18

1 Answers1

0

You want to create a function object, and then assign properties to that. You can do that in the object literal with Object.assign:

 {
    log: Object.assign(function log() { /*...*/ }, {
       error() { /*...*/ },
    }),
 }
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • Fascinating! I see, so since functions are objects in JS, you can actually assign properties to them, and a way to do this would be to use Object.assign? – Darshan Apr 15 '21 at 14:42
  • Exactly. That's also why your third version works. – Jonas Wilms Apr 15 '21 at 14:43
  • This comment + @asdfgerte's explanation above answered the question nicely. I also found this stackoverflow question which expands on it further: https://stackoverflow.com/questions/8588563/adding-custom-properties-to-a-function/20734003 – Darshan Apr 15 '21 at 15:16