1

Let's say I've got two functions a and b that I want to be visible within a given functional scope. They share some common functionality, so I factor the common code out into a third method called support.

support needs to be callable by both a and b, but I don't want it to be visible to other methods at this scope. Is this possible?

// Some scope; maybe global, maybe another function

function a() {
  let res = support()
  res.name = "a"
  return res
}

function b() {
  let res = support()
  res.name = "b"
  return res
}

function support() {
  return {"foo": "bar", "name": "support"}
}

I came up with an idea while writing that I'll post as an answer, but it's not quite what I'm looking for, as a and b become function expressions, rather than behaving like regular function declarations (if I'm using the right terminology).

Lovethenakedgun
  • 731
  • 6
  • 22
  • *"I don't want it to be visible to other methods at this scope"* why? – Felix Kling Jun 17 '21 at 14:23
  • @FelixKling Was really more of a thought experiment & wondering how JS worked than relating to something practical. Catalyst was looking at a codebase that contained hundreds of global JS functions in files that are imported in various places & in various orders across a huge .NET project. Was looking at general refactoring first (as there's many chunks of just straight-up duplication), but then this question popped into my head. – Lovethenakedgun Jun 17 '21 at 14:38

1 Answers1

1

Came up with this while writing, so I figured I'd post it as an "answer", but it's not exactly what I was asking. I created an immediately invoked function expression & returned the functions a & b and assigned them to the variables "a" and "b" at the correct scope.

let [a, b] = (function(){ 

  function support() {
    return {"foo": "bar", "name": "support"}
  }

  function a() { 
    let res = support()
    res.name = "a"
    return res 
  }
    
  function b() { 
    let res = support()
    res.name = "b"
    return res 
  }

  return [a, b]
})()

So at that upper scope, a and b can be called, but support is inaccessible. But these top level [a, b] aren't function declarations; they're variables containing function expressions (I think). I can't call a() before assigning the variables; if a actually was a function declared in this scope, it'd be hoisted, and I'd be able to. I have a sneaking suspicion that what I'm asking is impossible, so leaving this as the closest I could come up with.

Lovethenakedgun
  • 731
  • 6
  • 22
  • 1
    There is not really any relevant difference between function expressions and function declarations at runtime. Both result in function objects. But you are right that there is a difference between *when* those function objects are created. You can only "hide" things by creating scope and there are not many things that create scope. Maybe have a look at modules? – Felix Kling Jun 17 '21 at 14:22
  • @FelixKling Thanks for the suggestion. Looking at https://stackoverflow.com/questions/35223111#answer-35225936 it seems like functions imported from modules are indeed hoisted. As I understand it, hoisting seems to be the only major difference; is that fair to say? – Lovethenakedgun Jun 17 '21 at 14:34
  • Yep, the main difference between a function declaration and assigning a function expression to a variable is the *time* when each function definition is evaluated, which in turn affects when it can be accessed. Function declarations are always evaluated before any other statement or expression in that scope is evaluated, so calls to those functions can occur before the actual definition. – Felix Kling Jun 17 '21 at 14:45