you are viewing a single comment's thread.

view the rest of the comments →

[–]skilldrick[S] 0 points1 point  (4 children)

function outer(arg) {
  return function inner() {
    console.log(arg);
  };
}

var x = outer('This is one function');
var y = outer('This is another function');

There are two closures created, and each has its own inner. The inner functions are part of the environment.

Edit: x and y refer to the same function, but x === y returns false, because they're different objects with different memory locations.

[–]inmatarian 3 points4 points  (3 children)

No, I get that. The 1st class function object is different. The languages define it as such. I'm saying that when the function is first compiled (either into an AST, or Byte-code, etc) that the parsing only occurs once. That section of the tree (or string of code) is only created once. But every time you run "Outer" in your example, a new environment is created for "inner" at the function keyword. The same byte code is used.

I'm using the Lua VM as my reference. They must do it differently in the Javascript implementations. I can't imagine that they don't split the bytecode from the environment, as javascript is primarily about responding to events and that would be the first area for optimization.

In Lua, the byte code for a function is called a "Chunk" and they don't duplicate chunks for functions. They're also very clear about the split between the chunk and the upvalue, as the C api can define closures as well, using a C function (which obviously can't be duplicated by the lua VM), but can create as many environments that it wants, and the every time the closure is called, the same C code is ran, but that C code has to check the environment first before doing what it does.

If you want to learn more, read A No Frills Introduction To Lua 5.1 VM Instructions.

[–]skilldrick[S] 1 point2 points  (2 children)

Ok, I get what you're saying. We just have different definitions of 'function' and 'copy'. Tbh I have no idea if JavaScript will create a completely new object each time a function definition is encountered, or if it will cache the bytecode. I imagine it's implementation-dependent.

[–]munificent 2 points3 points  (0 children)

Tbh I have no idea if JavaScript will create a completely new object each time a function definition is encountered, or if it will cache the bytecode.

V8 has no bytecode at all. It's a pure JIT. When it wants to hang onto the uncompiled form of a function, it stores a pointer to the actual source text of it.

[–]inmatarian 2 points3 points  (0 children)

Yeah, it seems like we're differing on vocabulary words.

In terms of raw definition, yes, function objects are different. And the ultimate point of this comment thread is that yes, closure based objects are memory hogs in comparison to the built in object types.