Scripting in vRealize Orchestrator using Javascript

Scripting in vRealize Orchestrator Using Javascript

vRealize Orchestrator utilizes Javascript for scriptable tasks and actions.  Therefore, it is a good idea to get familiar enough with Javascript to perform at least some basic tasks.  The good news is that a lot of the more advanced features of Javascript that have come along in the past 15 years are not really required for workflow development in vRealize Orchestrator.  The majority of scripting tasks involve basic operations, such as setting and getting variable values, translating between data structure types, utilization of the API objects exposed by the server and plug-in modules, and some of the more basic functions built-in to Javascript, such as math and JSON operations.

This chapter serves as a primer for Javascript.  If you’re already familiar with Javascript, you can most likely skip this chapter, although it might be worth browsing quickly as you may pick up a few tips that apply to Javascript use within vRealize Orchestrator.

Javascript Syntax

Javascript is a flexible language with a syntax that somewhat resembles Java and C.  It is an object oriented language, but not strongly typed.  That means that when working with objects in Javascript, it isn’t rigid about matching what the code or programmer may have expected up with what the data actually is.  This is a double-edged sword.  The benefits come in the form of shorter code that can easily be adapted and refitted for ever-changing requirements.  The drawbacks are that the code retains less structure and may not be as self-documenting as a strongly typed language would have been.  This can sometimes make it a little less easy to comprehend when reviewing someone else’s code.

In Javascript, code is executed in order, line by line, starting with the first line, and going in sequence.  This execution order is called control, and as a line is executed, control is passed to the next line and on and on in that sequence until the end of the code is reached.

Each line can either have a terminator or not.  A semi-colon denotes the termination of a line in Javascript.  If no terminator is provided, the line ends on the newline character.  If a terminator is provided, it is possible to condense multiple instructions to a single line of code by placing semi-colons after each instruction.

In this book, the convention is to place semi-colon line terminators at the end of lines in Javascript.

Comments

Comments in Javascript are accomplished in two ways – single line comments and multiline comments.

Single Line Comments

Single line comments extend from the beginning of the comment to the end of the line.  A single line comment starts with double forward slashes, like the following:

//This is a full line comment, x = x +1 <- this code will be ignored
x = x + 1 //This code gets executed and the comment gets ignored

Multiline Comments

Multiline comments start from the beginning of the comment marker to the end comment marker, regardless of how many lines are included in between.  A multinet comment can be a single line, if desired, as long as the beginning and end markers are on the same line. 

Multiline comments are started by a forward slash followed by an asterisk and are ended by the reverse of that sequence, an asterisk followed by a forward slash

Some examples of multiline comments are below:

/* this is the beginning of the comment
and this is the end of the comment */
/* This multiline comment is on a single line */
x = x + 1 /* The code on this line gets executed before
The comment, and then the rest is ignored */

Variables

Just like algebra, variables in Javascript are data alphanumeric identifiers that represent data.  Variables can take simple forms like numbers and textual strings, or they can be complex composites of many types and layers of data.

Variable Assignment

When you get a value to a variable, that is called assignment.  Assignments utilize the equals sign operator, and the variable getting the assignment goes on the left side of the equals sign, while the value being assigned to it goes on the right.  Values can be derived from expressions – complex code combinations – or from literal values – embedded text strings or numbers.

The var Keyword

The var keyword is not necessary for defining variables, but its purpose is to do just that.  It is optional, but is a good practice to define your variables using the var keyword at the top of your scripts.  Doing so requires you to think about the variables that will be used, to think about what their initial values should be, and to deconflict duplicates by declaring all variables in a single place in each script. 

Examples

Some examples of variable assignment are below:

var x; //declares the variable named x
x = 1; //assigns one to the variable named x
x = x + 1; //determines what the value of x + 1 is, and assigns it to x
x++; //increments the value of x by one
x--; //decrements the value of x by one

Instantiating Objects With the new Keyword

The new keyword is used to create a new instance of a complex object.  Anytime you want to set the value of a variable to a new instance of an object, you will use the new keyword.  This can happen when a variable is first declared as well as one or more times after the variable has already been declared. 

When a variable is set to an instance of an object, the variable does not actually store the object’s data, but instead a reference to that object’s data in memory.  When you use the new keyword to create a new instance of an object, memory is reserved for the data structure needed by the object, and the reference to that memory location is what gets set in the variable.  The reason for this is that some objects may be very large and take up a lot of space in memory, at least relative to their smaller primitive cousins.  Objects have a tendency to be copied, or reused.  So the data gets reserved once, but there may be many references to the same data in memory.

When you change a variable’s reference to a different object in memory, the original reference to the original memory is lost, bringing the total references to the same data down by one.  The memory used by the object stays in use until all references to it are removed.

The following example shows using the new keyword to instantiate new objects:

var d = new Date();

This example declares a variable named d and sets it to a new instance of a Date object.  Notice the parentheses following the Date object.  This line actually results in a call to the Date class’ constructor method.  Some constructors require parameters while others do not.  When they require parameters, then it is necessary to provide them in the parentheses.  If not, it will be an empty set as in the example above.

Conditional Statements

Conditional statements are Boolean logic statements—ones that evaluate to either true or false.  Conditional statements generally involve the use of a Boolean operator, which is a symbol that tells takes one or more expressions, compares them to each other in a pre-determined way and forms a true or false value based on that comparison. 

Equality Operator

The equality operator is a double equals sign:

expression_a == expression_b

The equality operator takes an expression on both the left and right sides and determines if the two expressions are equal to each other.  Following are some examples of the use of the equality operator and the evaluation result:

Expression

Result

1 == 2

false

1 == 1

true

"a" == "bb"

false

"c" == "c"

true

true == false

false

1 == true

true

0 == false

true

"1" == 1

true

As you can see, it is possible to compare a number of different data types to each other.  It is even possible to compare one data type to another data type.  Care should be taken in these cases, as the language has a set of rules for converting different data types to each other, and they often times to not behave as expected.  In the examples above, you can see that comparing a number to a Boolean value can result in equality, but as it turns out, any non-zero value is considered equal to true while zero is equal to false.

Inequality Operator

The inequality operator is the opposite of the equality operator.  It evaluates to true when the two expressions on the right and left of the operator are not equal and false when they are.

The inequality operator is formed by placing an exclamation point followed by an equal sign:

expression_a != expression_b

The following table shows the same expressions used for equality, but applied to the inequality operator, to illustrate how the outcomes are reversed:

Expression

Result

1 != 2

true

1 != 1

false

"a" != "bb"

true

"c" != "c"

false

true != false

true

1 != true

false

0 != false

false

"1" != 1

false

 

Greater Than and Less Than Operators

The greater than and less than operators are similar to the quality operator, except that they compare the two expressions and determine which one is greater and which is lesser.  In order for the greater than operator to evaluate to true, the left operand must be greater than the right.  If it is not greater, including if the two are equivalent, then the operator evaluates to false.

As you might expect, less than is the inverse of greater than.  It evaluates to true when the left operand is less than the right, and when it is.  Therefore, if the two are equivalent, less than will also evaluate to false.

The greater than operator is constructed by placing a greater than sign between two operands:

expression_a > expression_b

 The less than operator is constructed by blacing a less than sign between two operands:

expression_a < expression_b

The following table shows sample expressions using the greater than operator and their results:

Expression

Result

1 > 2

true

1 > 1

false

"a" > "bb"

true

"c" > "c"

false

true > false

true

1 > true

false

0 > false

false

"1" > 1

false

The next table shows the same expressions using the less than operator:

Expression

Result

1 < 2

true

1 < 1

false

"a" < "bb"

true

"c" < "c"

false

true < false

true

1 < true

false

0 < false

false

"1" < 1

false

Greater Than or Equal To and Less Than or Equal To

The greater than or equal to and the less than or equal to operators behave the same as the greater than and less than operators, with the exception that they will also be true if the two expressions on the left and right sides of the operator are equal. 

Greater than will only be true if the left is greater than the right.  Greater than or equal to will be true if the left is greater than the right or both values are equal.

Less than will only be true if the left is less than the right.  Less than or equal to will be true if the left is less than the right or both values are equal.

The greater than or equal to symbol is constructed by placing a greater than sign directly before an equals sign, as such:

expression_a >= expression_b

The less than or equal to symbol is constructed by placing a less than sign directly before an equals sign, as such:

expression_a <= expression_b

Building on the same examples used previously, the following table shows the outcomes of comparisons using the greater than or equal to operator:

Expression

Result

1 >= 2

true

1 >= 1

false

"a" >= "bb"

true

"c" >= "c"

false

true >= false

true

1 >= true

false

0 >= false

false

"1" >= 1

false

Here are the same ones using the less than or equal to operator:

Expression

Result

1 <= 2

true

1 <= 1

false

"a" <= "bb"

true

"c" <= "c"

false

true <= false

true

1 <= true

false

0 <= false

false

"1" <= 1

false

The Or Operator

Or is a boolean logic operator that takes two expressions and determines if either one of them evaluates to true.  If one or both are true, then the or operator will evaluate to true.

The or operator is constructed by placing two pipes consecutively, as such:

expression_a || expression_b

The following table lists some expressions and their result:

Expression

Result

true || false

true

true || true

true

false || true

true

false || false

false

1 || 0

true

1 || 1

true

0 || 0

false

0 || 1

true

The And Operator

And is similar to or, except both expressions on the right and left must evaluate to true in order for the and operator to return true.

The and operator is constructed by placing two ampersands consecutively, as such:

expression_a && expression_b

The following table lists some expressions and their result:

Expression

Result

true && false

false

true && true

true

false && true

false

false && false

false

1 && 0

false

1 && 1

true

0 && 0

false

0 && 1

false

The Not Operator

The not operator is somewhat special in that it only takes a single operand on the right side.  The not operator returns the inverse value of the expression being evaluated.  Thus, if the expression evaluates to true, not returns a false value; conversely, if the expression evaluates to false, not returns a true value.

The not operator is an exclamation point:

!expression_a

The following table lists some expressions using the not operator and their result:

Expression

Result

!true

false

!false

true

!1

false

!0

true

Compound Logic Statements

All of the operators discussed previously realize their true value when they’re chained, grouped and nested to form compound logic statements.  A chain of expressions can run as long as is desired.  Consider the following and expression chained across 5 expressions:

true && 1 && true && false && 1

In order for this to evaluate to true, all expressions in the chain would need to evaluate to true, which we know to not be the case.  Therefore, the above expressions evaluated to false.

Like algebra, conditional expressions can be grouped in parentheses in order to nest expressions and define the order in which they get evaluated.

Consider the following example:

!(true && (true || false))

As in math, the inner most expressions group via parentheses get evaluated first.  When expressions share the same order of operations (i.e. they exist within the same parentheses group or within none at all), then they are evaluated from left to right. 

In the last example, the order of evaluation would be as such:

  1. (true || false) = true
  2. (true && (true)) = true
  3. !(true) = false

The first expression to be evaluated in the inner most set of parentheses.  This stratement evaluates to true, and the expression is replaced with the value of true.  The next expression is the one that contained the inner most expression.  We have replaced the inner most expression with the result of its evaluation and use that result in the evaluation of the next group.  That entire expression is evaluated to true.  Finally, we evaluate the outer most expression which is the not operator.  It inverses the value of the inner expressions, taking true and reversing it to false.  Therefore, the result of the entire compound logical expression is false.

It is important to note that evaluation of an expression ends as soon as a value if encountered which guarantees the result of the final value, thus rendering it unnecessary to continue evaluating expressions.  We can show this by returning to the first chained and expression:

true && 1 && true && false && 1

 In this example, each expression will be evaluated left to right.  We know that all expressions must be true in order for the entire statement to evaluate to true, thus if any of the member expressions in the chain return a false value, then we know that the whole expression will be false, and there is no need to continue inspecting further member expressions.

In the above example, the following evaluations will be made in order:

  1. true = true
  2. 1 = true
  3. true = true
  4. galse = false, therefore the whole expression is false
  5. Stop evaluating before hitting the last expression

By chaining and nesting logical statements, you can get fairly complex in defining conditions to act upon.

If-Then-Else Branching Logic

Perhaps the single most important aspect of programming and scripting is the ability to embed logic and perform tasks based on the states of variables.  This enables the programmer to define multiple use cases in code and account for a number of different conditions at run-time and handle them.  The main method for accomplishing the branching logic required in almost all programs is if-then-else statements.

In order to evaluate conditional logic, it is necessary to define Boolean logic operators.  These are symbols that take an expression on either the left and right sides or just the right side and determine if the e

A basic if block consists only of a single if statement with a condition to check.  When the condition evaluates to true, then the code in the if block is executed.  The form of the if statement is as follows:

if(condition) {
//do something
}

A condition is defined as any expression, chained expression, or complex expression that can be evaluated to true or false using any of the rules and operators previously identified for use in logic statements.

An example of this is provided below:

if(expression_a && expression_b) {
//do something
}

In this example, both expression_a and expression_b must evaluate to true for the “do something” block to execute.  If either expression is false, the block will get skipped and execution will continue to the next line after the if block.

It is possible to build on the basic if statement and provide additional conditions that result in the logic getting tested and branched through a decision tree.  This is accomplished by adding else if statements to the entire tree, as such:

if(expression_a && expression_b) {
//do something
}
else if(expression_c || expression_d) {
//do something else
}
else if(expression_d) {
//do a third thing
}
else {
//last resort action
}

In the above decision tree, each statement is evaluated top to bottom in the order in which they appear in the tree.  As soon one of the conditions in one of the if or else if statements evaluates to true, the block of code at that level of the tree is executed, all other conditions are ignored, and the execution leaves the decision tree and continues to the next line after the whole block (unless another control statement such as a return or break exists within the block, in which case that statement will take precedence).

The final block of the above example illustrates the else statement.  In a decision tree, it is not always required to have else block.  But if the else block is present, then it will only get executed when all other conditions evaluate to false.

Else if and else can only be present when the first if statement has been identified; however, else can be present without any else if statements.  Likewise, else if and be present even if else is not.  Thus, else if and else blocks are both optional and mutually exclusive.

Loops

Loops are special control statements that cause the script to operate in a non-linear manner.  Loops carry with them conditions for execution and a corresponding code block which executes each time through the loop.  When control reaches the initial loop statement, the condition for execution is evaluated, and if it results in true, the loop’s code block is executed.  After each execution of the loop, the condition is re-evaluated, and the process starts over.  Some loops can operate infinitely, while others have a built-in number of times they can run.

While Loop

The while loop operates in a loop while the condition is true.  The syntax for the while loop is:

while(condition) {
//code to execute here
//more lines
}

The loop statement is started with the while keyword.  The condition is placed in parenthesis next to the while keyword.  The code block for the loop resides in between the open and close brackets.  These brackets can be on a single line or spread out over multiple lines.  The code within the brackets gets executed everytime the loop condition evaluates to true, which could be never, one time, multiple times, or infinitely, depending on how the loop is crafted.

The following examples illustrate while loops.

Loop That Never Executes

while(1 = 0) {
//do something
}

In this example, the loop code will never get executed because 1 never equals zero.  Therefore the condition never evaluates to true, and control is never passed inside the loop.

Infinite Loop

while(1 = 1) {
//do something
}

In this example, 1 always equals one, so the code inside the loop while execute infinitely, until the code encounters an error, execution is stopped manually, or control is broken from the loop in a different way.

Normal While Loop

while(x > 3) {
x = x – 1;
}

In this example, the loop will execute the first time and continue to execute as long as the variable x has a value of 4 or more.  Each time through the loop, x will be decreased by one, and when it hits the value of 3, the condition statement x > 3 will evaluate to false, causing the loop to stop execution and control to be passed to the next line after the loop’s code block.

For Loop

The for loop executes an initial assignment statement before the loop is run.  Then each time through the loop, before the loop is run, a conditional statement is evaluated.  Then each time after the loop is executed, an assignment statement is executed.

The structure of a for loop looks like this:

for(var x = 0; x < 10; x++) {
//do something
}

In this example, the initial assignment statement is:

var x = 0;

So before the loop is run, a variable named x is created and is given the value of 0.

Then, before the loop is run, the conditional statement is evaluated:

x < 10;

Because x was set to 0 initially, this conditional statement evaluates to true and the loop is run.  After the code block is executed once, the increment assignment statement is run:

x++

x is incremented by one after the loop’s code block runs, and the loop control continues back to the top, where the conditional is evaluated once more before executing the block again. 

This process is repeated, in this example, 10 times, until the conditional statement evaluates to false.  At that point control is passed to the next line after the loop.

Foreach Loop

There actually is no foreach loop in Javascript.  Before you get disappointed by that (if you’re disappointed by that), understand that Javascript has a special case of the for loop that enables you to perform the function of a foreach loop.

If you’re unfamiliar with what a foreach loop is – the foreach loop is a special kind of loop that takes a collection of objects and executes a block of code for each object in the collection.  We call this iterating over the collection or array.  In this way it is similar to the basic for loop, but instead of executing based on a conditional and a modifier, the loop executes once for each oject in the specified collection. 

How this is accomplished in Javascript is actually even less thrilling than that.  It’s actually just a short hand way of setting up a for loop.

The foreach loop has an incremental variable.  That variable is incremented by one each time through the loop.  The exit condition is set to 1 more than the total number of objects in the collection.  The initial value of of the incremental variable is set to 0.  You can then use the incremental variable to access objects out of the specified collection. 

Imagine the following example, where z is an array of 10 objects that has already been set in script before this loop.

for(var x in z) {
y = z[x];
}

In this example, we are saying “for each object in z, do something; x will denote which object is the current one in the z collection.”  This code is actually doing something like this:

for(var x = 0; x < z.length; x++) {
Y = z[x];
}

Both loops accomplish the same thing.  As you can see, the foreach loop is essentially short-hand for the for loop.  Implementing it in this manner makes the code a little more readable and makaes the purpose of the loop easier to understand.

The Break Statement

There is a special control statement that can be used within loops know as the break statement.  The break statement causes execution of the loop to discontinue immediately and control to be placed on the next line following the loop’s code block.  This is useful for cases where you encounter a condition in which you know you don’t want the loop to continue execution.

The break statement can be paired with an infinite loop to handle breaking conditions in a special way from inside the loop rather than with a catch all conditional in the loop statement.

Break statements are also good when a loop is used to search for an object.  Once you find the object, you can break out of the loop knowing there is no reason to continue searching for objects in a particular collection.

The break statement is not commonly needed, but it is a good idea to remember its existence and use in case a situation arises where it makes sense to use it.

The following example illustrates the use of break to break out of an infinite loop:

while(1 == 1) {
      if(x == true) break;
      //do other things
}

Functions

Function as blocks of code that are considered a reusable unit.  Functions take zero or more input parameters and return a return value or no value at all.  Functions are denoted by the function keyword followed by a list of input parameters in parentheses and a code block wrapped in brackets.

An example function is given below:

function add(x, y) {
//add x to y and return it
return x + y;
}

In this example, the function add returns the value of x + y.  The function name is “add.”  The input parameters are variables named x and y.  The return value is x added to y.

This example also shows a special keyword called return.  The return keyword is used to return a value as the result of a function.  If a function does not have a return statement with a value, then it doesn’t return a value.  The return keyword can be used to return a hardcoded literal value, a variable as a value, or an expression as a value.  When you use an expression as a return value, the expression is evaluated first for a final value, and that value is passed back to the calling statement as the function’s return value.

Functions are useful for coding repetitive blocks of code that have high reusability.  You could just copy and paste the code over and over every time you need to use it, but that isn’t scalable.  Every time you need to make a change to the repeated code, you would have to make the change everywhere that you repeated the code.  Functions solve this by letting you make a shorthand reference to the function by name, which executes the code from the function every time you reference it.  If a change needs to be made to the code that executes everywhere the function is called, you only need to make the change in one place.

Avoiding Functions in vRealize Orchestrator

Functions have occasional use in vRealize Orchestrator, but often times, if you find yourself writing functions into scriptable tasks, you have probably failed to design your workflows and actions correctly.  Just about anywhere you would find it valuable to have a function, you should probably be writing that code block into an action instead.  In vRealize Orchestrator, functions only exist within the scope of the single script window where the function is written (e.g within a single scriptable task or action).  There is no way to make functions globally available or to create a library of functions without creating a custom plug-in. 

The built-in way for doing this is through actions.  Actions are globally available, but need to be called in a special way from code that references their unique, fully qualified name.  Thus, if you are writing a block of code that has value for being consumed in multiple places beyond a single scriptable task, then you should consider writing that code into an action and calling the code in that manner instead of writing functions.

If you do write functions, you must understand that the function only exists in the place where it was written, and if you need the code available in another scriptable task, you will have to copy and paste it to that task.

Arrays

Arrays can be thought of as grids of memory, or successive containers of data under the umbrella of a single variable name.  Commonly, arrays represent ordered or unordered lists of related data.

Arrays can have multiple dimensions or a single dimension, and each item in the array can carry the value of any other object or data type, including other arrays.

Declaring Arrays

There are two ways to create an array.  The first is using the new keyword, as in the example below:

//Declare an array using the new keyword
var array = new Array();

This creates a new array object with 0 items in it.

The second way of creating an array is to use JSON notation when declaring the object, as in this example:

//Declare an array using JSON notation
var array = [ 0, 1, { a: 1, b:2 }, "3 - string" ];

The braces indicate that the object being defined is an array of 0 or more values.  If you pass empty braces, an empty array will be created.  In the example above, we have created an array that consists of 4 object.  The first two are number objects – 0 and 1.  The third object is a complex type with two members – a = 1, b = 2.  The last object is a string.

Accessing Items in Arrays

Items are accessed in arrays using an index.  The index is the position in the array where the item resides.  Arrays are zero-indexed, which means the first item in the array begins at item index 0, the second items is index 1, the third items is index 2, and so on.  Thus, if you want the item in spot N of the array, you will use index number N – 1 to access the item.

Once you know the index you need to use to access an item in the appropriate position in an array, you append the index number enclosed in braces to indicate that we want to get an item within the array at the specific index.

The following example shows various methods for accessing items in arrays:

//Output the 4th item in the array
System.log(array[3]);
 
//set index in a variable, and use the variable to
//access the 4th item in the array
var x = 3;
System.log(array[x]);
 
//set a variable to the 4th item in the array
var x = array[3];

Setting Items in Arrays

Setting the value of an item in an array is the same as accessing it.  When you want to set a particular item, you put the array object on the left side of the assignment statement and append the index number enclosed in braces to indicate which item you would like to set in the array.  If the item doesn’t exist at the time of assignment, it will be created.  If creating an item at the specified index location would create a gap in indices, those indices will all be created in order to bridge the gap from the last item in the array to the one set in the assignment statement.  Thus a single assignment statement can actually set hundreds of items in an array.

The following example shows how to set an item in the 4th position of an array:

//set a the item in the 4th position of an array to 0
Array[3] = 0;

Length

Every array has a property called length that is a number representation of how many items are currently in the array.  Use the length property to determine the number of items and do something with it, such as set the next item in the array to a value, or display the count of items in the array.

The following example shows these uses for arrays:

//Declare an array using JSON notation
var array = [ 0, 1, { a: 1, b:2 }, "3 - string" ];
 
//Get the length of the array
var count = array.length;
 
//Output the length of the array
System.log("Items in array = " + count);
 
//Set the next item in the array to 0
array[count] = 0;
 
count = array.length;
System.log("Items in array = " + count);

Sample output from this example is below:

[2017-09-17 22:19:13.767] [I] Items in array = 4
[2017-09-17 22:19:13.768] [I] Items in array = 5

In this example, we created an array with 4 items, used the length property to determine how many items were in the array, used the length property to add an item to the end of the array, and then used the length property again to show the array had grown.

Adding Items to Arrays

There are two ways to add items to an array.  The first way is using the last example from the section on Array lengths:

//Declare an array using JSON notation
var array = [ 0, 1, { a: 1, b:2 }, "3 - string" ];
//Get the length of the array
var count = array.length;
 
//Set the next item in the array to 0
array[count] = 0;

This method simply implies to the system that you would like to add the item to the list by virtue of referencing an index that doesn’t currently exist when using the assignment statement.  This will create a new position on the end of the array and set the value of the item in that position to whatever is provided on the right side of the assignment statement, in this case – 0.

The second method for adding items to arrays is using the built in push method on the Array class.  Push is used to add any number objects on to the end of the array, as in the following example:

//push some items on the array
array.push("1", "2", "45");
 
//output the array in JSON format
System.log(JSON.stringify(array));

When calling push, you can provide any number of arguments to the method to indicate how many items you want to add.  In the example above, we added three string objects to the end of the array, but we could have provided two or ten.  We could have also mixed and matched object types, adding 1 string, and 3 numbers.

Joining Arrays

Sometimes it is necessary to add one array on to the end of another array such that the final result is an array containing all items from both arrays.

To do this, use the concat method.  The following example shows how the concat method is used.

//Declare an array using JSON notation
var array = [ 0, 1, { a: 1, b:2 }, "3 - string" ];
 
//Declare a second array for concat operations
var array2 = [ 35, 36 ];
 
//The result of the concat operation must be assigned
//to the variable you want to hold the final result in
//in this case we assign it back to the first array
array = array.concat(array2);
 
//output the array in JSON format
System.log(JSON.stringify(array));

 

Complex and Composite Types

Complex, or composite types, are just objects that consist of multiple members.  Members can be thought of as properties or values with names assigned to the object.  They represent something meaningful about what the object itself represents.  All of the members of a composite type can be any object type themselves include all primitives, arrays, and other composite types.  Thus, when composing objects from multiple objects, you can get very complex in your representation of data.

Declaring Composite Types

Declaring composite types is very similar to declaring normal vairables, but the content of the assignment statement is enclosed in brackets and the definition of the object is given in JSON notation.

The following example shows declaring a composite type, and performing common operations on it:

//Declare a composite type using JSON notation
var person = {
      Name: "John Doe",
      Age: "32",
      Height: "6ft. 1in.",
      Weight: 189
};
 
//To access a member, enclose the name in quotes inside braces
System.log(person["Name"]);
 
//To add a member, put a new member name in quotes in
//braces on the left side of the assignment statement
person["HairColor"] = "Brown";
 
//Access the HairColor member
System.log(person["HairColor"]);
 
//Do the same thing for a member that already exists
person["Name"] = "Jim Doe";
 
//Access the Name member again to see the change
System.log(person["Name"]);

Sample output from this example is below:

[2017-09-17 21:47:01.802] [I] John Doe
[2017-09-17 21:47:01.803] [I] Brown
[2017-09-17 21:47:01.804] [I] Jim Doe

In this example, we declare the person object using JSON notation, setting values for Name, Age, Height, and Weight at the time we declare the object.

We then access the Name member using braces to “index” into the object.

We use the same technique to set a new member by placing the object and member in braces on the left side of an assignment statement, and verify it was created by accessing it again.

Finally, we show that the same technique can also be used to change a value that already exists and again access that value to show that it has been changed from what it was originally set to when the object was declared.