0

Is it preferable to use closures instead of instance properties? What is the memory overhead in keeping parent scopes alive, compared to passing properties down as instance properties?

const FooFactory = ({ id }) => {
  const proto = {
    getIdFromClosure() {
      return id;
    },
    getId() {
      return this.id;
    }
  };

  return Object.create(proto, { id: { value: id } });
};

const foo = FooFactory({ id: 123 });  
foo.getIdFromClosure(); // 123
foo.getId(); // 123
Donny Verduijn
  • 424
  • 6
  • 10
  • Possible duplicate of [How do JavaScript closures work?](https://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – Blue Jan 16 '18 at 21:47
  • 1
    If the `id` is associated with the object, I'm not sure why you'd not want it as a property. Is there something compelling you to consider closures for this? Right now you're also creating a separate prototype object for each object you create. As a property, you could then share a prototype too, which is really the point of prototypal inheritance. –  Jan 16 '18 at 21:53
  • While i personally prefer to avoid using the "this" keyword completely, in this case, there is indeed no other reason to use closures. You are right about the separate prototype object creation. To have the benefits of prototypical inheritance, it would have to live on its own. Completely overlooked this fact. Thank you for your help. – Donny Verduijn Jan 16 '18 at 22:13

2 Answers2

1

You can use closure variables to implement information hiding. Properties are like "public" member variables in other languages, they can be accessed directly; e.g. in your example you can use foo.id instead of foo.getId(). A closure variable is not directly accessible from outside the class, so it's like "private" member variables, you have to call a function to access it.

This is useful if you don't want to make the value visible, or if you want to reserve the ability to change how it's represented.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • While i understand closures and its use for private members, you made me think about the idea that instead of using closures to prevent write access, using instance properties through object.create would be a better option. – Donny Verduijn Jan 16 '18 at 22:41
  • There's no difference between using `Object.create` and assigning to `this.id` in the constructor. – Barmar Jan 16 '18 at 22:45
  • You could set writable to false for the instance property, when using the second argument of `Object.create`, but this is a little off-topic. – Donny Verduijn Jan 16 '18 at 23:05
0

It makes no sense to create a prototype object inside a factory. You should use either

function FooFactory(id) {
  return {
    getIdFromClosure() {
      return id;
    }
  };
}

or

const proto = {
  getId() {
    return this.id;
  }
};
function FooFactory(id) {
  return Object.assign(Object.create(proto), {id});
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375