1 Global scope
When you start writing server side script
in a document, you are already in the Global scope.
There is only one Global scope
throughout a server side script
document. A variable is
in the Global scope if it's defined outside of a function. A Global variable can be accesed in every local function.
<xsql-script name='test_global_var'> <body> <function name='local_test_global_var'> <body> <println>Value of variable [g_value] is: <global.get name='g_value' /></println> </body> </function> <global.set name='g_value' type='string'>GLOBAL SCOPE</global.set> <local_test_global_var /> </body> </xsql-script>
Value of variable [g_value] is: GLOBAL SCOPE
function fGlobalVar() { console.log(`fGlobalVar: Executing`); console.log(`fGlobalVar: Value of variable [gStrValue] is: ${gStrValue}`); console.log(`fGlobalVar: Exiting`); } function testGlobalVar() { console.log(`testGlobalVar: Executing`); // console.log(`Value of variable [gStrValue] is: ${gStrValue}`); // ERROR!!!!!!!!!!!!!!!!!!! console.log(`testGlobalVar: Variable is not declared`); gStrValue = 'GLOBAL SCOPE'; console.log(`testGlobalVar: Variable is declared`); console.log(`testGlobalVar: Value of variable [gStrValue] is: ${gStrValue}`); fGlobalVar(); console.log(`testGlobalVar: Exiting`); } function testGlobalVarExtern() { console.log(`testGlobalVarExtern: Executing`); //console.log(`Value of variable [gStrValue] is: ${gStrValue}`); // ERROR!!!!!!!!!!!!!!!!!!!!!! console.log(`testGlobalVarExtern: Variable is not declared`); testGlobalVar(); console.log(`testGlobalVarExtern: Value of variable [gStrValue] is: ${gStrValue}`); console.log(`testGlobalVarExtern: Exiting`); } testGlobalVarExtern();
testGlobalVarExtern: Executing
testGlobalVarExtern: Variable is not declared
testGlobalVar: Executing
testGlobalVar: Variable is not declared
testGlobalVar: Variable is declared
testGlobalVar: Value of variable [gStrValue] is: GLOBAL SCOPE
fGlobalVar: Executing
fGlobalVar: Value of variable [gStrValue] is: GLOBAL SCOPE
fGlobalVar: Exiting
testGlobalVar: Exiting
testGlobalVarExtern: Value of variable [gStrValue] is: GLOBAL SCOPE
testGlobalVarExtern: Exiting
limit the use of global variables
A good practice
limit the use of global variables. That is, inside the body of a function, never use variables defined outside the function.
2 Local scope
A variable declared within a function only can be accessed into the function where it is declared.
In next example a local variable is used outside the function where is declared, so causes an error.
<xsql-script name='test_local_var'> <body> <function name='local_var'> <body> <set name='m_var'>10</set> </body> </function> <local_var /> <println><m_var /></println> </body> </xsql-script>
undefined function or variable 'm_var'
function testLocalVar() { function __localVar() { var mIntLocVar = 10; } __localVar(); console.log(mIntLocVar); } testLocalVar();
ReferenceError: "mIntLocVar" is not defined.
Precedences of local variables
In the function's body, the precedence of the local variable is more than the global variable with the same name. If the name of the function's local variable is same as the name of the global variable, then the local variable hides the global variable.
<xsql-script name='test_precedence'> <body> <function name='local_func'> <body> <set name='m_var'>5</set> <println><global.get name='m_var' /></println> </body> </function> <global.set name='m_var'>10</global.set> <local_func /> </body> </xsql-script>
10
function testPrecedence() { var mIntVar; function __localVar() { var mIntVar = 5; console.log("Inside _localVar : " + mIntVar); } mIntVar = 10; __localVar(); console.log("Outside _localVar : " + mIntVar); } testPrecedence();
Inside _localVar : 5
Outside _localVar : 10
3 Block scope
A variable defined with var
is globally scoped or locally scoped to the function in which it is defined. Control sentences as if
, switch
or loop sentences as for
and while
, that creates block scopes have no effect on var.
let
and const
, on the other hand, are scoped within the block which they are defined. In XSQL this scope does not exist. In next example javascript works differently than XSQL.
<xsql-script name='test_block_scope'> <body> <set name='m_var'>10</set> <if> <expr><true /></expr> <then> <set name='m_var'>5</set> </then> </if> <println>m_var = <m_var /></println> </body> </xsql-script>
m_var = 5
var mIntVar = 10; { let mIntVar = 5; console.log('mIntVar (inside block) = ' + mIntVar); } console.log('mIntVar (outside block) = ' + mIntVar);
mIntVar (inside block) = 5
mIntVar (outside block) = 10
In the exemple above, the declaration of mIntVar using let
, is made within an if sentence.
Outside the block, prevails the value assigned in declaration with global scope made just before the if statement.
4 Data types
Javascript variables are dynamically typed. If we declare variables and assign a value to it then it will convert that variable type. In script can function. XSQL works in a similar way.
<xsql-script name='test_type'> <body> <set name='m_var1'>10</set> <set name='m_var2'>10.45</set> <set name='m_var3'>LEON TROTSKY</set> <set name='m_var4'><date.today /></set> <set name='m_var5'><true /></set> <println>type [m_var1] <variable.typeof><m_var1 /></variable.typeof></println> <println>type [m_var2] <variable.typeof><m_var2 /></variable.typeof></println> <println>type [m_var3] <variable.typeof><m_var3 /></variable.typeof></println> <println>type [m_var4] <variable.typeof><m_var4 /></variable.typeof></println> <println>type [m_var5] <variable.typeof><m_var5 /></variable.typeof></println> </body> </xsql-script>
type [m_var1] java.lang.Integer
type [m_var2] java.math.BigDecimal
type [m_var3] java.lang.String
type [m_var4] java.sql.Date
type [m_var5] java.lang.Boolean
var mIntVar1 = 10; var mBcVar2 = 10.45; var mStrVar3 = 'LEON TROTSKY'; var mJsDateVar4 = new Date(); var mBoolVar5 = true; console.log(`type [mIntVar1] ${typeof mIntVar1}`); console.log(`type [mBcVar2] ${typeof mBcVar2}`); console.log(`type [mStrVar3] ${typeof mStrVar3}`); console.log(`type [mJsDateVar4] ${typeof mJsDateVar4}`); console.log(`type [mBoolVar5] ${typeof mBoolVar5}`);
type [mIntVar1] number
type [mBcVar2] number
type [mStrVar3] string
type [mJsDateVar4] object
type [mBoolVar5] boolean
XSQL data types vs javascript data types
The main difference that can be observed in last example is the data types obtained. The types used in XSQL are derived from java classes. In any case, as you will see in this section, there are objects in server side javascript
that also derive from java classes.
5 Several variables in a line
In javascript we can assign several variables in a single statement, while in XSQL no.
<xsql-script name='test_statement_multidefs'> <body> <set name='m_var1'>10</set> <set name='m_var2'>20</set> <set name='m_var3'>30</set> <println> m_var1 1 [<m_var1 />] m_var2 [<m_var2 />] m_var3 [<m_var3 />] </println> </body> </xsql-script>
m_var1 1 [10] m_var2 [20] m_var3 [30]
var mIntVar1 = 10, mIntVar2, mIntVar3 = 30; mIntVar2 = 20; console.log('mIntVar1 [' + mIntVar1 + '] mIntVar2 [' + mIntVar2 + '] mIntVar3 [' + mIntVar3 + ']');
mIntVar1 [10] mIntVar2 [20] mIntVar3 [30]
6 Declaring variables without values assigned
In XSQL there is no way to declare a variable without assigning a value to it.
On the other hand, in server side script
you can define a variable with let
, var
and const
,
assigning it a value later. The value of the variable after assignment is undefined.
var mIntVar; console.log("BEFORE ASSIGN VALUE: " + mIntVar); mIntVar = 10; console.log("AFTER ASSIGN VALUE: " + mIntVar);
BEFORE ASSIGN VALUE: undefined
AFTER ASSIGN VALUE: 10
7 Assigning decimal values
Javascript decimal numbers are floating-point
numbers, and so are represented as binary fractions. Unfortunately most decimal fractions cannot be represented exactly as binary fractions.
<xsql-script name='test_bigDecimal'> <body> <set name='m_var1'><add><number>0.1</number><number>0.2</number></add></set> <println> m_var1: [<m_var1 />]</println> </body> </xsql-script>
m_var1: [0.3]
var mDecVar1 = 0.1 + 0.2 console.log("m_var1: [" + mDecVar1 + "]");
m_var1: [0.30000000000000004]
This problem does not exists in XSQL, because use java.math.BigDecimal
. But in Server side script
there is also the possibility of working with big decimal using Ax.math.bc
. In next example we resolve the above problem.
var mBcVar1 = 0.1; var mBcVar2 = 0.2; console.log("m_var1: [" + Ax.math.bc.add(mBcVar1, mBcVar2) + "]");
m_var1: [0.3]
8 Date variables
Sometimes if we are migrating from XSQL, we need to perform calculations with date types or use date types in database operations.
In this cases, primitive javascript date type is not the best solution. In server side script
we have a java.util.Date
object wrapper that simplify these operations.
<xsql-script name='test_date'> <body> <set name='m_var_date'><date.mdy><number>1</number><number>1</number><number>2030</number></date.mdy></set> <set name='m_var_date'><add><m_var_date /><date.units type='m'>1</date.units></add></set> <println>m_var_date: <m_var_date /></println> </body> </xsql-script>
m_var_date: 01-02-2030
var mDateVar = new Ax.util.Date(2030, 1, 1); var mDateVar = mDateVar.addMonth(1); console.log("m_var1: [" + mDateVar + "]");
m_var1: [Fri Feb 01 00:00:00 CET 2030]