Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-loader.php on line 71

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-core/bp-core-catchuri.php on line 37

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-core/bp-core-functions.php on line 148

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-core/bp-core-functions.php on line 148

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-core/bp-core-functions.php on line 148

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-core/bp-core-functions.php on line 148

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-core/bp-core-functions.php on line 148

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-core/bp-core-functions.php on line 148

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-core/bp-core-avatars.php on line 52

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-core/bp-core-avatars.php on line 54

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-core/bp-core-loader.php on line 167

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-core/bp-core-loader.php on line 172

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-activity/bp-activity-functions.php on line 202

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-activity/bp-activity-functions.php on line 202

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-activity/bp-activity-functions.php on line 202

Warning: Creating default object from empty value in /homepages/44/d123476235/htdocs/tddjs/wp-content/plugins/buddypress/bp-activity/bp-activity-functions.php on line 202
Test-Driven JavaScript Development
Avatar of Thomas

by Thomas

JavaScript Inheritance

September 21, 2011 in Uncategorized

John Resig, back in 2008, wrote the following 25 line oop framework to provide better class/inheritance structure for javascript objects and it seems to work amazingly well. Granted, there are other methods for doing the same thing out there, but I wanted to bring this method to everyone’s attention.

/* Simple JavaScript Inheritance
 * By John Resig http://ejohn.org/
 * MIT Licensed.
 */
// Inspired by base2 and Prototype
(function(){
  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
  // The base Class implementation (does nothing)
  this.Class = function(){};

  // Create a new Class that inherits from this class
  Class.extend = function(prop) {
    var _super = this.prototype;

    // Instantiate a base class (but only create the instance,
    // don't run the init constructor)
    initializing = true;
    var prototype = new this();
    initializing = false;

    // Copy the properties over onto the new prototype
    for (var name in prop) {
      // Check if we're overwriting an existing function
      prototype[name] = typeof prop[name] == "function" &&
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;

            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];

            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);
            this._super = tmp;

            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }

    // The dummy class constructor
    function Class() {
      // All construction is actually done in the init method
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }

    // Populate our constructed prototype object
    Class.prototype = prototype;

    // Enforce the constructor to be what we expect
    Class.prototype.constructor = Class;

    // And make this class extendable
    Class.extend = arguments.callee;

    return Class;
  };
})();

What this does is creates an object called Class. It then specifies a method .extend to take properties and create a class that inherits from Class. It goes on to setup the prototype, constructor, and _super properties.

You can see the original post here http://ejohn.org/blog/simple-javascript-inheritance/.

He gives a great example of exactly how this simplifies inheritance and class definitions in JavaScript.

Here’s the example code he gives in his post.

var Person = Class.extend({
  init: function(isDancing){
    this.dancing = isDancing;
  },
  dance: function(){
    return this.dancing;
  }
});
var Ninja = Person.extend({
  init: function(){
    this._super( false );
  },
  dance: function(){
    // Call the inherited version of dance()
    return this._super();
  },
  swingSword: function(){
    return true;
  }
});

var p = new Person(true);
p.dance(); // => true

var n = new Ninja();
n.dance(); // => false
n.swingSword(); // => true

// Should all be true
p instanceof Person && p instanceof Class &&
n instanceof Ninja && n instanceof Person && n instanceof Class
Avatar of Chad

by Chad

Objects and Prototypal Inheritance Learning Snippets

September 21, 2011 in Test-Driven JavaScript Development

Constructors are fairly easy to see in JavaScript. Try replacing the declarations in the code below with other common declarations. (Ex: new Array and [], new Object and {})

var func = new Function();
var afunc = function(){};
console.log(func.constructor);
console.log(afunc.constructor);

In understanding enumerable properties and testing for existing properties I found this classic IE hole a good example. Run this in the console of both FF and IE (.hasOwnProperty is not supported in Safari) to see the same result as the type check:

Array.prototype.hasOwnProperty("indexOf");

typeof Array.prototype.indexOf == "function";

Good resources for understanding constructors in JavaScript:
Private Members in JavaScript by Douglas Crockford, author of JavaScript: The Good Parts
JavaScript tutorial: Object constructors – I specifically like the design pattern under the “Creating Constructors” section.

Avatar of Thomas

by Thomas

JavaScript Function Declaration

September 8, 2011 in Uncategorized

As you may or may not know, there are many different ways to declare functions in Javascript that we were looking at with TDDJS the other week. However, after reading this article today by Greg Ferrell, it made me realize why these are very very different methods of declaring a function.

So, here are the four methods we’ve been discussing:

Anonymous Functions

function(){
	alert('Hello World!');
}

Function Declaration

function thisFunct(){
	alert('Hello World!');
}

Function Expression (Variable Declaration with Anonymous Function)

var thisFunct = function(){
	alert('Hello World!');
}

Named Function Expression (Variable Declaration with Function Declaration)

var thisFunct = function thisFunct(){
	alert('Hello World!');
}

A huge difference between the first two examples and the last two is how Javascript builds its references at runtime. JavaScript goes through all your code and builds the Function Declarations first before it even starts looking at function declarations. In other words, Functions rule, and variables are secondary. This means that when you do the following, everything will be fine.

var test = addTest(5,3);

function addTest(a,b){
	return (a+b);
}

However, when you do the following using one of the last two methods, you will get a javascript error that addTest is undefined.

var test = addTest(5,3);

var addTest = function(a,b){
	return (a+b);
}

This is an interesting detail about how JavaScript prioritizes execution order and also how functions are treated by the engine. I hope I helped you learn something.

Avatar of Thomas

by Thomas

Discussion of Memoization

September 7, 2011 in Test-Driven JavaScript Development

So, today we were visiting about memoization in JavaScript . This is basically the concept of caching the arguments and results of a function call as an object in the function.

I mentioned an article by John Hann regarding memoization and you can find it here:

http://unscriptable.com/index.php/2009/05/01/a-better-javascript-memoizer/.

The article has an interesting discussion of the use of the function instance to cache the results or to use anonymous function calls to encapsulate the result variable. This all has to do with memory and performance optimization and will require a bit of experimenting to fully understand.

Johnn is referencing a presentation given by Stoyan Stefanov from Yahoo at JSConf in 2009. I went and found the presentation he was talking about and you can find it here:

http://www.slideshare.net/stoyan/high-performance-kick-ass-web-apps-javascript-edition

The slide where he starts talking about memoization is slide 79.

Anyway, let’s discuss.