Friday, December 7th, 2007

Making sure you get new instances in JavaScript

Category: JavaScript, Tip

John Resig has posted on simple class instantiation, which delves into the nasty little bug that people can run into:

javascript

  1. var foo = User(...); // forgot to use the "new" operator

The magic “new” changes the scoping, allowing “this” to do the right thing. John walks through an example, and then makes a generic solution:

javascript

  1. // makeClass - By John Resig (MIT Licensed)
  2. function makeClass(){
  3.   return function(args){
  4.     if ( this instanceof arguments.callee ) {
  5.       if ( typeof this.init == "function" )
  6.         this.init.apply( this, args );
  7.     } else
  8.       return new arguments.callee( arguments );
  9.   };
  10. }
  11.  
  12. var User = makeClass();
  13. User.prototype.init = function(first, last){
  14.   this.name = first + " " + last;
  15. };
  16. var user = User("John", "Resig");
  17. user.name
  18. // => "John Resig"

Posted by Dion Almaer at 2:45 am
19 Comments

++---
2.7 rating from 49 votes

19 Comments »

Comments feed TrackBack URI

Isn’t prototype using a similiar concept?

Comment by Thorsten — December 7, 2007

Thorsten : Nop, you still need to use the “new” keyword. But still, I can’t see what’s the point doing that, if the user forgot to do something he * should*, why would you make up his mistake?

The more earlier an error comes out, the easier the debugging will be.

Comment by Samori Gorse — December 7, 2007

What if I don’t want to get a new User?

This misleads to horrible code design and probably future refactoring problems.

If i write a program to print “Helo World”, it should print “Helo World”, not “Hello World”, just as an example.

Comment by dcrec1 — December 7, 2007

@samori

That was exactly what I was thinking when reading this. It is a programmer’s error it should be covered up. This creates a debugging mess.

Comment by Site Smart — December 7, 2007

sorry I meant to say it shouldn’t be covered up

Comment by Site Smart — December 7, 2007

Putting such intelligence into fighting with obvious typing-like errors is some kind of misunderstanding. I’d rather wouldn’t like to work with class system which crucial part trying to repair my mistakes and convince me what I should have in mind instead.

Comment by Krzysztof — December 7, 2007

The performance issue is also considerable almost twice the amount of time to create the instance of a User object.

I share ‘Samori’ point on if the user is not doing what he should why should you clutter your code to make for there stupidity. However that said it is indeed a pretty nice trick.

Really simple benchmark example page below.
John Way:
http://lm.elmuchacho.com/library/tests/makeClass_john_resig/makeClass.htm
Native Way:
http://lm.elmuchacho.com/library/tests/makeClass_john_resig/native.htm

The result speak of itself.

Comment by elmuchacho — December 7, 2007

As always crappy Resig javascript “fixing” where there is no issue.

You want to have var x = new User() ? well, don’t forget the “new”, that’s all, no need for a crappy makeClass()

Comment by Laurent V. — December 7, 2007

@Laurent: I don’t see John as fixing anything but simply trying to build a method of easing some instantiation pains. If you read *his* full post and the comments, it looks like Sebastian Werner (QooxDoo) and Brendan Eich (creator of JS) seem to like his article.

Also, why would you attack John personally? Has he done anything to you for you to lower yourself to name-calling?

Comment by Rey Bango — December 7, 2007

@Rey Bango,

He’s not fixing anything, but there’s still no point in doing such a thing. Maybe I’m missing something, but I can’t see how 3 letters can ease any pain.

Comment by Samori Gorse — December 7, 2007

@Samori: From what I’m gathering from reading the post and knowing John myself, it looks like he’s trying to make it easier for new developers to avoid making a coding error. That’s what I’m seeing. Apart from that, it doesn’t really matter to me if developers don’t find it useful or not. I respect everyone’s opinion and if you don’t think it’s to your benefit, I totally understand. I’m just a bit astonished by some of the vitriol comments that I’ve seen of late. Its as if some people have lost their ability to discuss topics in a calm, collected manner.

Comment by Rey Bango — December 7, 2007

I agree with something in almost all the comments.

First, if ‘new’ fixes things then ‘new’ is the pain free way and I’m afraid John’s suggestion is not practical.

That said, John’s code seems to also be a nifty poc at least. I think it’s pretty damn cool and appreciate getting to see/learn from it. Thx John! I agree wholeheartedly with Rey in having a big fat ? regarding the bad attitude of some in the comments.

Comment by Eric — December 7, 2007

While this is a pretty elegant solution, it promotes bad practice. I agree with Samori that this would be better caught in the debugging phase rather than to provide an crutch that would lead you into making the same mistake over and over. Besides, the best way to get better at a language is to make mistakes and learn from them.

Comment by Andy Kant — December 7, 2007

@Rey Bango : I totally understand you’re point of view, but I don’t think correcting a coding error at the fly would be any help.

I mean, when I write :

if(myvalue=null)

instead of :

if(myvalue==null)

Nothing is telling me I’m doing something wrong, but my conditionnal is always true while this might not be the behaviour expected.
That’s why, I would write :

if(null==myvalue)

And if I’m forgotting a equal sign, I’ll get an error, that’s what errors are for, to be reported. When you do mistakes and learn from them, you’re actually improving you skills.

At least, that’s my opinion.

PS : Sorry for mistakes, I’m French, but I’m learning ;-)

Comment by Samori Gorse — December 7, 2007

So… All this extra code to make up for a rookie developer forgetting to use the new keyword? Only extra code I would for that would be to throw an Error telling the programmer to re-read the JavaScript basics.

:)

Comment by Jeria — December 7, 2007

Actually if your creating 100+ objects across multiple files then doing it without “new” can cut down on code bloat.

Comment by Chris Phillips — December 7, 2007

@Phillips “new” is code bloat? What is next, a function to replace the even more bloated “alert”?

Comment by Jeria — December 8, 2007

@Rey Bango

I think you should have read my small comment as well I’m not insulting John but instead complimented him on the trick. The reference to developer stupidity was not directed at John but at developer in general even me when I make mistake like forgetting the ‘new’ I call myself stupid.

My comment did sound a bit firing but at the concept for a simple reason that I don’t think it will help using it as a generic method to declare your classes in this manner as the performance result will be un-acceptable in a production environment. But hey that’s just me let’s ask John if he think that increasing by approx 60% the instance creation time is acceptable?

Comment by elmuchacho — December 8, 2007

Whenever I read one of Johns articles it provides a new insight and some coding pattern learning. Maybe not for me all the times but for many at least. What John really shows in his articles is how versatile JS is – and he is really good in quenching the most out of this language.
So the real value of this is not whether you should use it or not, but what you can learn from it.

Comment by Frank Thuerigen — December 8, 2007

Leave a comment

You must be logged in to post a comment.