Skip to content
This repository has been archived by the owner on Dec 28, 2017. It is now read-only.
/ clonejs Public archive

🕸 UNMAINTAINED since 2013 — JS object creation pattern

Notifications You must be signed in to change notification settings

oleksandr-shvets/clonejs

Repository files navigation

cloneJS Build Status NPM version

CloneJS.org | Nano | API documentation | ChangeLog | GitHub | NPM package | Travis CI

This framework provides:

  • Speed! It's extremely fast! Faster than JS core! (class-objects creation).
  • Class-less, the pure prototype-based paradigm.
  • Lazy initialization⠙ support (by $inits behavior).
  • Separation of all your objects into the state (data) and behavior (methods),
    as in ECMA Script 6: classes does not have fields, only methods.
  • IE6 support! + Emulation of Object.getPrototypeOf (partial) and Object.create.

What is the Clone?

clone function produces new objects — Clones.
Clone object — this is the lazy shallow copy, i.e., it is actually not a copy, it's just a reference to the object, with one difference: if you will add/replace any of its properties, it would not affect the cloned object (prototype).
All JavaScript objects are clones of Object.prototype (except itself and objects, created by Object.create(null)).

Try the true prototype-based OOP

With this framework you can easilly create and manipulate objects without constructors, instead of classic js way, where you should define a constructor for every object (that you want to use as prototype), even if you didn't need it. It's possible to build and maintain extremely large numbers of "classes" with comparatively little code.

It's trivial to create new "classes" - just clone the object and change a couple of properties and voila... new "class".

It's really class-free: clone() produces objects (prototypes), not function-constructors, unlike all other class-producing tools (Ext.define, dojo.declare etc).

Read more:

Installation

Node.js:

npm install clonejs

CDN⠙ for client-side:

<script src="http://quadroid.github.io/clonejs/cdn/clone.min.js"></script>

Usage

var clone = require('clonejs');//</node.js>
    
/// Forget about classes.    
//  Instead of creating class (function), create prototype (object):

var duck$ = { // $ postfix means prototype: Duck.prototype === duck$
    quack: function(){
        console.log( this.name +" Duck: Quack-quack!");
    }
};

/// Inheritance is simple (talkingDuck prototype extends duck prototype):

var talkingDuck$ = clone.extend( duck$, {
    quack: function(){
        duck$.quack.call(this);
        console.log("My name is "+ this.name +"!");
    }
});

/// Forget about the `new` operator, use `clone` function to create instances:

var donald = clone( talkingDuck$, {name: "Donald"});
donald.quack();// Donald Duck: Quack-quack! 
               // My name is Donald!
var daffy  = clone( talkingDuck$, {name: "Daffy"});
daffy.quack(); // Daffy Duck: Quack-quack! 
               // My name is Daffy!

/// Forget about the `instanceof` operator, use JS native 
//  .isPrototypeOf() method instead:

duck$.isPrototypeOf(donald);// true
Object-oriented notation:
  var duck$ = clone.extend({
      quack: function(){
          console.log( this.name +" Duck: Quack-quack!");
      }
  });
    
  var talkingDuck$ = duck$.$extend({
      quack: function(){
          duck$.quack.call(this);
          console.log("My name is "+ this.name +"!");
      }
  });
        
  var donald = talkingDuck$.$clone({name: "Donald"});
  var daffy  = talkingDuck$.$clone({name: "Daffy"});

Lazy initialization

How to initialize object without constructor?
Lazy initialization is the tactic of delaying the calculation of a value until the first time it is needed.

var obj = clone.new({
    name: "object"
    },{
    $inits: {
        lazy: function(){
            console.log("Lazy initialization...");
            return this.name +" lazy initiated.":
        }
    }
});

console.log( "obj.lazy: " + obj.lazy );
// Lazy initialization...
// obj.lazy: object lazy initiated.

console.log( "obj.lazy: " + obj.lazy );// initializer does't run again
// obj.lazy: object lazy initiated.

This code will work on IE8-, but you need to remember:

Internet Explorer 8– obsticles

Your accessor function should not return null or undefined.
If accessor returns boolean, you need to compare it with true or false obviously:

if( obj.lazyBoolean == true   ) console.log(true);
// or
if( obj.lazyBoolean.valueOf() ) console.log(true);

If accessor returns object, you need to call valueOf() method:

console.log( obj.lazyObject.valueOf().name );

// for info, this will works without errors/warnings on all browsers:
console.log( ({name: "obj.property" }).valueOf().name );// obj.property
console.log( (function(){return "fn"}).valueOf()()    );// fn
console.log( (777).valueOf() );// 777
console.log( "str".valueOf() );// str
console.log( false.valueOf() );// false
// but this will throw error:
console.log( (undefined).valueOf() );
console.log(      (null).valueOf() );

You can call valueOf() method only on first access.
If accessor returns primitive value (string, number, boolean), you can use it as normal.
JavaScript automatically invokes valueOf() in places where a primitive value is expected.


For more details, see API documentation

yandex metrika githalytics.com alpha

About

🕸 UNMAINTAINED since 2013 — JS object creation pattern

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages