added support and docs for extending of native objects....

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-05-02 19:55:05 +03:00
parent 935f0e01fa
commit f2e063ca21
3 changed files with 85 additions and 12 deletions

View File

@ -36,8 +36,8 @@ $ npm install ig-object
Or just download and drop [object.js](object.js) into your code. 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 Include the code, this is compatible with both [node's](https://nodejs.org/) and
[RequireJS'](https://requirejs.org/) `require(..)` [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)) var C = object.Constructor('C', Object.create(B.prototype))
``` ```
Now we can test this...
```javascript ```javascript
var c = C() // or new C() var c = C() // or new C()
@ -192,6 +193,46 @@ handling.
as restrict the use-cases for the constructor. 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 ## Components
Get sources for attribute Get sources for attribute
@ -267,6 +308,7 @@ A shorthand to this is `Constructor.__rawinstance__(context, ..)`.
Define an object constructor Define an object constructor
``` ```
Constructor(<name>)
Constructor(<name>, <prototype>) Constructor(<name>, <prototype>)
Constructor(<name>, <class-prototype>, <prototype>) Constructor(<name>, <class-prototype>, <prototype>)
-> <constructor> -> <constructor>

View File

@ -286,6 +286,26 @@ function(root, ...objects){
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// Constructor... // 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... // Make an uninitialized instance object...
// //
// makeRawInstance(context, constructor, ...) // makeRawInstance(context, constructor, ...)
@ -343,6 +363,9 @@ function(context, constructor, ...args){
// prototype defines .__new__(..)... // prototype defines .__new__(..)...
constructor.prototype.__new__ instanceof Function ? constructor.prototype.__new__ instanceof Function ?
constructor.prototype.__new__(context, ...args) constructor.prototype.__new__(context, ...args)
// native constructor...
: /\[native code\]/.test(constructor.toString()) ?
Reflect.construct(constructor, args)
// callable instance -- prototype is a function... // callable instance -- prototype is a function...
// NOTE: we need to isolate the .prototype from instances... // NOTE: we need to isolate the .prototype from instances...
: constructor.prototype instanceof Function ? : constructor.prototype instanceof Function ?
@ -359,15 +382,22 @@ function(context, constructor, ...args){
return constructor.prototype.__call__ return constructor.prototype.__call__
.call(obj, this, ...arguments) }, .call(obj, this, ...arguments) },
constructor.prototype.__call__) 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... // default object base...
: {} : Reflect.construct(Object, [], constructor)
// link to prototype chain... // link to prototype chain, if not done already...
obj.__proto__ = constructor.prototype if(obj.__proto__ !== constructor.prototype){
Object.defineProperty(obj, 'constructor', { obj.__proto__ = constructor.prototype
value: constructor, Object.defineProperty(obj, 'constructor', {
enumerable: false, value: constructor,
}) enumerable: false,
}) }
return obj } return obj }
@ -504,8 +534,8 @@ module.Constructor =
module.C = module.C =
function Constructor(name, a, b){ function Constructor(name, a, b){
var proto = b == null ? a : b var proto = b == null ? a : b
var cls_proto = b == null ? b : a
proto = proto || {} proto = proto || {}
var cls_proto = b == null ? b : a
// the actual constructor... // the actual constructor...
var _constructor = function Constructor(){ var _constructor = function Constructor(){
@ -529,7 +559,9 @@ function Constructor(name, a, b){
.replace(/Constructor/g, name)) .replace(/Constructor/g, name))
// set .toString(..)... // set .toString(..)...
// NOTE: do this only if .toString(..) is not defined by user... // 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', { && Object.defineProperty(_constructor, 'toString', {
value: function(){ value: function(){
var args = proto.__init__ ? var args = proto.__init__ ?
@ -553,7 +585,6 @@ function Constructor(name, a, b){
|| (_constructor.__rawinstance__ = || (_constructor.__rawinstance__ =
function(context, ...args){ function(context, ...args){
return makeRawInstance(context, this, ...args) }) return makeRawInstance(context, this, ...args) })
// set .prototype.constructor // set .prototype.constructor
Object.defineProperty(_constructor.prototype, 'constructor', { Object.defineProperty(_constructor.prototype, 'constructor', {
value: _constructor, value: _constructor,

View File

@ -1,6 +1,6 @@
{ {
"name": "ig-object", "name": "ig-object",
"version": "2.6.0", "version": "2.7.0",
"description": "", "description": "",
"main": "object.js", "main": "object.js",
"scripts": { "scripts": {