Just JavaScript - Object Construction
Written by Ian Elliot   
Thursday, 21 August 2014
Article Index
Just JavaScript - Object Construction
Late and early binding
The Constructor

Constructor pitfalls

This double use of this in a constructor is often confusing to beginners. 

It also has the potential to cause some errors. 

For example if you use a constructor without new then this is set to the current call context and not to a new empty object.  The result is that the properties and methods that should have been added to the new object are added to the current call context. In most cases the call context is the global object so all of the properties and methods are added to the global object. 

For example:

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

works because the constructor called without new adds x, y and add to the global object. 

The hijacking of the this call context in the constructor also causes problems when new is used and for some reason the constructor wants to use the call context. However this very rarely happens because constructors are not usually methods of other objects.

For example:

Geometry={};
Geometry.units="inches"; Geometry.Point=function(x,y){
 this.x=x;
 this.y=y;
 this.add=function(){
  return this.x+this.y;
 };
};
var myPoint= new Geometry.Point(1,2);

There is nothing wrong with defining the Point constructor to be a property of a Geometry object, but because of the use of new this is set to reference the new object that is being created and not the Geometry object i.e. the call context. What this means is that that you cannot use this to reference the units property of the Geometry object. You can make it work but only by putting the Geometry object inside a constructor and giving it a private variable that references it so that the Point constructor can access it.

This is not a practical issue but it is important that the way that this is used in a constructor is completely understood. As soon as you put new in front of a function call this is no longer the call context.

Self or New?

The issue of using an object factory or an object constructor is a difficult topic. Most JavaScript programmers are introduced to using constructors as if it is the standard way of creating objects - it is. However it has problems. The first is that you have to remember to use new in front of a constructor call - and if you forget it doesn't work. You don't need to use new in front of an object factory call and the use of self produces early bound methods and properties. The problem is that using a constructor brings will it some additional actions that make programming easier that will be the subject of the next chapter - in particular the constructor property and the prototype property are automatically set when you use new and a constructor

There is a compromise you can use a constructor but use self rather than this by simply setting self to reference the same object as this.

For example: 

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

Notice that self is set to this as the first instruction. The only real difference is that in the definition of the add function the properties are early bound to the instance. If you want to use this in the creation of the object and self in method definitions you can. Indeed you can choose to use self or this in method definition depending on whether you want them early or late bound to the call context.

You can even test for the use of new in a call to the constructor by testing if this is the global object, usually window. If this is the global object the constructor has been called without using new and you simple call the constructor properly:

Point=function(x,y){
 if(this===window) return new Point(x,y);
    rest of constructor

this assumes that the global object is window. If you can't assume this set up a global variable to store a reference to the global object:

Global=this;
Point=function(x,y){
 if(this===Global) return new Point(x,y);
    rest of constructor

There are many variations in this basic theme. In general, however, the us of new in front of a constructor isn't a big problem.

 

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. 

 

JustJavaScripticon

Just JavaScript 

 There is a newer version of the draft of the book here.

A Radical Look At JavaScript

Contents

  1. JavaScript Isn't Java, or C, or C# ... (Book Only)
  2. In The Beginning Was The Object
  3. The Function Object
  4. How Functions Become Methods
  5. The Object Expression
  6. Object Construction
  7. The Prototype
  8. Type And Non-Type
  9. Constructor And InstanceOf
  10. Duck Testing And Prototype Construction

-Preface-

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. 

 

Coming Next

The inheritance problem - prototype and type.

Related Articles

JavaScript Doesn't Need Class

Javascript Jems - Object factories, constructors and clones

Javascript Jems - a new take on objects

 

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

 

Banner


JavaScript Canvas - Fetch API

Working with lower-level data is very much part of graphics. This extract from Ian Elliot's book on JavaScript Graphics looks at how to use typed arrays to access graphic data.



JavaScript Jems - The Inheritance Tax

JavaScript should not be judged as if it was a poor version of the other popular languages - it isn't a Java or a C++ clone. It does things its own way.  In particular, it doesn't do inheritance  [ ... ]


Other Articles

 

espbook

 

Comments




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

 

<ASIN:0596805527>

<ASIN:193398869X>

<ASIN:0137054890>

<ASIN:1449381871>

<ASIN:1430230541>



Last Updated ( Sunday, 10 May 2015 )