TIScript supports named and anonymous (lambda) first class functions. Functions are objects of the Function class.

Named functions

Named functions are declared using the following syntax:

function <function-name> ( <parameters> )
  //...function body
<function-name> is a function name, either: simple <nmtoken> , or
compound name: <nmtoken1> [ . <nmtoken2> [ . <nmtoken3> [ . <nmtokenN> ]]] 1)
<parameters> is a list of formal function parameters:
[<parameter-name1> [ , <parameter-name2> [ , ... <parameter-nameN> ]]]

Anonymous functions

Anonymous (a.k.a. lambda) functions can be declared in-place by using the following forms:

Classic JavaScript form:

function ( <parameters> ) { <statements> }

"This" lambda function declarations:

Functions declared this way own this environment variable as any other functions.

Single statement lambda function form:

: <parameters> : <statement>

Block lambda function form:

: <parameters> { <statements> } 

"fat arrow" lambda function (a.k.a. "that" lambda function) declarations:

Such functions do not own this environment variable. this environment variable gets resolved to this of outer function as in "arrow" functions in ES6.

Single statement lambda function form:

( <parameters> ) => <statement>;

Block lambda function form:

( <parameters> ) => { <statements> } 

Single parameter arrow function can be declared without ( and ) brackets as :

name => <statement>; // or
name => { <statements> } 

Nested functions (functions inside other functions) are allowed.

Async functions

async function ( <parameters> ) 
  (<statement> | <await-expression>)* 

Async functions executed asynchronously and allowed to use await expressions inside.

Generator functions

function* ( <parameters> ) 
  (<statement> | <yield-statement>)* 

Generator function is used in for(var x in generator)  statement. Generators emit values by using yield statements.

Event functions

Event handling function is a variant of normal function but function name given as a string. Instead of function event functions are declared with event keyword:

event name[.namespace] [$(selector)]  [( [eventObj [,element] ) ]
  //... event handling function body


Optional parameters

TIScript supports optional parameters in function declarations:

Parameters with default values

Some parameters in the function declaration may have the default value defined, for example:

function Foo(a, b, c = 12)
  return a + b + c;

Such a function can be called with either two:

var r1 = Foo(1, 2);    // r1 = 15

or three actual parameters:

var r2 = Foo(1, 2, 3); // r2 = 6

The parameter with the predefined value must not have non-optional parameters to its right in the parameter list. In other words, only the last (or all) parameters can have default values.


a.k.a. Parameter vectors

There are situations when you need to define functions with the number of parameters unknown upfront. Such functions can be declared as:

function Bar(a, b, rest..)
  var total = a + b;
  for (var n in rest) 
    total += n;
  return total;

At runtime, the variable rest will contain an array with actual parameters passed into the function. So, after

var r1 = Bar(1, 2, 3, 4);

r1 will contain value 10 , and after

var r2 = Bar(1, 2);

r2 will contain value 3

Stringizer functions

Stringizer function is a normal function or method with the name starting from '$' (dollar) sign.

While parsing call of such a function tiscript treats everything inside '(' and ')' as a literal string. Example:

var bodyDiv = self.$( div#body );

Such a call is a direct equivalent of the following:

var bodyDiv = self.$( "div#body" );

If text inside '(' and ')'  contains unpaired bracket symbols like   ')' and '}'  such symbols have to be escaped as \)  and \}.

Stringizer parameters

The text inside '(' and ')' can contain so called tiscript code injections - sequences of tiscript code that needs to be executed and its string result to be inserted inline. To include such a code inside the string it has to be enclosed into '{' and '}' brackets. Example:

var n = 3; 
var nthDiv = self.$( div:nth-child({ n }) );

The $() call above will be translated by the parser into the following:

var nthDiv = self.$( "div:nth-child(", n , ")" );

Defining custom stringizer functions

Here is real life example of the stringizer function that can be used in Sciter for inserting HTML fragments:

function Element.$append( params.. ) // accepts html fragments with inclusions as params vector
  for( var i = 1; i < params.length; i += 2 ) // each odd parameter is an inclusion - result of the correspondent { ... } expression.
    params[i] = params[i].toHtmlString();     // convert our inclusion into escaped HTML string for safety.
  this.insert( params.join("") );             // combine all params into single string and call Element.insert(html)
                                              // method of the DOM element in Sciter.

Having such function in place we can use it now as:

var arr = [1,2,3];
var table = self.$( table#some );
for( var n in arr )
  table.$append ( <tr><td>Cell #{n}</td></td> );

Code above will insert three rows/cells with texts: "Cell #1", "Cell #2" and "Cell #3" into the table. Pretty convenient, isn't it?

Function call with literal object

If some function accepts single parameter-object then it can be called omitting '(' and ')' brackets like this:

  foo { one:1, two:2 }

that is an exact equivalent of this standard JavaScript call:

  foo ({ one:1, two:2 })

1) Declaration of functions with compound names is a short form for the expression:
name1.name2.name3. ... .nameN = function( <parameters> ) { <statements> }