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

Commit

Permalink
Merge pull request #4 from quadroid/v1.0.0-alpha
Browse files Browse the repository at this point in the history
Merge branch v1.0.0-alpha (by github)
  • Loading branch information
Alex Shvets committed Jul 8, 2013
2 parents d3e876b + bb22158 commit 2f5eb36
Show file tree
Hide file tree
Showing 67 changed files with 584 additions and 8,909 deletions.
3 changes: 0 additions & 3 deletions .gitmodules
@@ -1,6 +1,3 @@
[submodule "lib/es5-shim"]
path = lib/es5-shim
url = git://github.com/kriskowal/es5-shim.git
[submodule "build/html"]
path = build/html
url = git://github.com/quadroid/clonejs.git
Expand Down
2 changes: 1 addition & 1 deletion .version
@@ -1 +1 @@
v0.7.4-beta
v1.0.0-alpha
14 changes: 7 additions & 7 deletions CHANGELOG.md
@@ -1,4 +1,4 @@
### Build v0.7.4-beta (2013-04-14 09:06)
##### Build v0.7.4 (2013-04-14 09:06)
* add ability to inject into Object.prototype, update module interface
* change namespace interface
* add RequireJS support
Expand All @@ -7,21 +7,21 @@
* improve documentation
* refactor tests

### Build v0.7.3-beta (2013-04-12 06:00)
##### Build v0.7.3 (2013-04-12 06:00)
* improve documentation
* fix bug: first call applySuper() on sealed object
* optimize `for`
* deploy scripts: add comments

### Build v0.7.2-05-beta (2013-04-06 15:35)
###### Build v0.7.2-05 (2013-04-06 15:35)
* reverse changelog items order
* deploy scripts: fix new line in build message
* fix cdn src

### Build v0.7.2-04-beta (2013-04-06 14:35)
###### Build v0.7.2-04 (2013-04-06 14:35)
* update documentation

### Build v0.7.2-03-beta (2013-04-01 12:06)
###### Build v0.7.2-03 (2013-04-01 12:06)
* fix bug in getKeys(), forEach()
* add getValues() test
* add getSuper()
Expand All @@ -31,11 +31,11 @@
* update describe() test
* fix applySuper() bug

### Build v0.7.2-02-beta (2013-03-30 22:06)
###### Build v0.7.2-02 (2013-03-30 22:06)
* fix home page nav
* incrase CI speed

### Build 0.7.2.01 (2013-03-30 15:32)
###### Build v0.7.2-01 (2013-03-30 15:32)
* fix deploy scripts
* jsdoc template: update DL's formatting
* edit readme
Expand Down
252 changes: 71 additions & 181 deletions README.md
@@ -1,20 +1,42 @@
## [clone.js](http://clonejs.org) [![Build Status](https://travis-ci.org/quadroid/clonejs.png?branch=master "travis-ci.org")](https://travis-ci.org/quadroid/clonejs)
<!-- HIDDEN: -->
[API documentation](http://clonejs.org/symbols/%24object.html)
## CloneJS [![Build Status](https://travis-ci.org/quadroid/clonejs.png?branch=master "travis-ci.org")](https://travis-ci.org/quadroid/clonejs) [![NPM version](https://badge.fury.io/js/clonejs.png)](http://badge.fury.io/js/clonejs)
[**CloneJS.org**](http://clonejs.org)
| [API documentation](http://clonejs.org/symbols/clone.html)
| [ChangeLog](https://github.com/quadroid/clonejs/blob/master/CHANGELOG.md)
| [GitHub](http://github.com/quadroid/clonejs)
*| [GitHub](http://github.com/quadroid/clonejs)
| [NPM package](http://npmjs.org/package/clonejs)
| [Travis CI](http://travis-ci.org/quadroid/clonejs)
| [Travis CI](http://travis-ci.org/quadroid/clonejs)*
<!-- /HIDDEN -->

**This framework provides:**

This is the micro-framework that based on the ECMA Script 5 features like [Object.create⠙][] and [property descriptors⠙][Object.defineProperty⠙].
* Speed! It's extrimerly fast!
* Class-less, the pure prototype-oriented paradigm.
* Separate all your objects and classes to state (data) and behavior (methods).
* [Lazy initialization⠙][] support (by `__inits__` behavior).
* IE6+ support! Shims `Object.create` and `Object.getPrototypeOf` methods.

##### Try the true [prototype-based OOP⠙](http://en.wikipedia.org/wiki/Prototype-based_programming)
[Lazy initialization⠙]: http://en.wikipedia.org/wiki/Lazy_initialization

**It's trivial to create new "classes"** - just clone the prototype and change a couple of properties and voila... new "class".
The main code of the framework:

**It's really class-free**: do you know the difference between js constructor-functions and classes in other languages?
`$object.clone` produces prototype objects, not function-constructors, unlike other class-producing tools (`Backbone.Model.extend`, `Ext.define`, `dojo.declare`).
function clone(/** Object! */obj, /** object! */state, /** object= */behavior$){
if( behavior$ ){
behavior$.__proto__ = obj;
state.__proto__ = behavior$;
}else{
state.__proto__ = obj;
}
return state;
}

Thats it!

#### Try the true [prototype-based OOP⠙](http://en.wikipedia.org/wiki/Prototype-based_programming)

**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 prototype objects, not function-constructors, unlike other class-producing tools (`Ext.define`, `dojo.declare`).

In 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.
Expand All @@ -31,207 +53,75 @@ Node.js:

npm install clonejs

[CDN⠙][] for client-side (~3 KB gzipped):
[CDN⠙][] for client-side:

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

### Usage

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

var duck$ = {
quack: function(){
console.log( this.name +' Duck: Quack-quack!');
console.log( this.name +" Duck: Quack-quack!");
}
});
$duck.quack();//Unnamed Duck: Quack-quack!
/// Inheritance is simple:
var $talkingDuck = $duck.clone({
};

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

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

/// Forget about the `new` operator, use .create() method instead:
var donald = $talkingDuck.create({name: 'Donald'});
donald.quack();// Donald Duck: Quack-quack! My name is Donald!
/// Forget about the `new` operator, use clone 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



###### Cloning objects:

var $proto = $object.clone({a:1, b:2, c:3});

/// clone:
var clone = $proto.clone();
clone.a = 11; // $proto.a not changed
$proto.b = 22; // clone.b will be also changed to 22
/// copy:
var copy = $proto.copy();
copy.a = 111;// $proto.a not changed
$proto.b = 222;// copy.b not changed

/// create:
var instance = $proto.create({d: 4444});
instance.a = 1111;// $proto.a not changed
$proto.b = 2222;// like clone, instance.b will be also changed to 2222
assert( instance.a === 1111 );
assert( instance.d === 4444 );
See: [clone][], [copy][], [create][], [deepCopy][], [deepClone][].

###### Property modificators:

var $myType = $object.clone({
'(final) property1': "not configurable and not writable",
'(writable final) property2': "not configurable only",
'(hidden) property3': "not enumerable",
'(const) constant': "not writable",
property4 : "simple property",
'(get) property3alias': 'property3',// automatically create getter
_item : "private property (not enumerable)",
'(get) item': function() { return this._item },
'(set) item': function(v){ this._item = v },
constructor : 'MyType'
});
assert( $myType.property3alias === $myType.property3 );

See: [describe][].

###### Inheritance & constructors:
var $parent = $object.clone({
constructor: function Parent(){
this.applySuper();
console.log('$parent constructor arguments:', arguments);
}
});
var $child = $parent.clone({
constructor: function Child(arg1, arg2){
this.callSuper('constructor', arg1, arg2);
console.log('$child constructor arguments:', arguments);
}
});
var $grandchild = $child.clone({
constructor: function Grandchild(){
this.applySuper(arguments);
console.log('$grandchild constructor arguments:', arguments);
}
});
var myBoy = $grandchild.create(1,2,3);
/// console log:
// $parent constructor arguments: [1,2]
// $child constructor arguments: [1,2,3]
// $grandchild constructor arguments: [1,2,3]
assert( $child.isPrototypeOf(myBoy) );
duck$.isPrototypeOf(donald);// true

See: [constructor][], [create][], [applySuper][], [callSuper][], [createSuperSafeCallback][].

###### Properties iteration:

var $obj = $object.clone({a: 11, b: 22, c: 33}),
obj = $obj.create({d: 44});

/// Map only own properties (default):
var mappedObj1 = obj.map(function(value){return 100 + value});
// mappedObj1 == {d: 144}

/// Map all properties, replace default (`$object`) prototype of returned object:
var proto = {e: 55};
var mappedObj2 = obj.map(function(value){return 100 + value}, obj, false, proto);
// mappedObj2 == {a: 111, b: 122, c: 133, d: 144, e: 155}
proto.f = 66;
// mappedObj2 == {a: 111, b: 122, c: 133, d: 144, e: 155, f: 66}

See: [forEach][], [map][], [filter][], [every][], [some][].

###### Namespaces:
var app = clonejs.$namespace.create();

/// create namespace item `app.collections`
app.extend('collections', {
$item: {},
_items: {}
});
###### Lazy initialization:

/// create namespace item `app.collections.arrayCollections`
Instead of defining in constructor, you can initialize your properties separetly.
Lazy initialization is the tactic, that will initialize property in first use of them.

app.collections.extend('arrayCollections', {_items: []});

/// create namespace item `app.models.users`

var $users = app.collections.$arrayCollections.clone({
$item: {name: '', isAdmin: false},
constructor: function Users(items){
items.forEach(function(item){
var newItem = $object.create.call(this.$item, item);
this._items.push(newItem);
}, this);
var obj = clone.create({
name: "Default Name"
},{
__inits__: {
lazy: function(){
console.log("Lazy initialization...");
return this.name +": Lazy initiated.":
}
}
});
app.put('models.users', $users);
/// use namespace:

var users = app.models.$users.create([{name: 'User1'}]);

See: [$namespace][], [$namespace.extend][], [$namespace.put][].


console.log( obj.lazy );
// Lazy initialization...
// Default Name: Lazy initiated.

console.log( obj.lazy );// initializer don't run again
// Default Name: Lazy initiated.

[Object.create⠙]: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create
[Object.defineProperty⠙]: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty
[property descriptors⠙]: http://ejohn.org/blog/ecmascript-5-objects-and-properties/#ig-sh-1

[CDN⠙]: http://code.lancepollard.com/github-as-a-cdn/

[$object]: http://clonejs.org/symbols/%24object.html

[clone]: http://clonejs.org/symbols/%24object.html#clone
[create]: http://clonejs.org/symbols/%24object.html#create
[copy]: http://clonejs.org/symbols/%24object.html#copy
[deepCopy]: http://clonejs.org/symbols/%24object.html#deepCopy
[deepClone]: http://clonejs.org/symbols/%24object.html#deepClone

[describe]: http://clonejs.org/symbols/%24object.html#.describe

[forEach]: http://clonejs.org/symbols/%24object.html#forEach
[every]: http://clonejs.org/symbols/%24object.html#every
[some]: http://clonejs.org/symbols/%24object.html#some
[map]: http://clonejs.org/symbols/%24object.html#map
[filter]: http://clonejs.org/symbols/%24object.html#filter

[constructor]: http://clonejs.org/symbols/%24object.html#constructor
[applySuper]: http://clonejs.org/symbols/%24object.html#applySuper
[callSuper]: http://clonejs.org/symbols/%24object.html#callSuper
[createSuperSafeCallback]: http://clonejs.org/symbols/%24object.html#createSuperSafeCallback

[$namespace]: http://clonejs.org/symbols/$namespace.html
[$namespace.extend]: http://clonejs.org/symbols/$namespace.html#extend
[$namespace.put]: http://clonejs.org/symbols/$namespace.html#put

<!-- HIDDEN: -->
![yandex metrika](http://mc.yandex.ru/watch/20738752)
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/3110be9614da5cb337ebd483c187010f "githalytics.com")](http://githalytics.com/quadroid/clonejs)
Expand Down

0 comments on commit 2f5eb36

Please sign in to comment.