Blog

How Good C# Habits can Encourage Bad JavaScript Habits: Part 1

This is the first post in a multi-part series covering common mistakes C# developers tend to make when they first start writing JavaScript.

Introduction

Many people come to jQuery and believe that their knowledge of a previous classical language (C#, Java, etc) will help them be successful at client-side scripting. You can use your classical language skills to accomplish a large amount of functionality with jQuery. However, the more client-side code you write you will find yourself uncovering strange bugs because you didn’t take adequate time to learn JavaScript properly.

“…it turns out that if you have absolutely no idea what you’re doing in the language you can still generally make things work.” –Douglas Crockford, Yahoo!’s JavaScript Architect, Douglas on JavaScript — Chapter 2: And Then There Was JavaScript

This article is targeted for developers that use jQuery but haven’t invested the time necessary to learn JavaScript. The intent is to help you avoid some common mistakes when moving from a classical language (Java, C#, etc) to JavaScript.

jQuery is a library that is written in JavaScript. It is important to remember that you will always be writing in JavaScript when using jQuery. It is inevitable that you will run into native JavaScript concepts that are foreign to the classical language proficient developer. Taking the time now to be proficient in JavaScript will increase your client-side code quality, efficiency, and decrease code maintenance.

Bad Practices

1. Having Variables & Functions in Global Scope

A best practice in C# is to limit the use of global variables. This doesn’t necessarily translate into a bad practice in JavaScript, but most C# developers are not aware of how easily it is to pollute the global namespace with needless variables and functions.

One way you can pollute the global namespace is to not declare your variables. In JavaScript, if you don’t declare your variables then they become globally available to the rest of the program, which is probably not what you wanted and generally a bad idea.

Coming from a C# background, you are most likely used to the concept of namespacing your classes so they won’t clash with other libraries. In the same way you should be mindful to not declare variables or functions in the global namespace to prevent clashing with other libraries, browser extensions, and also your own code.

Bad Practice

The following code shows some bad examples of how to declare variables and functions.

 var iAmGlobal = "Keep these to a minimum";

iAmGlobalToo = "Bad";

function oldSchoolWay() { //Placed in global scope when executed
  iAmGlobalNooo = "Really Bad";
  console.log( 'Bad oldSchoolWay Function' );
}

//Bad way to prevent namespace clashing
function namespace_oldSchoolWay() { console.log( "Worse oldSchoolWay Function" ); }

//Functions window.oldSchoolWay();
window.namespace_oldSchoolWay();

//Global variables are available off window object console.log( window.iAmGlobal );
console.log( window.iAmGlobalToo );
console.log( window.iAmGlobalNooo );

You can execute and modify the above code from jsFiddle.

In the above code snippet you’ll see that the iAmGlobal, iAmGlobalToo, and iAmGlobalNooo are all global variables. You would expect iAmGlobal and probably iAmGlobalToo to be global variables, but the variable inside the oldSchoolWay function is also global because it was never declared! The best way to stay out of this trouble is to be disciplined and declare all of your variables and not let JavaScript do it for you.

Klaus Komenda actually refers to the function statement as the Old School Way of function declaration. I’ve even seen C# developers trying to prefix their function names (as shown above by namespace_oldSchoolWay) to minimize collisions with other libraries, but you should not do this. That technique still clutters the global namespace.

There are many options to fix this problem, but the simplest is to create a namespace object and then declare all your functions and properties within it. See the following code snippet for a slightly better approach.

Object Literal (All Public)

An Object Literal is a convenient way to create new objects. The syntax looks very similar to what you might expect to see in JSON (JavaScript Object Notation), but they are actually quite different. For more information about this you can check out an in-depth discussion on it by Ben Alman entitled There’s no such thing as a “JSON Object”.

When you create an Object Literal you can provide properties and methods and they can refer to each other. You can also add additional methods and properties to the object after it has been defined. All the properties and methods that you declare in the Object Literal are publicly accessible to the rest of your JavaScript code.

 //Object Literal declaring properties and methods 
var skillet = { 
  //public property 
  ingredient: "Bacon Strips",

  //public method
  fry: function() {
    console.log( 'Frying ' + this.ingredient );
  }
}; 

console.log( skillet.ingredient );  //Bacon Strips 

skillet.fry(); 
//Frying Bacon Strips

//Adding a public property to an Object Literal 
skillet.quantity = "12"; 
console.log( skillet.quantity ); //12

//Adding a public method to an Object Literal 
skillet.toString = function() { 
  console.log( this.quantity + " " + this.ingredient ); 
}; 

skillet.toString(); //12 Bacon Strips​ 

You can execute and modify the above code from jsFiddle.

The above code declares a skillet variable and sets it to an Object Literal with one property (ingredient) and one method (fry) that are both publicly accessible off of the object. You can also add additional public methods and properties to the object after the initial declaration as shown above when adding the quantity property and the toString method. The toString method is able to access the properties of the skillet object since all of it’s parts are public.

Pros

  • Cleans up the global namespace by adding a namespace to your properties and methods
  • You can add functionality to the object literal at a later point
  • All the properties and methods are public

Cons

  • Uses the Object Literal syntax to define your properties and methods that some may find cumbersome
  • There isn’t the ability to have private properties or methods

Self-Executing Anonymous Function: Part 1 (All Private)

Another common technique that you can use to protect the global namespace is to use a Self-Executing Anonymous Function. This is just a fancy term to refer to a function with no name that is immediately executed after it’s defined. The value of this technique is that you can create a wrapper around your code that protects it from the global namespace. By using the most simple version of the Self-Executing Anonymous Function you can create code that is exclusively private.

 //Self-Executing Anonymous Function: Part 1 (All Private) 
(function() { 
  //private variable 
  var ingredient = "Bacon Strips";
  
  //private function
  function fry() {
    console.log( 'Frying ' + ingredient );
  }

  fry();
}());

//Variables not accessible 
console.log( window.ingredient ); //Undefined

//Functions not accessible 
try { 
  window.fry(); //Throws Exception 
} catch( e ) { 
  //Object [object DOMWindow] has no method 'fry' 
  console.log( e.message ); 
}

//Can't add additional functionality 

You can execute and modify the above code from jsFiddle.

The above code snippet wraps the ingredient variable and fry function with a Self-Executing Anonymous Function and right before the function ends it executes the fry method. After the Self-Executing Anonymous Function finishes executing there is no way to run the function again or reference any of the internals of the wrapped code.

Pros

  • Hides all your implementation from external code
  • The function runs once and only once
  • The code inside doesn’t use the Object Literal notation

Cons

  • All information is hidden, which may not be what you want
  • Slightly more complicated technique, but not really

Revealing Module Pattern (Public & Private)

The Revealing Module Pattern actually uses the concept of the Self-Executing Anonymous Function as well, but in this case we save the result into a variable. This pattern introduces the concept of a Closure. A closure is a way to keep variables alive after a function has returned. The Mozilla Developer Network has a great page explaining closures. In it they provide a core definition:

“A closure is a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created.”

In the following example we will declare private properties and methods as well as public properties and methods.

 //Revealing Module Pattern (Public & Private) 
var skillet = (function() { 
  var pub = {}, //Private 
      property amountOfGrease = "1 Cup";

  //Public property
  pub.ingredient = 'Bacon Strips';

  //Public method
  pub.fry = function() {
    console.log( 'Frying ' + pub.ingredient );
  };

  //Private method
  function privateWay() {
    //Do something...
  }

  //Return just the public parts
  return pub;
}());

//Public Properties 
console.log( skillet.ingredient ); //Bacon Strips

//Public Methods 
skillet.fry();

//Adding a public property to a Module 
skillet.quantity = 12; 
console.log( skillet.quantity ); //12

//Adding a public method to a Module 
skillet.toString = function() { 
  console.log( skillet.quantity + " " + skillet.ingredient + " & " + amountOfGrease + " of Grease" ); 
};

try { 
  //Would have been successful, 
  //but can't access private variable 
  skillet.toString(); 
} catch( e ) { 
  console.log( e.message ); 
  //amountOfGrease is not defined 
} 

You can execute and modify the above code from jsFiddle.

Inside of the Revealing Module Pattern we declared a pub object that will keep all the public properties and methods that you want to be exposed. At the end of the Module the pub object is returned, which is what causes the them to be public outside of the Self-Executing Anonymous Function. All the parts that were not added to the pub object remain private to the outside world; however, the public methods that were exposed have access to the private parts because of the Closure that was created.

Pros

  • Allows for public and private properties and methods
  • The Technique is Easy to understand
  • The code inside doesn’t use the Object Literal notation

Cons

  • Doesn’t allow for a way to add private properties to be used in new public methods

Self-Executing Anonymous Function: Part 2 (Public & Private)

We looked at the Self-Executing Anonymous Function earlier as a pattern you could use to keep all your code private. As it turns out, you can actually modify the pattern somewhat so that you can achieve the same benefits of the Revealing Module Pattern. Not only can we achieve public and private properties and methods, but we can also provide an easy way to extend the namespace while keeping the content protected from the global namespace. In addition, the following pattern can protect the $ from conflicting with other JavaScript libraries and also protect undefined from being redefined.

Take a look at the following example, and we will walk through the code explaining the key changes to the pattern.

 //Self-Executing Anonymous Func: Part 2 (Public & Private) 
(function( skillet, $, undefined ) { 
  //Private Property 
  var isHot = true;

  //Public Property
  skillet.ingredient = 'Bacon Strips';

  //Public Method
  skillet.fry = function() {
    var oliveOil;

    addItem( 'tn Butter nt' );
    addItem( oliveOil );
    console.log( 'Frying ' + skillet.ingredient );
  };

  //Private Method
  function addItem( item ) {
    if ( item !== undefined ) {
        console.log( 'Adding ' + $.trim(item) );
    }
  }

}( window.skillet = window.skillet || {}, jQuery ));

//Public Properties 
console.log( skillet.ingredient ); //Bacon Strips

//Public Methods 
skillet.fry(); //Adding Butter & Fraying Bacon Strips

//Adding a Public Property 
skillet.quantity = "12"; 
console.log( skillet.quantity ); //12

//Adding New Functionality to the Skillet 
(function( skillet, $, undefined ) { 
  //Private Property 
  var amountOfGrease = "1 Cup";

  //Public Method
  skillet.toString = function() {
    console.log( skillet.quantity + ' ' +
                 skillet.ingredient + ' & ' +
                 amountOfGrease + ' of Grease' );
    console.log( isHot ? 'Hot' : 'Cold' );
  };
}( window.skillet = window.skillet || {}, jQuery ));

try { 
  //12 Bacon Strips & 1 Cup of Grease 
  skillet.toString(); //Throws Exception 
} catch( e ) { 
  console.log( e.message ); 
  //isHot is not defined 
} 

You can execute and modify the above code from jsFiddle.

First, since we have a Self-Executing Anonymous Function, we can actually provide some parameters to pass to it when it executes. In this case we are passing 2 arguments to the anonymous function.

The first argument looks quite strange. What is window.skillet = window.skillet || {} doing? The code checks to see if skillet exists in the global namespace (window). If it does not exist, then window.skillet is assigned an empty object literal. Using this approach we can build a library across JavaScript files. If another script uses the same technique, then it will pass in the existing instance and append logic to it. Inside the Anonymous Function, if we want something to be public, then we append it to the skillet object. Any other properties or methods will be considered private.

The second argument passed in jQuery. The benefit of this is that the named parameter is referenced as $, which allows us to refer to jQuery as $ within the Anonymous Function without having to worry that it will conflict with the $ declared in other JavaScript libraries. This is a common practice that you will most likely run across when looking at well written jQuery code.

You might notice a 3rd parameter to the Anonymous Function called undefined. Why did we add that parameter and why didn’t we pass an argument to it? In JavaScript, you can unfortunately redefine what undefined means. Imagine that some code somewhere deep in one of your 3rd party libraries redefines undefined to something strange like true. If anywhere in your code you test against undefined, then you code will most likely not behave like you intended. In JavaScript, if you have a parameter that doesn’t have a matching argument, then it’s value is set as undefined. By using this trick, it can save us from the bad code someone wrote to redefine undefined.

Pros

  • Gives you the ability to have public and private properties and methods
  • The code inside doesn’t use the Object Literal notation
  • Keeps undefined’s value as undefined in case someone overrode the value
  • Allows you to use $ inside your code without worrying about clashing with other libraries
  • Allows your library to grow across files using the “window.namespace = window.namespace || {}” technique
  • A common pattern that you will see in many libraries, widgets, and plugins

Cons

  • Slightly more complicated pattern, but not overly difficult to understand

If you are interested in digging deeper into some of the patterns I mentioned above then I encourage you to check out Klaus Komenda’s post entitled JavaScript Programming Patterns. The article provides an insightful view of how JavaScript patterns have changed over the years.

Best Practice

In JavaScript it is very important to declare all of your variables and it is considered a best practice to limit the number of objects in the global namespace. Depending on the situation you are developing you may need one or more of the concepts listed above to organize your code and keep it from colliding with other libraries. There is no pattern that is a Silver Bullet, but rather you should assess where you are at and examine the pros and cons of each pattern to address your situation.

2. Not Declaring Arrays & Objects Correctly

JavaScript is a prototypal language and not a classical language like C#. Although JavaScript does have a new operator which looks a lot like C#, you should not use it for creating new objects or arrays.

What Not To Do

You might be tempted to use the new keyword to create your objects in JavaScript.

 //Bad way to declare objects and arrays 
var person = new Object(), 
    keys = new Array(); 

The new keyword was added to the language partially to appease classical languages, but in reality it tends to confuse developers more than help them. Instead, there are native ways in JavaScript to declare objects and arrays and you should use those instead.

Preferred Way

Instead of using the previous syntax, you should instead declare your objects and arrays using their literal notation.

//Preferred way to declare objects and arrays 
var person = {}, 
    keys = []; 

Using this pattern you actually have a lot of expressive power using Object Literals and array initializer syntax. As we mentioned earlier, you should be careful to know that Object Literals are not JSON.

 //Preferred way to declare complex objects and arrays 
var person = { 
    firstName: "Elijah", 
    lastName: "Manor", 
    sayFullName: function() { 
      console.log( this.firstName + " " + this.lastName ); 
    } 
  }, 
    keys = ["123", "676", "242", "4e3"]; 

Best Practice

You should declare all of your variables using their literal notation instead of using the new operation. In a similar fashion you shouldn’t use the new keyword for Boolean, Number, String, or Function. All they do is add additional bloat and slow things down.

The only real reason why you would use the new keyword is if you are creating a new object and you want it to use a constructor that you defined. For more information on this topic you can check out Douglas Crockford’s post entitled JavaScript, We Hardly new Ya.

Conclusion

This article has covered some of the common issues you might address coming from C# to JavaScript. I have committed just about everyone of the above Bad Practices myself when I starting to code in JavaScript heavily.

With the recent serge of jQuery hitting the market and other great JavaScript libraries, it is important that we as developers understand the language instead of just thinking that our previous language knowledge will get us by.

This article only covers some of the things you should know. The next post in the series will be published next week. In the meantime please feel free to add comments of any other gotchas that you’ve experience coming from a C# background. I would love to hear about it.

The second post covers the following topics:

  • 3. Not Understanding False-y Values
  • 4. Not Testing & Setting Default Values Correctly
  • 5. Using the Wrong Comparison Operators
  • 6. Not Using the For…In Statement Correctly
Tweet about this on TwitterShare on FacebookShare on RedditShare on Google+Share on LinkedIn

  • http://twitter.com/pixelhandler uoʇɐǝɥ ןןıq

    I enjoyed this article even though I don't program with C, I noticed that the script examples here follow proven design patterns. Nice summary of using avoiding the bad parts of JavaScript, global variables.

  • http://twitter.com/rwaldron rick waldron

    I'm not sure about C# as I have no experience – but I will say that this is a good round up of “Good Practice patterns”. Great post.

  • http://twitter.com/SlexAxton Alex Sexton

    I like the approach of teaching C# (a self-proclaimed enterprisey language) programmers common pitfalls based on their previous enterprise experience. It is a good use of an 'enterprise' directed site. So, kudos. More posts like these!

  • http://twitter.com/zdam Adam Webber

    Hi,
    Part 1 of this post was probably the most articulate explanation of Javascript encapsulation patterns I have come across.
    You should consider putting Part 1 into a new blog post with a different title (perhaps “Core Javascript encapsulation patterns”?) to aid google searchability.
    Thanks for the great post!

  • http://twitter.com/vitor_canova Vitor Canova

    OMG I always use “new Array()”, “new Object()” and about 70% of wrong way that you wrote. Great post. What about events? Probalby I'm doing wrong too.

  • http://twitter.com/oooJamesooo James Setaro

    Great article, I have seen these patterns in the past and they have always given me a headache because the are so different than classical languages. Great explanations.

    p.s.small type here:”In JavaScript, f you…”

  • amWirick

    Hi James,

    Thanks for the feedback and pointing that out. That typo was a bit awkward :). Post updated.

  • Hpm

    Very informative (I just start learning js).

    Thanks a lot for this article

  • http://www.facebook.com/people/Gaurav-Srivastava/100000825838110 Gaurav Srivastava

    Great Article, will be useful for developers those are novice in client side programming like me

  • Nirmalsat

    Nice..:).. Looking for more such articles.. Keep up the good work..

  • http://twitter.com/dcousineau Daniel Cousineau

    I wouldn't necessarily say “don't use the new keyword”, just leave it at “use {} and [] instead of new Object() and new Array()”

    Obviously you'll need to use the new keyword if you're using JavaScript's prototype system. Granted the greater jQuery community tends to avoid the prototype system.

  • http://www.sareez.com/ Sarees

    Awesome… thanks for sharing…

  • threenine39

    I enjoyed this post being a “Self Proclaimed enterprisy” C# Developer I learnt alot from this article.
    Look forward to part two.

  • Marc Borgers

    Great article. Together with http://jqfundamentals.com/ one of the better ones I read about the topic.

  • Avronpolakow

    Illuminating article which simplifies a lot of complicated stuff.

    It is worthwhile to compare when to use Object Literals vs. javascript function classes

    ¬ Object Literals do not take arrgument whereas classes can

    ¬ Object Literals cannot be inherited whereas the classes can (using prototypes)

    I have compiled some of your article comparing these to if you wish to see these.

    avronpolakow@gmail.com

  • Fajciarx

    little offtopic: your visual studio theme is nice on eyes, mind telling me which theme are you using?

    you're a wizard btw ;)

  • http://www.facebook.com/diszo.sasil Diszo P. Sasil

    very nice article. :)

  • Zecc

    I think saying an object literal is not JSON is confusing in this context.
    The way I see it, while it is true that not all literals are JSON, all JSON are literals.

    So the whole JSON thing is a non-issue when what you want to write is an object literal. Just write it and be done with it.

  • Adam Davis

    How is it you guys avoid using other languages. I'm a programmer also and I end up using C++, C#, HTML and Java all the time.

  • jsc42

    new Array() and new Object() were the only ways to create arrays and anonymous objects in early versions of JavaScript. The Array constructor has a trick that the [ ] literal does not have: you can define the initial no of elements (e.g. var arr = new Array(10); ); however, as a consequence, you cannot use the constructor syntax to initialise an array with a single element with an integer value.

    There is no absolute right or wrong – it is a case of using the most appropriate tool for the job. Using the [ ] and { } literals for arrays and objects is usually the simplest (both in terms of typing for the programmer and in parse time for the interpretter); but if you have to cater for very old versions or you want an initialised length, then the 'old school' ways are more appropriate.

  • Keiranvv

    What about new Date() ?

  • Dr. Random

    Hmmm…time to restructure some of my javascript. :)

  • Anthony Marguccio

    In your “Self-Executing Anonymous Function: Part 2 (Public & Private)” example, is the reason isHot is undefined because private methods and properties live in the anonymous function only? At first, I was thinking that you could have a privileged method in one anonymous function accessing a private variable in another anonymous function because they were both added to the skillet namespace. Running your example, I see that is not the case. Could you explain that?

    Great write up! Thanks.

  • cbsides

    Thanks for this post, that's a really excellent selection of antipattern/patterns. As the front-end development team at my company (a C#/.NET shop), we just did an internal tech talk on the same topic and this helps to reinforce that we got our audience right :)

  • http://www.facebook.com/NarukiOni Naruki Bigglesworth

    That part was the reason I was going to comment, as well. I wanted you to explain the specific reason it is undefined, since you had declared it (too ambiguously) as a private variable.

    If I understand correctly, the reason it is undefined is that it is private to the scope it was declared in. It is not a private member of the skillet object. So any code inside that scope can see it, but external to that scope, even if a member of the skillet object, cannot.

  • reifnir

    Better-est Practice: put quotes around properties in complex objects

    //Preferred way to declare complex objects and arrays
    var person = {
    “firstName”: “Elijah”,
    “lastName”: “Manor”,
    “sayFullName”: function() {
    console.log( this.firstName + ” ” +
    this.lastName );
    }
    },
    “keys” = [“123″, “676”, “242”, “4e3″];

  • Mitch

    Thanks for the excellent article. Unrelated question…where can I get your vs.settings file? I love that color scheme. :)

  • http://twitter.com/canuckistani canuckistani

    I quite like and use this particular pattern:

    /**
    * namespace Foo
    */

    if(typeof(Foo) == 'undefined') {
    var Foo = {};
    }

    (function() {

    this.foo = function(x,y) {} // public

    function bar() {} // private

    }).apply(Foo);

    Using apply here makes it a bit more readable to my eyes, YMMV.

  • http://www.facebook.com/profile.php?id=100000198090383 Hla Min Swe

    Thank a lot.

  • http://twitter.com/rmurphey Rebecca Murphey

    +1 to the commenter who suggested a title for this post that reflects that it's about best practices for code encapsulation. Great content here covering lots of useful patterns. For readers who are interested in this stuff, I also recommend Stoyan Stefanov's new book, JavaScript Patterns, which provides a lot of useful guidance along these same lines for a broad range of JS topics.

  • Martin

    Why do you even mention jQuery? It's not even a JavaScript library. It's a client side scripting library that is just using JS.

    The article seems really to be great, but it makes people keep thinking jQuery==JS

  • Pickatutorial.com

    A very informative one. A real food for thought.

  • http://twitter.com/ebanzon Ernie Banzon

    coming from a c# background, i must accept that i don't have enough time to take my js learning to the next level, but your article encourages me to learn more. very well explained. thanks

  • Tang Biao

    There is a typo in module pattern: It should be (function(){ …. })(); not “…));”

  • Pingback: Avoiding conflicts when using jQuery and EPiServer Composer | Frederik Vig - ASP.NET developer()

  • Pingback: Good C# Habits, Bad JavaScript Habits | ChurchCode()

  • Pingback: 5 пунктов о том, как хорошо писать плохой JavaScript | KSDaemon's blog()

  • Pingback: Declaring var In JS ... best practice if any??? - PreCentral Forums()

  • Pingback: JavaScript global namespaces « Kiss' world()

  • Pingback: Javascript OOP Best Practices | tutorials blogs()

  • Pingback: RealTime - Questions: "Javascript new Window?"()

  • Pingback: István Miklós Antal » Web developer’s guide()

  • Pingback: Jquery y el lado del servidor. « memories of the trail()

  • Pingback: Good JavaScript Habits For C# Developers by Elijah Manor | appendTo - The Company Dedicated to jQuery()

  • Pingback: Good C# Habits, Bad JavaScript Habits | Church Mag()

  • Jon

    First of all great article.

    However, my problem with your approach is that you get huge long error messages that are unspecific and simply say:
    (function( skillet, $, undefined ) { … etc etc etc … }( window.skillet = window.skillet || {}, jQuery )); is not a function.Not terribly helpful as you don't know where the error is. Is this a drawback to this approach or is this simply me not understanding something correctly?Many thanks!

  • Pingback: Orizen Designs – Pure Insight – Freelance of all related to web – Web Design, Development, Flash, Flex, Swishmax » Blog Archive » Monthly Javascript Digest – 07/2011 swishmax components, gui design, gui development()

  • Pingback: How Good C# Habits can Encourage Bad JavaScript Habits:Part 1 | jQuery-Javascript | Scoop.it()

  • Pingback: Emulare i namespace in JavaScript… « JP's Web Place()

  • Pingback: Better JavaScript « mabbled()

  • Pingback: Doing Javascript the right way | Onyxtek Web Design()

  • Pingback: Helpful links to get started with JavaScript « The Joe Code()

  • Pingback: The "Tech. Arch."()

  • Pingback: Хорошие привычки C# = плохие привычки JavaScript | Записки на лету()

  • Pingback: Daily Interests - Joshua Lyman.com()

  • Pingback: First attempt at AngularJS and ASP.NET’s PageMethods & WebMethods | I Came, I Learned, I Blogged()

  • Pingback: Bootstro-js | jQuery plugin for page walkthough or demo()

  • Pingback: JavaScript & Namespacing | techblog()

  • Pingback: Finally… A good grasp on structured javascript and namespaces | WebDev 3.0()

  • Pingback: How Good C# Habits can Encourage Bad JavaScript Habits Part 1 | Liudas Notes()

  • Pingback: How Good C# Habits can Encourage Bad JavaScript Habits Part 1 | appendto()