The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
The trouble with new

0 replies.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a flat view of this topic  Flat View
Previous Topic   Next Topic
Threaded View: This topic has 0 replies on 1 page
Edward Spencer

Posts: 148
Nickname: edspencer
Registered: Aug, 2008

Edward Spencer is a Ruby/Rails developer and the creator of the ExtJS MVC framework
The trouble with new Posted: Sep 8, 2009 8:44 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Edward Spencer.
Original Post: The trouble with new
Feed Title: Ed's Elite blog
Feed URL: http://feeds2.feedburner.com/EdSpencer
Feed Description: Ruby on Rails development, Git issues and ExtJS/JavaScript
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Edward Spencer
Latest Posts From Ed's Elite blog

We have a simple JavaScript class:


function User(firstName, lastName) {
this.name = firstName + " " + lastName;
}

We create a new User:


var ed = new User("Ed", "Spencer");
alert(ed.name); //alerts 'Ed Spencer'
alert(window.name); //undefined

All is well. Unless we forgot the 'new':


var ed = User("Ed", "Spencer");
alert(ed.name); //ed is undefined
alert(window.name); //alerts 'Ed Spencer'

Curses! That's not what we want at all. By omitting the 'new' keyword, the JavaScript engine executes our 'User' constructor in the current scope, which in this case is the global window object. With the scope ('this') set to window, setting 'this.name' is now the same as setting 'window.name', which is not what we're trying to do.

Here's the problem though, omitting the 'new' keyword is still perfectly valid syntax. We know at design time if 'new' must be used or not, and can use a little trick to make it act as though 'new' was indeed used:


function User(firstName, lastName) {
if (!(this instanceof User)) {
return new User(firstName, lastName);
}

this.name = firstName + " " + lastName;
}

Because the 'new' keyword sets up a new context, we can just test to see if 'this' is now an instance of our class. If it's not, it means the user has omitted the 'new' keyword, so we do it for them. John Resig has an example of this over on his blog.

This is all very well and good, but I don't think we should use it. The reason is that we're hiding a pseudo syntax error from the developer, instead of educating them with its correct usage. If we hide this mistake in each class we write, our unknowing developer will remain unknowing, and run into a wall when they repeat their mistake on classes that don't fix it for them.

Instead, I suggest the following:


function User(firstName, lastName) {
if (!(this instanceof User)) {
throw new Error("You must use the 'new' keyword to instantiate a new User");
}

this.name = firstName + " " + lastName;
}

The only difference of course is that we're throwing an Error instead of fixing the developer's mistake. The benefit is that their syntax won't actually work unless they write it correctly. This is good because our erstwhile developer is prompted to fix their code and understand why it was wrong. Better informed developers leads to better code.

Well, hopefully.

Read: The trouble with new


Topic: Webistrano/Capistrano problem with git Previous Topic   Next Topic Topic: Snap Flex Controls To Grid

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use