miércoles, 2 de octubre de 2013

Jtype, dando tipos a javascript

Tal vez se acuerdan de TypeScript, era un framework javascript para dar tipos a Javascript,  este framework esta impulsado por microsoft. Jtype tiene la misma idea, llevar javascript al mundo de las clases, con herencia y todo lo que ya conocemos.

Basta de chacharas y veamos un ejemplo:
// get the precompiled person class
var cachedPerson = localStorage.getItem('Person');

// compile the person class
var Person = $$(cachedPerson ? cachedPerson : '', function($fName, $lName, $age)
    // set the readonly fields (cast the string arguments)
    this.firstName = $$.asString($fName);
    this.lastName  = $$.asString($lName);

    // set the protected field (cast the number arguments)
    this._age = $$.asInt($age);
    'public readonly firstName': '',
    'public readonly lastName': '',

    'protected _age': 0,

    'public getFullName': function()
        // return the concatenated full name
        return this.firstName + ' ' + this.lastName;

    'public virtual triggerOneYearOlder': function()
        // increment the protected field

    'public age':
        'get': function()
            // return the protected field
            return this._age;
        'set': function($v)
            // if the incoming property value is valid, set the protected field
            if ($v > 0)
                this._age = $v;

// if the person class was not cached, store a local copy of the precompiled export string
if (!cachedPerson)
    localStorage.setItem('Person', $$.export(Person));

// get the precompiled employee class
var cachedEmployee = cachedPerson && localStorage.getItem('Employee');

// compile the employee class
var Employee = $$(cachedEmployee ? cachedEmployee : '', Person, function($fName, $lName, $age, $salary)
    // call the base constructor
    this.__base($fName, $lName, $age);

    // set the protected salary field
    this._salary = $salary;
    'protected _salary': 0,

    'public override triggerOneYearOlder': function()
        // increment the protected age field (by calling the base method)

        // increase the salary by three percent
        this._salary *= 1.03;

    'public salary':
        'get': function()
            // return the salary
            return this._salary;

// if the employee class was not cached, store a local copy of the precompiled export string
if (!cachedEmployee)
    localStorage.setItem('Employee', $$.export(Employee));

// instantiate a person object
var p = new Person('John', 'Doe', 30);

// check that the values were set
console.log(p.firstName);// John
console.log(p.lastName);// Doe
console.log(p.age);// 30

// get a protected field
console.log(p._age);// undefined

// set a readonly field (throws an exception in debug mode)
//p.firstName = 'Jane'; (uncomment to try it out)

// set an invalid property value
p.age = -40;

// check that the field and property didn't change
console.log(p.firstName);// John
console.log(p.age);// 30

// set a valid property value
p.age = 40;

// check that the property did change
console.log(p.age);// 40

// invoke a method
console.log(p.getFullName());// John Doe

// invoke a virtual method

// check that the age was incremented (by the virtual method)
console.log(p.age);// 41

// instantiate an employee object
var e = new Employee(p.firstName, p.lastName, p.age, 75000);

// check that the inherited values were set
console.log(e.firstName);// John
console.log(e.lastName);// Doe
console.log(e.age);// 41

// get an inherited protected field
console.log(e._age);// undefined

// set an inherited readonly field (throws an exception in debug mode)
//e.firstName = 'Jane'; (uncomment to try it out)

// check that the field didn't change
console.log(e.firstName);// John

// get a declared field (not inherited)
console.log(e.salary);// 75000

// cast the employee object as a person object
e = e.as(Person);

// check the types of both person objects
console.log(p instanceof Person);// true
console.log(p instanceof Employee);// false
console.log(e instanceof Person);// true
console.log(e instanceof Employee);// true

// check that both person objects don't have the derived property
console.log(p.salary);// undefined
console.log(e.salary);// undefined

// invoke an overridden method

// cast the person object as an employee object
e = e.as(Employee);

// check that the age was incremented (by the base method)
console.log(e.age);// 42

// check that the salary increased 3% (by the overridden method)
console.log(e.salary);// 77250

Dejo link