Since Quartex Pascal targets JavaScript, all variables are by default of type variant. The reason we can support typed variables is because our compiler initializes variables and fields automatically for you, assigning 0, false or "" (and so on) to make sure the variable already has a type. If you have used variant under Delphi or Lazarus, you have a good idea how they behave already.


In short: a variant is a kind of universal variable that can contain any type of values JS knows about. So if you assign an integer value, then it becomes an integer. If you assign a string, it becomes a string.



Under Quartex Pascal variant is the bridge between the world of pascal and the world of JavaScript. It allows us to interact with JavaScript on it's own terms, without breaking the strict typing we all love and appreciate.


If you examine the core RTL units (sysutils, classes and types), you will find that several data-types derive from variant, such as THandle:


type

 ..

 THandle = variant;


The reason THandle is of type variant, is because a handle or reference can (from a pascal point of view) be anything. It depends completely on the context in which it's used. Some external libraries return JavaScript objects when you interact with them, others return references to native browser elements; It completely depends on the framework or API you are dealing with. Variant allows us to work with whatever values the browser, NodeJs etc. operates with - without getting stuck in terminology.


For example, the following is perfectly legal:


// Create and assign a JavaScript object to a variant

// Use an asm section to write inline JavaScript

var lHandle: THandle;

asm

 @lHandle = {

       first: 1200,

       second: "hello world"

};

end;

WriteLn( lHandle.first );

WriteLn( lHandle.second );


In the above code, the pascal compiler doesn't see or care what is inside the variant. Variant is regarded as a "black box" that can contain anything, including objects, so the compiler gladly compiles the code, not really knowing if the properties first and second exists. So if you are pondering how Quartex Pascal bridge the Pascal and JavaScript barrier, variant is very much at the heart of it.


But since strict typing and order is one of object pascal's strengths, variant can be typecast to make it easier to work with:


// Define a class for the JavaScript object above.

// Then we can use ordinary type casting to access its data

type


JTestObject = class(JObject)

 first: int32;

 second: string;

end;


var lObject := JTestObject( lHandle );

WriteLn( lObject.first );

WriteLn( lObject.second );


If you want to know the difference between TObject and JObject, that is documented here: TObject and JObject.


As you probably suspect from the code above, we can avoid the whole asm section and create our JS object in pascal. This is ultimately why there is a JObject ancestor in the compiler (see link above).


type


JTestObject = class(JObject)

 first: int32;

 second: string;

end;


// create an instance of our JavaScript object

var lObj := new JTestObject;


// populate fields

lObj.first := 1200;

lObj.second := "welcome to the jungle";


// dump the object to console as JSON

WriteLn( JSON.Stringify( variant(lObj) ) );



It is really neat once you get into it, because you can use all the benefits of object pascal to construct complex data and applications -that would take forever in vanilla JavaScript.