Thursday, August 16, 2007

Javascript vs. C++

I learned C++ recently, so when I saw this Javascript singleton variant making the rounds:

var foo = function() {
  var t = new Date();
  foo = function() {
    return t;
  };
  return foo();
};

...it struck me how much more concise the equivalent C++ solution is:

static Date* foo() {
  static Date t;
  return &t;
}

I do wonder why the author of the Javascript example returns foo() intead of t; it seems like the latter is more straightforward and semantically the same.

5 Comments:

Blogger Ola said...

The author returns foo() instead of t because of closures and scoping rules in JavaScript.

JavaScript doesn't have static variables like C++ so anytime the outer function foo is called, it creates a new instance of the variable t meaning the value is different across invocations.

On the other hand, by returning foo(), with JavaScript closures, the value of t the very first time the function is called is kept across different invocations and that value is returned. This is equivalent to C++'s static keyword.

I have never tried the Singleton pattern in JavaScript before and didn't read the linked to article but the reason why returning foo() works is foo (inner function) is implictly declared in the global scope by not having the keyword var in front of it so it doesn't go out of scope after execution of outer foo.

And I think the neatest part of it is by using the same name foo in the function, it doesn't even have to do the evaluation anymore, the inner foo just replaces the outer foo in the global scope and the value t is always returned.

1:35 AM  
Blogger Nick said...

Having read the article you linked to, and then the article the article you linked to linked to (if you follow my drift), this is actually a pretty neat trick - as Ola mentioned above, the outer foo() method replaces itself with the inner foo() method, thereby caching/memoising its result the first time it is called; this is especially useful when computing expensive values, as it avoids repeating the calculation each time the method is called (think 'lazy initialisation' rather than 'singleton').

The article mentions using this to avoid repeating browser feature detection each time a browser-dependent method is called, but there's no reason this pattern couldn't be used in other situations as well (and other languages?)

2:30 AM  
Blogger Kishore Senji said...

I do not think there is any reason for returning foo() instead of just t. May be just to prove that reference to a function can be changed while the function is being executed.

6:25 AM  
Blogger Kiril said...

JavaScript is a dynamic language (I don't know is this good for beginners??? depends on developer experience) You can find more singleton patterns. Use of patterns depends on the task. You should select the best pattern and use it. As you familiar with Java you can use this experience.
Watch this video "Advanced JavaScript" by Douglas Crockford.

10:15 AM  
Blogger Thomas Frank said...

I had some thoughts on the JavaScript...

In this particular case I would prefer the slightly shorter

var foo = function() {
return foo.t || (foo.t = new Date())
};

although closures are always fun ;-)

Also remember this is an anonymous function assigned to as a reference to a variable, so if we do something like

foo2=foo;
foo=undefined;
foo2();

we're in trouble both with the original code and with my solution.

i could solve this quite easily with my method:

var foo = function() {
var f=arguments.callee;
return f.t || (f.t = new Date())
};

but in the original example it would be a hard nut to crack :-D

6:20 PM  

Post a Comment

<< Home