0

Could use some feedback on a Saturday afternoon object composition/closure investigation (is it accurate, is it missing any key points, non-key points, can you help answer remaining questions/provide resources to do so). Thanks in advance :)

run here: https://www.typescriptlang.org/play#code/ or in some typescript debug env or remove all typings and run in node

interface Inner {
  (closureScopedInput?: string): string
}

function outer(input: string): Inner {
  debugger
  console.log('input:', input);
  return function(closureScopedInput: string | undefined) {
    debugger
    console.log('closureScopedInput changing:', closureScopedInput);
    
    return `output = ${input} ${closureScopedInput}`     
  }
}
const setClosureScope = outer('1')
console.log('example1:', setClosureScope('2'))
console.log('example2:', setClosureScope('3')) 
console.log('example3:', setClosureScope('4')) 
console.log('example4:', setClosureScope('5')) 

questions:

  • why is the first debugger/console.log('input:', input) hit only when outer is expressed as setClosureScope, and not on every subsequent setClosureScope call when new values are passed in?
  • how does this memory storage actually work with regards to scoped execution context and memory references?

conclusions:

when the function outer is expressed as variable setClosureScope:

  • the value passed into the outer function is stored in memory as a closure scope
  • This technique/methodology of wrapping data in closures is: - common in object composition - powerful because it locks data down to the scope of nested closures inside objects that encapsulate these data properties as members
coreycosman
  • 315
  • 2
  • 7
  • 1
    You call `outer('1')` only once, but you call `setClosureScope()` 4 times... When you call `setClosureScope`, there is no reason for `outer` to be executed again – blex Jul 06 '20 at 17:36
  • @blex I see, are you able to elaborate on how does this memory storage actually work with regards to scoped execution context and memory references? I am confused about what is actually going on here. You express function as variable, but if that function returns a function the variable will represent only the most inner function in memory? Meaning that variable will create a new namespace in memory for the inner function? Why does this happen? Why does the fact that a function returns a function dictate that it should reference most inner function instead of function that was expressed? – coreycosman Jul 06 '20 at 18:00
  • I don't think I can explain it any better than [this answer](https://stackoverflow.com/a/111111/1913729). As for _"Why does the fact that a function returns a function dictate that it should reference most inner function"_ well, it does not dictate anything, it would be exactly the same if the outer function returned `42` instead of a function. If you do `var x = foo();`, `x` is going to be the value returned by `foo()`. In your example, that result happens to be a function. And that function captured the outer function's lexical environment – blex Jul 06 '20 at 18:07
  • My knowledge is limited, I don't have an answer to all of your questions (especially the "memory" & "storage" you are referring to). The answer I linked to should help you understand at least a couple of notions, but if some of your questions are left unanswered, I would advise you to ask one question at a time, to have more chances of getting good answers – blex Jul 06 '20 at 18:20
  • @blex when we express setClosureScope as outer('1') the value of that variable is actually a whole execution context, not just the function itself, rather this is always happening when functions are either declared or expressed, so that each memory namespace stores the whole function object, along with its scope chain. This seems to be clear now. Thanks for your help! – coreycosman Jul 06 '20 at 18:52

0 Answers0