Closures vs. classes for encapsulation?

北城余情 提交于 2019-12-02 20:28:21
Raynos

The reasons to avoid closures is overhead.

Your get and set functions are trivially 20x slower than properties. Your closures also have a large memory overhead that is O(N) with the number of instances.

Also note that these encapsulated variables have zero real benefit, they just infer performance penalties.

var AddProperty = {
  constructor: function (v) { this._value = v; return this; },
  get: function () { return this._value; },
  set: function (v) { this._value = v; }
};

var a = Object.create(AddProperty).constructor(1);
var b = Object.create(AddProperty).constructor(2);

I noticed yesterday that this doesn't work, because my JS code doesn't keep any private state for each tab.

Your problem is not that you don't have private state, it's that you're using global state.

The easy solution is to have an object per tab (or a "struct" if you prefer) and store state in it.

So all you have to do is define a tab

var Tab = {
  constructor: function (...) {
    /* init state */
  },
  doTabStuff: function () { /* some method */ },
  ...
}

And then create new tabs when you need them

var tab = Object.create(Tab).constructor(...)

The benefit of a function for the purposes of encapsulating functionality is that you can use the module pattern:

http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

The module pattern provides the capability of creating private members and methods, without something with a lot of overhead like ease.js:

http://easejs.org/

This is an old question, but there are a few things the answers are missing so I figure I'd add to this.

First, as commenters love to point out, there aren't any real classes in javascripts, we just mimic them with closures. Here's what the javascript tutorials call a "class:"

function Class1(){
    var privateState='blah';
    this.get=function(){
        return privateState;
    }
}
var myObj=new Class1();

Importantly, the get method is just a closure. So, this is basically the same as your code. Because closures must reference the environment in which they were created (this is how they can use the private internal state data), they are more costly than just using a public function. So if you have a static method that doesn't require the internal state, you should add it to Class1 instead by using the prototype key word:

Class1.prototype.staticMethod=function(){...};

This way, the static method can be used through the prototype chain without using up extra memory with unnecessary closures. You could also achieve this with your method by adding static methods outside of your AddPropertyfunction.

So, in the end the only difference between a formal javascript "class" and your AddProperty function is that when you actually use the class constructor, the class appears in the object's prototype chain, whereas your objects just inherit directly from the generic object prototype. You could certainly write code that uses this distinction, but that would probably be bad code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!