Welcome to js.component!
js.component is a 4D component comprising 40+ classes with 450+ functions that:
- Fills many holes in the 4D language
- Dramatically improves the developer experience
- Reduces method count, lines of code, and coding time
- Provides multiple new ways to debug your code
- Implements key object-oriented techniques that are not widely known in the 4D world
js.component is 100% pure 4D code, 100% preemptive-safe, and 100% guaranteed to make you a more effective, more productive and more happy programmer!
js.component is both broad in scope and deep in functionality. Yet it has minimal impact on your existing projects — there are only ten methods that live in the global namespace! Every function has been carefully designed to provide maximum utility, flexibility, and ease of use.
js.component requires 4D v19 R5 or later.
To install js.component, place it (or an alias/symlink to it) in the
Components folder of your database, as you would any other 4D component.
js.component is not compiled so that you can see (and hopefully learn from!) the source code. If your host application is distributed in compiled form, you can open js.component as a project and compile it according to your preferred settings.
It is recommended that you add the following lines early in the
On Startup and
On Server Startup methods (or to methods that are called by them):
// You should call this in the main application process before any other // processes are started that might use DateTime. DateTime() // If you want to use js.component error handling, you MUST do this // to synchronize error handlers with the host db. _.setHostOnErrCall(Formula(ON ERR CALL($1))) // If you don't want to see a debug alert when an uncaught error occurs // (e.g. when you are running on Server), you should create your own // uncaught error handler and set it here. If (Application type=4D Server) _.setUncaughtErrorHandler(Formula(uncaughtErrorHandler($1))) End if
For a complete list of what has changed in each release, see the release notes.
This documentation follows the format and conventions of the new 4D documentation at developer.4d.com, so it should seem familiar. Extensive links have been provided to make navigation easy.
The headers of the documentation (which includes function names) are searchable via the search box in the upper right of the page. On the desktop, pressing
s focuses the search box.
Throughout this documentation you will see parameters with the type
Callable is any object that has both
.apply() properties which are formulas. This is done primarily to allow you to use formulas interchangeably with functors when using js.component. Why use a
Functor instead of a formula?
Functors are objects that can have properties. Thus they can maintain state and determine what
Thisrefers to when called.
The implementation of functors can be arbitrarily complex, whereas formulas are limited to a single line of code.
Some of the classes documented here are interfaces, which represent the shape of classes you will define to provide custom functionality. For example, the
MochaReporterDelegate interface is not actually a class, but rather a description of the functions that a class must implement in order to be used as a delegate for the
Accessing js.component classes
Almost all of js.component’s functionality is provided by classes, along with a very small set of global methods. The publicly accessible classes are available via the
.js namespace. For example, to instantiate an instance of the
Error class, you would use:
$error:=cs.js.Error.new("Something went wrong")
js.component can broadly be split into several categories of functionality.
Lodash class itself contains over 100 functions 🚀 covering a broad range of functionality. It is perhaps the best place to start exploring js.component.
Mocha unit testing framework
The classes in this component use a few key object-oriented design patterns:
- Class statics
A singleton class is a class that is designed to be global, and thus have one and only one instance. The following classes in js.component are (or are designed to be) singletons:
Lodash and its private friend classes
You manage singletons with the methods in the Singletons category.
A facade class provides a single API to instances of other classes which provide the facade’s functionality. This allows the functionality to be split up into multiple classes, which can be tested and maintained independently, while still providing a single API to the user.
Lodash class, for example, is a facade to multiple private classes.
A handle/implementation is similar to a facade in that the handle class provides a public API to an instance of the implementation class. Unlike a facade, however, the implementation class is provided by the user. Unlike a delegate, the implementation class provides the functionality of the handle class, rather than just providing a way to customize the behavior of the handle class.
Functor class and its corresponding implementation class are an example of handle/implementation.
A delegate class is provided by the user and serves to customize or augment a subset of the functionality of the parent class. Delegate classes in this documentation are always interfaces and the class name ends with "Delegate".
MochaReporter is an example of a class that uses
MochaReporterDelegate as its delegate.
In most object oriented languages, there are two types of class methods and properties: instance and static.
As in many other areas of the language, 4D’s terminology is, shall we say, “unique”: what it calls “methods”, almost every other language calls “functions”, and vice versa.
Instance methods and properties are accessed through individual instances of a class. Static methods and properties are accessed through the class object itself, which makes them global in nature.
4D unfortunately does not natively support static methods or properties. js.component works around this through the following convention:
For any given class
Foo, a parallel class called
FooStaticis created which contains “static” functions and properties.
A global method (what 4D calls a “method”)
Foois created which uses the
instance()method to return a singleton instance of the
To access the (pretend) static functions and properties on the
Foo class, you would use this:
I call them “pretend” statics because if 4D supported native class statics, the code would most likely be like this:
js.component uses this trick for
You can add properties and functions to a class object in 4D, but they are ephemeral — they will be lost when any classes’ source is modified and 4D internally rebuilds the
cs class store. This is why js.component uses a parallel “static” class to hold static properties and functions.