Friday, December 7th, 2007
Making sure you get new instances in JavaScript
John Resig has posted on simple class instantiation, which delves into the nasty little bug that people can run into:
-
-
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:
-
-
-
// makeClass - By John Resig (MIT Licensed)
-
function makeClass(){
-
return function(args){
-
if ( this instanceof arguments.callee ) {
-
if ( typeof this.init == "function" )
-
this.init.apply( this, args );
-
} else
-
return new arguments.callee( arguments );
-
};
-
}
-
-
var User = makeClass();
-
User.prototype.init = function(first, last){
-
this.name = first + " " + last;
-
};
-
var user = User("John", "Resig");
-
user.name
-
// => "John Resig"
-












Isn’t prototype using a similiar concept?
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.
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.
@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.
sorry I meant to say it shouldn’t be covered up
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.
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.
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()
@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?
@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.
@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.
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.
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.
@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 ;-)
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.
:)
Actually if your creating 100+ objects across multiple files then doing it without “new” can cut down on code bloat.
@Phillips “new” is code bloat? What is next, a function to replace the even more bloated “alert”?
@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?
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.