diff --git a/README.md b/README.md index 7e609bf..fd28fd6 100755 --- a/README.md +++ b/README.md @@ -36,8 +36,8 @@ $ npm install ig-object Or just download and drop [object.js](object.js) into your code. -## Basic usage +## Basic usage Include the code, this is compatible with both [node's](https://nodejs.org/) and [RequireJS'](https://requirejs.org/) `require(..)` @@ -64,6 +64,7 @@ var B = object.Constructor('B', {__proto__: A.prototype}) var C = object.Constructor('C', Object.create(B.prototype)) ``` +Now we can test this... ```javascript var c = C() // or new C() @@ -192,6 +193,46 @@ handling. as restrict the use-cases for the constructor. + +## Advanced cases + + +### Inheriting from native objects + +```javascript +var myArray = object.Constructor('myArray', Array, { + __proto__: Array.prototype, + + // ... +}) +``` + +All special methods and protocols except for `.__new__(..)` will work here +without change. + + +### Extending native `.constructor(..)` + +Extending `.constructor(..)` is not necessary in most cases as +`.__init__(..)` will do everything generally needed, except for instance +replacement. + +```javascript +var myArray = object.Constructor('myArray', Array, { + __proto__: Array.prototype, + + __new__: function(context, ...args){ + var obj = Reflect.construct(myArray.__proto__, args, myArray) + + // ... + + return obj + }, +}) +``` + + + ## Components Get sources for attribute @@ -267,6 +308,7 @@ A shorthand to this is `Constructor.__rawinstance__(context, ..)`. Define an object constructor ``` +Constructor() Constructor(, ) Constructor(, , ) -> diff --git a/object.js b/object.js index f73b2d5..d01e812 100755 --- a/object.js +++ b/object.js @@ -286,6 +286,26 @@ function(root, ...objects){ //--------------------------------------------------------------------- // Constructor... +// Make an object extending target... +// +// extend(target) +// -> object +// +// extend(target, object) +// -> object +// +// +// NOTE: this will modify the input object. +// +// XXX EXPERIMENTAL... +var extend = +module.extend = +function(target, obj){ + obj = obj || {} + obj.__proto__ = target.prototype + return obj } + + // Make an uninitialized instance object... // // makeRawInstance(context, constructor, ...) @@ -343,6 +363,9 @@ function(context, constructor, ...args){ // prototype defines .__new__(..)... constructor.prototype.__new__ instanceof Function ? constructor.prototype.__new__(context, ...args) + // native constructor... + : /\[native code\]/.test(constructor.toString()) ? + Reflect.construct(constructor, args) // callable instance -- prototype is a function... // NOTE: we need to isolate the .prototype from instances... : constructor.prototype instanceof Function ? @@ -359,15 +382,22 @@ function(context, constructor, ...args){ return constructor.prototype.__call__ .call(obj, this, ...arguments) }, constructor.prototype.__call__) + // use parent's constructor... + // XXX EXPERIMENTAL... + // XXX do a better test... + : (constructor.__proto__ instanceof Function + && constructor.__proto__ !== (function(){}).__proto__) ? + Reflect.construct(constructor.__proto__, [], constructor) // default object base... - : {} + : Reflect.construct(Object, [], constructor) - // link to prototype chain... - obj.__proto__ = constructor.prototype - Object.defineProperty(obj, 'constructor', { - value: constructor, - enumerable: false, - }) + // link to prototype chain, if not done already... + if(obj.__proto__ !== constructor.prototype){ + obj.__proto__ = constructor.prototype + Object.defineProperty(obj, 'constructor', { + value: constructor, + enumerable: false, + }) } return obj } @@ -504,8 +534,8 @@ module.Constructor = module.C = function Constructor(name, a, b){ var proto = b == null ? a : b - var cls_proto = b == null ? b : a proto = proto || {} + var cls_proto = b == null ? b : a // the actual constructor... var _constructor = function Constructor(){ @@ -529,7 +559,9 @@ function Constructor(name, a, b){ .replace(/Constructor/g, name)) // set .toString(..)... // NOTE: do this only if .toString(..) is not defined by user... - ;((cls_proto || {}).toString() == ({}).toString()) + // XXX revise this... + ;((cls_proto || {}).toString === Function.toString + || (cls_proto || {}).toString === ({}).toString) && Object.defineProperty(_constructor, 'toString', { value: function(){ var args = proto.__init__ ? @@ -553,7 +585,6 @@ function Constructor(name, a, b){ || (_constructor.__rawinstance__ = function(context, ...args){ return makeRawInstance(context, this, ...args) }) - // set .prototype.constructor Object.defineProperty(_constructor.prototype, 'constructor', { value: _constructor, diff --git a/package.json b/package.json index 20b96ed..c999356 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ig-object", - "version": "2.6.0", + "version": "2.7.0", "description": "", "main": "object.js", "scripts": {