Just JavaScript - Object Factories
Written by Ian Elliot   
Monday, 25 March 2019
Article Index
Just JavaScript - Object Factories
Object Factories

JustJavaScripticon

At their very simplest an object factory creates an object literal and returns it as its result.  

For example an object factory for the point object is:

var Point=function(){ 
             return {x:0,y:0}; 
          };

and to use it to create an instance of the Point object you would use:

var myPoint=Point();

It seems trivial yet in no time at all it can become complicated and subtle. 

Notice that we already have recreated one of the minor problems of a class-based language - finding a name for the class and for an instance. In this case the naming problem is finding something to call the object factory and then names for the instances - i.e. Point and myPoint. Perhaps it would be better to call the factory PointMaker or something to indicate that it wasn't actually an instance of a Point object. 

As the object being created gets bigger and more complicated, building it in smaller steps becomes a better method. Starting from an empty object you can add properties one by one. 

For example:

var Point=function(){ 
            var obj={}; 
            obj.x=0; 
            obj.y=0; 
            return obj; 
          };

One of the big advantages of using an object factory is that you can use parameters to customize the object produced. 

For example:

var Point=function(x,y){
            var obj={};
            obj.x=x;
            obj.y=y; 
            return obj;
};

and you create the object using:

var myPoint=Point(1,2);

The ability to customize object instances is one of the big plus points of using an object factory.  It is so useful that an object factory is often used to create a singleton – even though the factory will only ever create a single object. 

Constructing Methods

Of course the object that the factory produces can have any type of object as its properties including Function objects.

As already explained in Chapter 8 function properties aren't really the same thing as methods.

To make a Function property act like a method you have to make use of the this call context, i.e. this, to specify the instance that is being referenced. 

If you are creating an object as an object literal there is no other choice but to use this to create a late bound method for an object. 

However, if you are using a factory function there is an alternative and it is arguably better as it creates an early bound method.

For example, suppose we want to write a method that adds x and y together:

var Point=function(x,y){ 
            var obj={};
            obj.x=x; 
            obj.y=y; 
            obj.add=function(){
                      return obj.x+obj.y; 
                    }; 
            return obj; 
          };

Notice that the function uses obj.x and obj.y not just x and y. 

If you try out: 

var myPoint=Point(1,2);
myPoint.x=4;
alert(myPoint.add());

you will find it works and displays 6 – but how can it?

Private Variables

When myPoint.add is called, the variable obj has long gone as the factory object's code has terminated and all its variables have been destroyed. How can a Function object make use of the factory's obj variable long after it has been destroyed? 

The answer, of course, is closure.

If you recall, closure in JavaScript is necessary to resolve the problem of having Function objects which live for longer than their code. When you define the add Function object it captures the variables that are in scope at the time of its creation, i.e. obj. Thus the add function has access to obj even though, without closure, it should have been destroyed.

Also notice that code in other Function objects can't access the obj variable because it no longer exists and it is local to the factory function. That is, obj is a private variable for the instance of the point object we have created. 

The general rule is that any local variables declared within the object factory are turned into private variables for the object created by closure.

More exactly all of the methods created are assigned the same execution context as a closure. This means that all of the methods share the same private variables which is usually what you would expect and require.

This is another advantage of using an object factory even for a singleton. Object literals don't have private variables unless they are created within a function. 

Private Properties

It should be obvious now that closure can be used to create private properties for objects, but it is worth exploring a little more. 

For example, you can create a private property for the point object using something like:

var Point=function(x,y){
            var obj={};
            var myPrivateData=10;
            obj.getPriv= function(){
                           return myPrivateData;
                         };
            return obj; 
          };
var myPoint= Point(1,2);
alert(myPoint.getPriv()); 

Where the code has been stripped down to just what is needed to demo a private variable. In this case the getPriv function can access myPrivateData because of closure and so everything works. However, any attempt to directly access the variable fails because there is no closure in operation and it is not a property of the constructed object.

That is both:

alert(myPoint.myPrivateData);

and:

alert(myPrivateData);

fail.

You can of course use a getter and setter with a private variable but it is slightly more complicated to add them using an object factory.

For example:

var Point=function(x,y){
            var obj={
                      get Priv(){return myPrivateData;}
                    };
            var myPrivateData=10;
            return obj; 
          };

Now you can use Priv as if it was a variable but there is no access to myPrivate data except through get or set:

var myPoint= Point(1,2);
alert(myPoint.Priv); 

The private variable pattern is well known, but it works for methods as well although not as commonly.

For example, if you want to create a private function that only the object can use, all you have to do is declare it as a local variable within the object factory:

Point=function(x,y){ 
        var myPrivateData=10;
        var obj={}; 
        var myPrivateAdd=function(a,b){ 
                           return a+b; 
                         }; 
  obj.add=function(){     return myPrivateAdd(1,2);   }; };

In this case myPrivateAdd is accessible from the object constructed because of closure, which means it can be called from within any method of the object. Again the myPrivateAdd function cannot be called outside the object because it is not a property and is only available as a closure inside the object. 

Notice that a private function can make use of private variables as these are made available to it by closures within the object itself.

The private variables and functions are instance entities in the sense that each object that the factory function produces has its own copy of all of the private entities because, as already explained, the execution context is created each time the factory function is used.

That is, all of the private variables are not shared.

If you want to make a private method, then you can use the obj variable within the private function to access properties of the object.

For example:

var Point = function (x, y) {
       var obj = {};
       obj.x = x;
       obj.y = y
var myPrivateAdd = function () { return obj.x + obj.y; }; obj.add = function () {     return myPrivateAdd();       }; return obj; };

You can see that myPrivateAdd is private and can be used by the add method to add two properties of the Point object. This is a private method.

Remaining Sections In The Chapter

  • Using this
  • Late and Early Binding
  • Constructors
  • Constructor Pitfalls
  • Strict Mode

Summary

  • Object literals are fine for singleton objects, but even here there are advantages to the use of an object factory.

  • An object factory creates an object complete with properties and methods and returns that object as its result.

  • If the object factory declares the local variable self to reference the new object, then methods can use self to early bind to the object's properties. 

  • Any local variables or local functions defined within the object factory are accessible to the constructed object because of the operation of closure – thus providing private variables and methods to the object.

  • JavaScript has the new operator, which if used in front of a function call makes it a constructor. A constructor automatically has this referencing a new empty object and automatically returns the object without the need for an explicit return. 

  • Notice that within a constructor this is not the call context but a new empty object. 

  • You can use this within a constructor in the same way as self in an object factory to refer to the new object and within methods to bind them to the object. 

  • You can add self to a constructor to get the benefit of both approaches.

  • If you use this in a method definition then the method is late bound. If you use self in a method definition then the method is early bound.

  • Finally you can make new optional in front of a constructor by a simple test and recall pattern, but this usually isn't necessary.  

 

This is an extract from the book Just JavaScript by Ian Elliot.

Buy Now: from your local Amazon

Just JavaScript 
An Idiomatic Approach

JustJavaScriptSmall

A Radical Look At JavaScript

 

Most books on JavaScript either compare it to the better known class based languages such as Java or C++ and even go on to show you how to make it look like the one of these.

Just JavaScript is an experiment in telling JavaScript's story "just as it is" without trying to apologise for its lack of class or some other feature. The broad features of the story are very clear but some of the small details may need working out along the way - hence the use of the term "experiment". Read on, but don't assume that you are just reading an account of Java, C++ or C# translated to JavaScript - you need to think about things in a new way. 

Just JavaScript is a radical look at the language without apologies.

Contents

  1. JavaScript – Essentially Different
  2. In The Beginning Was The Object
  3. Real World Objects 
  4. The Function Object
          Extract - The Function Object
          Extract - Function Object Self Reference
  5. The Object Expression
  6. Function Scope, Lifetime & Closure
    Extract Scope, Lifetime & Closure
    Extract Execution Context ***NEW!
  7. Parameters, Returns and Destructuring
         Extract - Parameters, and Destructuring
  8. How Functions Become Methods
  9. Object Construction
         Extract: - Object Factories
  10. The Prototype
         Extract - ES2015 Class and Extends
  11. Inheritance and Type
  12. The Search For Type
  13. Property Checking

Buy Now: from your local Amazon

Also by Ian Elliot 
JavaScript Async: Events, Callbacks, Promises and Async Await
Just jQuery: The Core UI 
Just jQuery: Events, Async & AJAX  

<ASIN:1871962579>

<ASIN:1871962560>

<ASIN:1871962501>

<ASIN:1871962528>

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

espbook

 

Comments




or email your comment to: comments@i-programmer.info



Last Updated ( Monday, 25 March 2019 )