Create large-scale, object-orientated architectures using classes, interfaces, type hinting and more in JavaScript

Learn

Begin

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. 	<meta charset="UTF-8">
  5. 	<title>My Document</title>
  6. </head>
  7. <body>
  8. 	<!-- Main body -->
  9. 	<script src="path/to/picket.js"></script>
  10. 	<script>
  11. 		start(
  12. 			'MyNamespace.Start',
  13. 			{
  14. 				MyNamespace: '/public/scripts/my',
  15. 				CoolLibrary: '/public/scripts/vendor/cool-library/dist'
  16. 			}
  17. 		);
  18. 	</script>
  19. </body>
  20. </html>
Start.js
1
define(
2

					
3
'require CoolLibrary.Application',
4
'require CoolLibrary.Application.Bootstrap.Authenticator',
5
'require MyNamespace.Application.FrontController',
6
'require MyNamespace.Application.Bootstrap.Database',
7

					
8
'class MyNamespace.Start',
9
{
10
    
11
    'public construct ()': function()
12
    {
13
        
14
        var application = new CoolLibrary.Application(new MyNamespace.Application.FrontController());
15
        
16
        application.bootstrap([
17
            new CoolLibrary.Application.Bootstrap.Authenticator(),

We built Picket in order to make writing complex JavaScript more manageable

Scalable

In Picket, each class is defined within one script file. That file is then loaded if any other class specifies it as a dependency meaning you don't have to manage script inclusions.

Language features too are built towards large-scale architectures with a strong dedication to object-orientation. Build code which does not encourage strong-coupling, is changeable and where each element is concerned only with itself.

Testable

Picket was built with testing in mind. Object-orientation, coupled with dependency injection and the ability to mock classes and interfaces allow you to test each individual element of your code without side-effects from other classes. This allows you to easily write code that is tested from top to bottom.

Predictable

Everything you do in Picket is type-safe meaning that properties and constants will hold what you expect them to hold; methods and events will recieve and provide what you expect. In truth, Picket will throw an error if this is ever not the case.

This means you can code confidently knowing that whenever something is wrong, you'll know about it immediately.

Simple namespaced classes with inheritance

Classes and their location are defined in a simple elegant way, as is their relationship to their parents.

  1. define(
  2.  
  3. 'class My.Child extends My.Parent',
  4. {
  5. 	
  6. 	// ...
  7. 	
  8. });

Interfaces and abstract classes

Interfaces can be defined and implemented, creating a contract between related classes and doing away with tight coupling.

  1. define(
  2.  
  3. 'interface My.IInterface',
  4. [
  5. 	
  6. 	'public doSomething ()',
  7. 	'public doSomethingElse (number) -> string'
  8. 	
  9. ]);

Private and protected members

Class members are defined as public, private or protected to ensure that you can write code that keeps its internal workings hidden.

  1. 'private myValue (string)': null,
  2.  
  3. 'public setMyValue (string)': function(value)
  4. {
  5. 	this.myValue('_' + value);
  6. }

Type Hinting

Properties, methods, events and constants all define rules regarding what types of variable they are prepared to deal with. Picket ensures that any badly-typed value is caught immediately.

  1. 'public myMethod (Date) -> string': function(date)
  1. myObject.myMethod(new Date()); // Returns string
  2. myObject.myMethod('November 30th'); // Errors - invalid argument

Optional arguments and default values

Method arguments can be defined as optional or be defined alongside a default value which is used if the user chooses to omit one.

  1. 'public myMethod (string = Example, number?)': function(string, optionalNumber)
  1. myObject.myMethod(); // Valid
  2. myObject.myMethod('Other example'); // Valid
  3. myObject.myMethod('Other example', 10); // Valid

Method overloading

Multiple methods with the same name but different argument type signatures can be defined allowing for a complex variety of permutations whilst not complicating the implementation.

  1. 'public compareDate (Date) -> boolean': function(date){},
  2. 'public compareDate (number, number, number) -> boolean': function(year, month, day){}

Class events

Classes can define events in order to declare information to other classes. Other classes can choose to bind to these events, if they are interested.

  1. eventObject.bind('change', 'handleChangeEvent');

Constants

Classes can define constants; properties that do not change value through the life of the program.

  1. 'public constant TAU (number)': 6.28

Auto file loading

Each class defines its dependencies and these are all loaded behind the scenes before any instance of the class is instantiated.

  1. define(
  2.  
  3. 'require My.Application',
  4. 'require My.Application.Controller',
  5.  
  6. 'class My.Start',
  7. {
  8. 	
  9. 	'public construct ()': function()
  10. 	{
  11. 		new My.Application(new My.Application.Controller()).run();
  12. 	}
  13. 	
  14. });

Reflection API

Picket has a thorough set of reflection classes which allows your code to inspect details of classes and interfaces and their members. This allows you to, for example, check the class name of an object or check whether its third argument of a given method is optional.

  1. var reflectionClass = new Reflection.Class(myObject);
  2. reflectionClass.getName(); // Class name
  3. reflectionClass.getMethods('myMethod')[0].getArguments()[2].isOptional(); // Boolean