开发者

Renaming the 'this' keyword

I'm concerned that I mig开发者_运维技巧ht be using a code pattern that leaks memory. Here's a pseudocode example:

window.user = new User(); 

user.getBasicInfo(function(basicInfo){

  user.name = basicInfo.name;

  user.getDetailedInfo(function(detailedInfo){

    user.favoriteColor = detailedInfo.favoriteColor;

  });

});

In other words, I'm not using the 'this' keyword to refer to the user object; I'm referring directly to the user object stored within the window object.

Obviously, the JavaScript 'this' keyword has given lots of people lots of trouble. I've seen some people rename 'this' to make it more clear as they descend a scope chain:

window.user = new User(); 

user.getBasicInfo(function(basicInfo){

  var userInOuterScope = this;    
  userInOuterScope.name = basicInfo.name;
  userInOuterScope.getDetailedInfo(function(detailedInfo){

    var userInInnerScope = this;
    userInInnerScope.favoriteColor = detailedInfo.favoriteColor;

  });

});

Not as pretty, but it seems like the scope chain might be less convoluted in that case.

Can the first approach leak memory? Can the second? To avoid leaking memory, must I pass everything as a parameter (and never refer to objects outside of the current scope)?


The potential to "leak memory" is not something relevant to the question you seem to be asking. That is, neither of the approaches have implications on memory use, at least not in any way clear to me.

The reason you might prefer to make use of the this facility in your code is that you might want a population of objects. In your case, you're apparently using the object as a singleton, so it makes no difference. However, that's really a special case, and you'd quickly find that it doesn't work so well if you've got 100 "User" objects.

Preserving the value of this (and it's not really "renaming" this; it's copying its value into another variable) inside a closure could result in a memory leak, or rather, could be part of a larger memory-leaking setup, but it's not problematic in and of itself. Making copies of object references is something that happens all the time.

edit — the "leakage" problem with closures comes about when a combination of things happens:

  1. Some objects are referenced by variables in the closure scope (not weird or harmful in and of itself);
  2. Functions with references to the closure scope "escape" from a function call, either by being returned or by being exported via global state side-effects (like registering an event handler) (also not weird or harmful in and of itself);
  3. The population of these exported functions grow, or the functions themselves allocate more room when they're invoked and preserve references to the space allocated in the closure, or the exported functions end up directly referenced by DOM nodes (this is particularly a problem in IE).

Really, JavaScript doesn't have any unique problems with memory leaks that any language with real closures has. For a vast amount of actual JavaScript software in this world (utility code wired into web pages), it's pretty rare that memory leakage is a problem, I suspect, though the IE issue with DOM references has probably crashed a few browsers over the years (which probably hardly surprised the hapless users).

I don't like pushing frameworks on people, but it's definitely true that framework authors must worry about this stuff. Trusting in your framework to keep the DOM clean by making sure you only attach event handlers and data to the DOM via framework facilities is therefore a Good Idea.


It doesn't appear that you have any circular references in your code, so I wouldn't worry about memory leaks. You're not setting objects equal to other objects as far as I see ( http://jsfiddle.net/Akkuma/UTL3B/ as a quick example how it could lead to memory leaks).

Here are a few references on memory leaks

  • http://www.ibm.com/developerworks/web/library/wa-memleak/
  • http://www.javascriptkit.com/javatutors/closuresleak/index.shtml
  • http://javascript.crockford.com/memory/leak.html

Additionally, you can use Chrome's Heap Snapshot tool to be able to tell whether or not you are having memory leaks worth worrying about.


JavaScript's this is not the same this like Java's or C#'s. It represents the current context of something being executed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜