CrxOop CrxOop: Bringing Object Oriented Programming, and Proper Prototype Based Programming, To Javascript
The aim of the library documented below is to provide developers with a solution to allow development using interfaces and classes as they are known in other object oriented programming (OOP) languages such as C++, C#, Java and PHP. Further more, V1.4 introduces structures, a generalization of the concept of prototypal inheritance, known here as POBP.
Subject
Body*
Email
SUBMIT CLOSE
Menu

3.6.2 O

'O' is a function. While 'this' allows you access to private variables and functions, as well as publics, of the current instance, 'O' allows access to privates of other instances.

'O' also allows friend classes to access the privates of instances of classes be friending said classes. When used this way, 'O' requires two arguments.

Internally 'O' will automatically cast the object to the relevant type and return 'this' of that object. Hence 'O' must never be passed to functions as parameters or from functions as returns, and because 'O' returns 'this', the rule applies to its return too. 'O' returns null if the object can not be casted.

'O' is also available in static functions.

JS (Tree)
crx_registerClass("ExampleClass1",
{
   FRIENDS: ['FriendOfExampleClass1'],
   PUBLIC:
   {
      VARS:
      {
         "publicVar": "I am ExampleClass1's publicVar"
      },
      FUNCTIONS:
      {
         "publicFunction": function(pExampleClass1)
         {
            //   Accessing private members
            console.log(this.O(pExampleClass1).privateVar);


            //   And also publics,
            console.log(this.O(pExampleClass1).publicVar);
            //   but never do this, instead do,
            console.log(pExampleClass1.publicVar);
            //   but the above does not always work because pExampleClass1
            //      is not guaranteed to be an instance of "ExampleClass1",
            //      while 'O' automatically casts. Hence if you need
            //      casting, either continue using 'O' or do
            console.log(pExampleClass1.CAST("ExampleClass1").publicVar);


            //   Like 'this' in the previous section, 'O' must never be
            //      passed around, but this also applies to the return
            //      of 'O' which is another 'this'. For example, instead
            //      of returning this.O(pExampleClass1) to return the
            //      instance pExampleClass1, do the following
            return this.O(pExampleClass1).THIS;
         }
      },
      STATIC:
      {
         FUNCTIONS:
         {
            "publicStaticFunction": function(pExampleClass1)
            {
               //   Accessing private members
               console.log(this.O(pExampleClass1).privateVar);


               //   And also publics,
               console.log(this.O(pExampleClass1).publicVar);
               //   but never do this, instead do,
               console.log(pExampleClass1.publicVar);
               //   but the above does not always work because pExampleClass1
               //      is not guaranteed to be an instance of "ExampleClass1",
               //      while 'O' automatically casts. Hence if you need
               //      casting, either continue using 'O' or do
               console.log(pExampleClass1.CAST("ExampleClass1").publicVar);


               //   Like 'this' in the previous section, 'O' must never be
               //      passed around, but this also applies to the return
               //      of 'O' which is another 'this'. For example, instead
               //      of returning this.O(pExampleClass1) to return the
               //      instance pExampleClass1, do the following
               return this.O(pExampleClass1).THIS;
            }
         }
      }
   },
   PRIVATE:
   {
      VARS:
      {
         "privateVar": "privateVar"
      }
   }
});
crx_registerClass("ExampleClass2",
{
   EXTENDS: "ExampleClass1",
   PUBLIC:
   {
      VARS:
      {
         "publicVar": "I am ExampleClass2's publicVar"
      },
      FUNCTIONS:
      {
         "test": function()
         {
            this.publicFunction(this);
            crx_static('ExampleClass1').publicStaticFunction(this);
         }
      }
   }
});
crx_registerClass("FriendOfExampleClass1",
{
   PUBLIC:
   {
      FUNCTIONS:
      {
         "publicFunction": function(pExampleClass1)
         {
            //   The following is the same as done inside
            //      ExampleClass1::publicFunction(). Notice how
            //      'O' is giving access to the friend class
            //      FriendOfExampleClass1. Also notice how in this
            //      case 'O' requires two paramters. Passing only
            //      the object will not work.
            console.log(this.O(pExampleClass1, 'ExampleClass1').privateVar);
            console.log(this.O(pExampleClass1, 'ExampleClass1').publicVar);
            console.log(pExampleClass1.publicVar);
            console.log(pExampleClass1.CAST("ExampleClass1").publicVar);
            return this.O(pExampleClass1, 'ExampleClass1').THIS;
         }
      }
   }
});

var instance = crx_new("ExampleClass2");
var instance2 = crx_new("FriendOfExampleClass1");

instance.test();
console.log('--------------------');
instance2.publicFunction(instance.CAST('ExampleClass2'));
privateVar
I am ExampleClass1's publicVar
I am ExampleClass2's publicVar
I am ExampleClass1's publicVar
privateVar
I am ExampleClass1's publicVar
I am ExampleClass2's publicVar
I am ExampleClass1's publicVar
--------------------
privateVar
I am ExampleClass1's publicVar
I am ExampleClass2's publicVar
I am ExampleClass1's publicVar
JS (Verbose)
crx_registerClass("ExampleClass1",
{
   "VERBOSE": 1,
   "FRIENDS": ['FriendOfExampleClass1'],
   "public var publicVar": "I am ExampleClass1's publicVar",
   "public function publicFunction": function(pExampleClass1)
   {
      //   Accessing private members
      console.log(this.O(pExampleClass1).privateVar);


      //   And also publics,
      console.log(this.O(pExampleClass1).publicVar);
      //   but never do this, instead do,
      console.log(pExampleClass1.publicVar);
      //   but the above does not always work because pExampleClass1
      //      is not guaranteed to be an instance of "ExampleClass1",
      //      while 'O' automatically casts. Hence if you need
      //      casting, either continue using 'O' or do
      console.log(pExampleClass1.CAST("ExampleClass1").publicVar);


      //   Like 'this' in the previous section, 'O' must never be
      //      passed around, but this also applies to the return
      //      of 'O' which is another 'this'. For example, instead
      //      of returning this.O(pExampleClass1) to return the
      //      instance pExampleClass1, do the following
      return this.O(pExampleClass1).THIS;
   },
   "public static function publicStaticFunction": function(pExampleClass1)
   {
      //   Accessing private members
      console.log(this.O(pExampleClass1).privateVar);


      //   And also publics,
      console.log(this.O(pExampleClass1).publicVar);
      //   but never do this, instead do,
      console.log(pExampleClass1.publicVar);
      //   but the above does not always work because pExampleClass1
      //      is not guaranteed to be an instance of "ExampleClass1",
      //      while 'O' automatically casts. Hence if you need
      //      casting, either continue using 'O' or do
      console.log(pExampleClass1.CAST("ExampleClass1").publicVar);


      //   Like 'this' in the previous section, 'O' must never be
      //      passed around, but this also applies to the return
      //      of 'O' which is another 'this'. For example, instead
      //      of returning this.O(pExampleClass1) to return the
      //      instance pExampleClass1, do the following
      return this.O(pExampleClass1).THIS;
   },
   "private var privateVar": "privateVar"
});
crx_registerClass("ExampleClass2",
{
   "VERBOSE": 1,
   "extends": "ExampleClass1",
   "public var publicVar": "I am ExampleClass2's publicVar",
   "public function test": function()
   {
      this.publicFunction(this);
      crx_static('ExampleClass1').publicStaticFunction(this);
   }
});
crx_registerClass("FriendOfExampleClass1",
{
   "VERBOSE": 1,
   "public function publicFunction": function(pExampleClass1)
   {
      //   The following is the same as done inside
      //      ExampleClass1::publicFunction(). Notice how
      //      'O' is giving access to the friend class
      //      FriendOfExampleClass1. Also notice how in this
      //      case 'O' requires two paramters. Passing only
      //      the object will not work.
      console.log(this.O(pExampleClass1, 'ExampleClass1').privateVar);
      console.log(this.O(pExampleClass1, 'ExampleClass1').publicVar);
      console.log(pExampleClass1.publicVar);
      console.log(pExampleClass1.CAST("ExampleClass1").publicVar);
      return this.O(pExampleClass1, 'ExampleClass1').THIS;
   }
});

var instance = crx_new("ExampleClass2");
var instance2 = crx_new("FriendOfExampleClass1");

instance.test();
console.log('--------------------');
instance2.publicFunction(instance.CAST('ExampleClass2'));
privateVar
I am ExampleClass1's publicVar
I am ExampleClass2's publicVar
I am ExampleClass1's publicVar
privateVar
I am ExampleClass1's publicVar
I am ExampleClass2's publicVar
I am ExampleClass1's publicVar
--------------------
privateVar
I am ExampleClass1's publicVar
I am ExampleClass2's publicVar
I am ExampleClass1's publicVar