Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forward declaration in Javascript

Background

I'm building a javascript based application that works differently on mobile and desktop devices. However, except for the DOM manipulation, most code is common between both platforms, so I have structured all files like: * foo.core.js * foo.mobile.js * foo.web.js

And hoping to leverage object oriented techniques to write cleaner code.

Problem:

I have two JavaScript files, with classes

File 1:

function ClassA()
{}

ClassA.prototype.foo = function(){};

GreatGrandChildA.prototype = new GrandChildA(); // this is where the error is
function GreatGrandChildA ()
{}

File 2:

ChildA.prototype = new ClassA();
function ChildA () // ChildA inherits ClassA
{}

GrandChildA.prototype = new ChildA()
function GrandChildA () // GrandChildA inherits ClassA
{}

Normally, in a language like C++, I would forward declare GrandChildA right in File 1. I would like to know how to do it in Javascript

Edit:

If I make a single file containing all four classes - in the same order in which they are loaded, the example works exactly as expected:

http://jsfiddle.net/k2XKL/

like image 985
antileet2 Avatar asked Sep 19 '11 11:09

antileet2


People also ask

What is forward declaration of a function?

A forward declaration allows us to tell the compiler about the existence of an identifier before actually defining the identifier. In the case of functions, this allows us to tell the compiler about the existence of a function before we define the function's body.

What is forward declaration in Java?

Forward declarations means the declaration of a method or variable prior to its implementation. Such declaration is necessary in C/C++ programming language in order to be able to use a variable or object before its implementation.

What is declaration in JavaScript?

Creating a variable in JavaScript is called "declaring" a variable.

What is the advantage of forward declaration?

Forward declarations in C++ are useful to save in compile time as the compiler does not need to check for translation units in the included header. Also it has other benefits such as preventing namespace pollution, allowing to use PImpl idiom and it may even reduce the binary size in some cases.


2 Answers

Simple logic for unordered js file loading:

File1:

// ClassB: inherite from ClassA
(function ClassB_Builder() {
  if(window.ClassB)return; // ClassB is already defined;
  if(!window.ClassA) { // ClassA is already not defined;
     setTimeout(ClassB_Builder,0); // shedule class building
     return;
  }
  ClassB=function() {
  }
  ClassB.prototype=new ClassA;
  ClassB.prototype.constructor=ClassB; // can be important for inheritance!!!
})();

File2:

// ClassA: base class
(function ClassA_Builder() {
  ClassA=function() {
  }
})();

// ClassC: inherite from ClassB
(function ClassC_Builder() {
  if(window.ClassC)return; // ClassC is already defined;
  if(!window.ClassB) { // ClassB is already not defined;
     setTimeout(ClassC_Builder,0); // shedule class building
     return;
  }
  ClassC=function() {
  }
  ClassC.prototype=new ClassB;
  ClassC.prototype.constructor=ClassC; // can be important for inheritance!!!
})();
like image 74
Andrew D. Avatar answered Sep 28 '22 18:09

Andrew D.


I assume that on your HTML page, you import File 1 and then File 2.

In File 1, you should see exception because "GrandChildA" is undefined. The function declaration is not done because File 2 has not loaded yet.

In File 2, you're being able to do:

ChildA.prototype = new ClassA();
function ChildA () // ChildA inherits ClassA
{}

because the Javacript runtime hoisted your named function "ClassA" before the code executes until ChildA.prototype = new ClassA();

Please read more about function hoisting and should you be doing it in such situation at http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

like image 40
Kenny Ki Avatar answered Sep 28 '22 17:09

Kenny Ki