Question about the efficiency of closure/encapsulation in JavaScript
I'm somewhat new to JavaScript, so bear with me if this is a dumb question.
Let's say that I've got a "class" that looks like this:
var obj = function () {
var val;
return {
setVal: function(newVal) {
val = newVal;
},
开发者_StackOverflow getVal: function() {
return val;
}
};
};
Assuming my syntax is correct, this defines a class with a "private" property named "value," with methods to set/get the property. Now, I will create two objects from this class:
var myObj = obj();
var yourObj = obj();
Does this create a separate setVal() and getVal() method for each object? If not, why not? If so, is this a serious concern when building efficient web applications? Is the trade-off (if any) of efficiency for closure worth it in most/all contexts? Am I dumb?
Thanks, Gerard
var obj = function () {
var val;
return {
setVal: function(newVal) {
val = newVal;
},
getVal: function() {
return val;
}
};
};
what this function does is as following :
- create variable named
val
- create new object
- create a new function and assign it to field
setVal
- create a new function and assign it to field
getVal
- return object.
So your always creating 4 new things.
This isn't really a problem if you have less then a 1000 objects on the page. Refactoring it away is a micro optimisation.
The alternative would be to not rely on local variables and use this._val
to indicate that val
is private.
It does do so conceptually. However, since this is such a common pattern, modern JavaScript JITers know how to optimize it away so that there is only one copy of the code stored in memory, with appropriate pointer redirections to make it work with the relevant closure.
EDIT: although I am not really up for spelunking through source code, here's some basic proof. Download the Chrome dev channel release, and take heap snapshots before and after running the following code:
var obj = /* as above */;
var objs = [];
for (var i = 0; i < 10000; ++i) {
objs.push(obj());
}
Then do the same for this code:
function Obj() { }
Obj.prototype.setVal = function (value) { this._val = value; };
Obj.prototype.getVal = function () { return this._val; };
var objs = [];
for (var i = 0; i < 10000; ++i) {
objs.push(new Obj());
}
You will find the heap snapshots to show the same numbers for "Code" in both cases, so indeed the optimization I describe is being performed.
精彩评论