base-class-extend
Advanced tools
Comparing version 0.0.2 to 0.0.3
@@ -7,28 +7,39 @@ // base-class.js | ||
// setConst(obj, prop, val) | ||
var setConst = typeof Object.defineProperty === 'function' ? | ||
var setConst = Object.defineProperty ? | ||
function setConst(obj, prop, val) { | ||
Object.defineProperty(obj, prop, {value: val}); | ||
} : | ||
function setConst(obj, prop, val) { | ||
obj[prop] = val; | ||
}; | ||
Object.defineProperty(obj, prop, {value: val}); } : | ||
function setConst(obj, prop, val) { obj[prop] = val; }; | ||
// setValue(obj, prop, val) | ||
var setValue = typeof Object.defineProperty === 'function' ? | ||
var setValue = Object.defineProperty ? | ||
function setValue(obj, prop, val) { | ||
Object.defineProperty(obj, prop, {value: val, | ||
writable: true, configurable: true}); | ||
} : | ||
function setValue(obj, prop, val) { | ||
obj[prop] = val; | ||
}; | ||
writable: true, configurable: true}); } : | ||
function setValue(obj, prop, val) { obj[prop] = val; }; | ||
// setProto(obj, proto) | ||
var setProto = typeof Object.setPrototypeOf === 'function' ? | ||
Object.setPrototypeOf : | ||
function setProto(obj, proto) { | ||
obj.__proto__ = proto; | ||
}; | ||
var setProto = Object.setPrototypeOf ? Object.setPrototypeOf : | ||
function setProto(obj, proto) { obj.__proto__ = proto; }; | ||
// extend | ||
// getProto(obj) | ||
var getProto = Object.getPrototypeOf ? Object.getPrototypeOf : | ||
function getProto(obj) { return obj.__proto__; }; | ||
// fnameRegExp: function name regular expression | ||
var fnameRegExp = /^\s*function\s*\**\s*([^\(\s]*)[\S\s]+$/im; | ||
// fname: get function name | ||
function fname() { | ||
return ('' + this).replace(fnameRegExp, '$1'); | ||
} | ||
// Function.prototype.name | ||
if (!Function.prototype.hasOwnProperty('name')) { | ||
if (Object.defineProperty) | ||
Object.defineProperty(Function.prototype, 'name', {get: fname}); | ||
else if (Object.prototype.__defineGetter__) | ||
Function.prototype.__defineGetter__('name', fname); | ||
} | ||
// BaseClass.extend | ||
// Usage: | ||
@@ -39,3 +50,3 @@ // var SimpleClass = | ||
// {classMethod: function () {}}); | ||
function extend(name, proto, classProps) { | ||
function BaseClass_extend(name, proto, classProps) { | ||
if (typeof name !== 'string') { | ||
@@ -55,18 +66,29 @@ classProps = proto; | ||
proto.hasOwnProperty('constructor') && proto.constructor || | ||
Function('proto, superCtor, new_', | ||
Function('proto, superCtor, BaseClass_new', | ||
'return function ' + name + '() {\n' + | ||
' if (!(this instanceof proto.constructor)) \n' + | ||
' return new_.apply(proto.constructor, arguments); \n' + | ||
' return superCtor.apply(this, arguments), this; }') | ||
(proto, superCtor, new_); | ||
' "use strict";' + | ||
' if (!(this instanceof proto.constructor) ||\n' + | ||
' this instanceof Array && !this.hasOwnProperty("length") ||\n' + | ||
' this instanceof Error && !this.hasOwnProperty("message"))\n' + | ||
' return BaseClass_new.apply(proto.constructor, arguments);\n' + | ||
' if (superCtor !== Object && superCtor !== Array && superCtor !== Error)\n' + | ||
' superCtor.apply(this, arguments);\n' + | ||
' return this; }') | ||
(proto, superCtor, BaseClass_new); | ||
if (typeof ctor !== 'function') | ||
throw new TypeError('constructor must be a function'); | ||
if (!ctor.name && name !== '$NoName$') { | ||
ctor = Function('proto, ctor, new_', | ||
ctor.prototype = proto; | ||
ctor = Function('proto, ctor, BaseClass_new', | ||
'return function ' + name + '() {\n' + | ||
' if (!(this instanceof proto.constructor)) \n' + | ||
' return new_.apply(proto.constructor, arguments); \n' + | ||
' "use strict";' + | ||
' if (!(this instanceof proto.constructor) ||\n' + | ||
' this instanceof Array && !this.hasOwnProperty("length") ||\n' + | ||
' this instanceof Error && !this.hasOwnProperty("message"))\n' + | ||
' return BaseClass_new.apply(proto.constructor, arguments);\n' + | ||
' return ctor.apply(this, arguments), this; }') | ||
(proto, ctor, new_); | ||
(proto, ctor, BaseClass_new); | ||
} | ||
ctor.prototype = proto; | ||
delete proto.constructor; | ||
@@ -76,3 +98,2 @@ delete proto.new; | ||
setValue(proto, 'new', ctor); | ||
ctor.prototype = proto; | ||
@@ -82,13 +103,11 @@ // inherits | ||
// inherits class methods | ||
// constructor.__proto__ -> for inherits class methods | ||
if (classProps == null || typeof classProps !== 'object') { | ||
// constructor.__proto__ -> for inherits class methods | ||
setProto(ctor, superCtor); | ||
} | ||
else { | ||
// constructor.__proto__ -> for inherits class methods | ||
setProto(ctor, classProps); | ||
setProto(classProps, superCtor); | ||
// class initializer | ||
// class initializer: initialize | ||
var init = classProps.hasOwnProperty('initialize') && classProps.initialize; | ||
@@ -98,3 +117,3 @@ delete classProps.initialize; | ||
// class initializer | ||
// class initializer: init | ||
var init = classProps.hasOwnProperty('init') && classProps.init; | ||
@@ -117,4 +136,4 @@ delete classProps.init; | ||
if (!('extend' in ctor)) ctor.extend = extend; | ||
if (!('new' in ctor)) ctor.new = new_; | ||
if (!('extend' in ctor)) ctor.extend = BaseClass_extend; | ||
if (!('new' in ctor)) ctor.new = BaseClass_new; | ||
@@ -127,11 +146,40 @@ // constructor.super_ -> for points super class | ||
function new_() { | ||
var obj = Object.create(this.prototype); | ||
// BaseClass.new | ||
function BaseClass_new() { | ||
//assert(this === this.prototype.constructor, | ||
// 'prototype of class/constructor is not class/constructor'); | ||
if (this.prototype instanceof Array) { | ||
var obj = Array.apply(null, arguments); // [] or new Array | ||
setProto(obj, this.prototype); | ||
} | ||
else if (this.prototype instanceof Error) { | ||
var obj = Error.apply(null, arguments); // new Error | ||
if (!obj.hasOwnProperty('message') && | ||
typeof arguments[0] === 'string') | ||
obj.message = arguments[0]; | ||
if (typeof obj.stack === 'string') | ||
obj.stack = obj.stack.split('\n').filter(function (str) { | ||
return !/((base-class.js)|(BaseClass_new))/.test(str); | ||
}).join('\n'); | ||
setProto(obj, this.prototype); | ||
} | ||
else | ||
var obj = Object.create(this.prototype); | ||
//assert(obj.constructor === this, 'new object is not instance of class (constructor)'); | ||
return this.apply(obj, arguments), obj; | ||
//var res = this.apply(obj, arguments) || obj; | ||
//assert(res.constructor === this, 'constructor returns other class object'); | ||
//assert(res === obj, 'constructor returns other object'); | ||
//return obj; | ||
} | ||
var BaseClass = extend('BaseClass', {}, | ||
{extend: extend, new: new_}); | ||
function assert(bool, msg) { | ||
if (!bool) throw new Error(msg); | ||
} | ||
var BaseClass = BaseClass_extend('BaseClass', {}, | ||
{extend: BaseClass_extend, | ||
new: BaseClass_new}); | ||
// exports | ||
@@ -142,3 +190,3 @@ if (typeof module !== 'undefined') { | ||
else { | ||
var g = Function('return this'); | ||
var g = Function('return this')(); | ||
g.BaseClass = BaseClass; | ||
@@ -145,0 +193,0 @@ } |
{ | ||
"name": "base-class-extend", | ||
"version": "0.0.2", | ||
"description": "Base Class constructor for easy class definition - inherits, extend", | ||
"version": "0.0.3", | ||
"description": "Base Class constructor for easy class definition - supports getter/setter, inherit/extend Array Error or EventEmitter etc", | ||
"main": "lib/base-class.js", | ||
@@ -14,5 +14,9 @@ "scripts": { | ||
"keywords": [ | ||
"array", | ||
"base-class", | ||
"inherits", | ||
"extend" | ||
"error", | ||
"events", | ||
"EventEmitter", | ||
"extend", | ||
"inherits" | ||
], | ||
@@ -19,0 +23,0 @@ "author": "LightSpeedC", |
@@ -8,4 +8,8 @@ base-class-extend | ||
Easy to use, easy to inherits/extend. | ||
Supports getter/setter. | ||
Easy to use, easy to inherit/extend. | ||
Also supports inheritance from `Array`, `Error`, or Node.js `events.EventEmitter`. | ||
no difficult keywords, | ||
@@ -18,3 +22,3 @@ no `constructor`, no `prototype`, no `__proto__`, | ||
```bash | ||
npm install base-class-extend | ||
$ npm install base-class-extend | ||
``` | ||
@@ -38,9 +42,9 @@ | ||
+ BaseClass: Base class or Super class for inherits | ||
+ *BaseClass*: Base class or Super class for inherits | ||
+ name: string name of your class, optional | ||
+ *name*: string name of your class, optional | ||
+ prototype: the prototype object for your class, optional | ||
+ *prototype*: the prototype object for your class, optional | ||
+ classProps: class or static properties object, optional | ||
+ *classProps*: class or static properties object, optional | ||
@@ -68,3 +72,3 @@ ## Returns | ||
if (!(value >= 1 && value <= 10)) | ||
throw new Error(''); | ||
throw new Error('Out of range'); | ||
this._value = value; }, | ||
@@ -90,2 +94,6 @@ }); | ||
## Parameters | ||
+ *arguments*...: pass to constructor, optional | ||
## Returns | ||
@@ -101,7 +109,6 @@ | ||
Object.extend = BaseClass.extend; | ||
Object.new = BaseClass.new; | ||
var SimpleClass = Object.extend('SimpleClass', {}, {}); | ||
var SimpleClass = Object.extend('SimpleClass'); | ||
// or simply | ||
var SimpleClass = BaseClass.extend.call(Object, 'SimpleClass', {}, {}); | ||
var SimpleClass = BaseClass.extend.call(Object, 'SimpleClass'); | ||
``` | ||
@@ -114,17 +121,27 @@ | ||
EventEmitter.extend = BaseClass.extend; | ||
EventEmitter.new = BaseClass.new; | ||
var UsefulClass = EventEmitter.extend('UsefulClass', {}, {}); | ||
var UsefulClass = EventEmitter.extend('UsefulClass'); | ||
// or simply | ||
var UsefulClass = BaseClass.extend.call(EventEmitter, 'UsefulClass', {}, {}); | ||
var UsefulClass = BaseClass.extend.call(EventEmitter, 'UsefulClass'); | ||
``` | ||
## inherits from all other class or constructor ... Function | ||
```js | ||
Function.prototype.extend = BaseClass.extend; | ||
var SimpleClass = Object.extend('SimpleClass'); | ||
var CustomArray = Array.extend('CustomArray'); | ||
var EventEmitter = require('events').EventEmitter; | ||
var CustomEventEmitter = EventEmitter.extend('CustomEventEmitter'); | ||
``` | ||
# EXAMPLES: | ||
```js | ||
var BaseClass = require('base-class-extend'); | ||
// SimpleClass | ||
var SimpleClass = BaseClass.extend(); | ||
var SimpleClass = BaseClass.extend('SimpleClass'); | ||
var s1 = new SimpleClass(); | ||
@@ -137,2 +154,3 @@ | ||
return Animal.new.apply(Animal, arguments); | ||
BaseClass.apply(this); // or Animal.super_.apply(this); | ||
this.name = name; | ||
@@ -166,3 +184,3 @@ }, | ||
return Cat.new.apply(Cat, arguments); | ||
return Cat.super_.apply(this, arguments) || this; | ||
Cat.super_.apply(this, arguments); | ||
} | ||
@@ -177,3 +195,3 @@ }); | ||
return Dog.new.apply(Dog, arguments); | ||
return Dog.super_.apply(this, arguments) || this; | ||
Dog.super_.apply(this, arguments); | ||
}, | ||
@@ -180,0 +198,0 @@ }, { |
@@ -23,2 +23,3 @@ // base-class-animal-test.js | ||
return Animal.new.apply(Animal, arguments); | ||
BaseClass.apply(this); // or Animal.super_.apply(this); | ||
this.name = name; | ||
@@ -53,3 +54,3 @@ }, | ||
return Cat.new.apply(Cat, arguments); | ||
return Cat.super_.apply(this, arguments) || this; | ||
Cat.super_.apply(this, arguments); | ||
} | ||
@@ -64,3 +65,3 @@ }); | ||
return Dog.new.apply(Dog, arguments); | ||
return Dog.super_.apply(this, arguments) || this; | ||
Dog.super_.apply(this, arguments); | ||
}, | ||
@@ -67,0 +68,0 @@ }, { |
@@ -35,3 +35,2 @@ // base-class-object-test.js | ||
Object.extend = BaseClass.extend; | ||
Object.new = BaseClass.new; | ||
@@ -45,8 +44,8 @@ // SimpleClass2 | ||
checkConstructorName('BaseClass', b1, b2, b3); | ||
checkConstructorName('SimpleClass0', s01, s02, s03); | ||
checkConstructorName('SimpleClass1', s11, s12, s13); | ||
checkConstructorName('SimpleClass2', s21, s22, s23); | ||
checkConstructor(BaseClass, b1, b2, b3); | ||
checkConstructor(SimpleClass0, s01, s02, s03); | ||
checkConstructor(SimpleClass1, s11, s12, s13); | ||
checkConstructor(SimpleClass2, s21, s22, s23); | ||
function checkConstructorName(ctorName) { | ||
function checkConstructor(ctor) { | ||
var objs = Array.prototype.slice.call(arguments, 1); | ||
@@ -57,5 +56,5 @@ | ||
if (obj == null) return; | ||
if (obj.constructor.name !== ctorName) | ||
throw new TypeError(obj.constructor.name + ' !== ' + ctorName); | ||
if (obj.constructor !== ctor) | ||
throw new TypeError(obj.constructor.name + ' !== ' + ctor.name); | ||
}); | ||
} |
@@ -18,2 +18,3 @@ // base-class-test-en.js | ||
return new Animal(name); | ||
BaseClass.apply(this); // or Animal.super_.apply(this); | ||
this.name = name; | ||
@@ -40,3 +41,3 @@ }, | ||
return new Bear(name); | ||
return Bear.super_.apply(this, arguments) || this; | ||
Bear.super_.apply(this, arguments); | ||
}}); | ||
@@ -73,3 +74,3 @@ | ||
return new Elephant(name); | ||
return Elephant.super_.apply(this, arguments) || this; | ||
Elephant.super_.apply(this, arguments); | ||
}}); | ||
@@ -76,0 +77,0 @@ |
@@ -15,2 +15,3 @@ // base-class-test-jp.js | ||
return new Animal(name); | ||
BaseClass.apply(this); // or Animal.super_.apply(this); | ||
this.name = name; | ||
@@ -37,3 +38,3 @@ }, | ||
return new Bear(name); | ||
return Bear.super_.apply(this, arguments) || this; | ||
Bear.super_.apply(this, arguments); | ||
}}); | ||
@@ -70,3 +71,3 @@ | ||
return new Elephant(name); | ||
return Elephant.super_.apply(this, arguments) || this; | ||
Elephant.super_.apply(this, arguments); | ||
}}); | ||
@@ -73,0 +74,0 @@ |
32634
13
589
257