mirror of
https://github.com/flynx/object.js.git
synced 2025-10-29 10:30:08 +00:00
more refactoring and experimenting...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
1ef5cb8f25
commit
535aeab9b0
@ -198,6 +198,11 @@ mixinFlat(<root>, <object>, ...)
|
||||
This is like `Object.assign(..)` but copies property objects rather than
|
||||
property values.
|
||||
|
||||
Make a raw instance
|
||||
```
|
||||
makeRawInstance(<context>, <constructor>, ...)
|
||||
-> <object>
|
||||
```
|
||||
|
||||
Define an object constructor
|
||||
```
|
||||
|
||||
145
object.js
145
object.js
@ -156,8 +156,72 @@ function(root, ...objects){
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Make a JavaScrip object constructor...
|
||||
// Make/get the base instance object...
|
||||
//
|
||||
// makeRawInstance(context, constructor, ...args)
|
||||
// -> instance
|
||||
//
|
||||
//
|
||||
// This will:
|
||||
// - construct an object
|
||||
// - if .__new__(..) is defined
|
||||
// -> call and use its return value
|
||||
// - if prototype is a function or if .__call__(..) is defined
|
||||
// -> use a wrapper function
|
||||
// - else
|
||||
// -> use {}
|
||||
// - link the object into the prototype chain
|
||||
//
|
||||
//
|
||||
// This will not call .__init__(..)
|
||||
//
|
||||
// XXX Q: should this be a class method or a utility???
|
||||
// XXX Q: should .__new__(..) be a class method???
|
||||
var makeRawInstance =
|
||||
module.makeRawInstance =
|
||||
function(context, constructor, ...args){
|
||||
var _mirror_doc =
|
||||
function(func, target){
|
||||
Object.defineProperty(func, 'toString', {
|
||||
value: function(...args){
|
||||
return target.toString(...args) },
|
||||
enumerable: false,
|
||||
})
|
||||
return func }
|
||||
|
||||
var obj =
|
||||
// prototype defines .__new__(..)...
|
||||
constructor.prototype.__new__ instanceof Function ?
|
||||
constructor.prototype.__new__(context, ...args)
|
||||
// callable instance -- prototype is a function...
|
||||
// NOTE: we need to isolate the .prototype from instances...
|
||||
: constructor.prototype instanceof Function ?
|
||||
_mirror_doc(
|
||||
function(){
|
||||
return constructor.prototype.call(obj, this, ...arguments) },
|
||||
constructor.prototype)
|
||||
// callable instance -- prototype defines .__call__(..)...
|
||||
// NOTE: we need to isolate the .__call__ from instances...
|
||||
: constructor.prototype.__call__ instanceof Function ?
|
||||
_mirror_doc(
|
||||
function(){
|
||||
return constructor.prototype.__call__.call(obj, this, ...arguments) },
|
||||
constructor.prototype.__call__)
|
||||
// default object base...
|
||||
: {}
|
||||
|
||||
// link to prototype chain...
|
||||
obj.__proto__ = constructor.prototype
|
||||
Object.defineProperty(obj, 'constructor', {
|
||||
value: constructor,
|
||||
enumerable: false,
|
||||
})
|
||||
|
||||
return obj }
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Make a JavaScrip object constructor...
|
||||
//
|
||||
// Make a constructor with an object prototype...
|
||||
// Constructor(<name>, <proto>)
|
||||
@ -258,11 +322,9 @@ function(root, ...objects){
|
||||
// not reusable, to use the same prototype for multiple objects clone
|
||||
// it via. Object.create(..) or copy it...
|
||||
//
|
||||
// XXX might be a good idea to be able to make an instance without
|
||||
// initializing it...
|
||||
// ...mainly for inheritance.
|
||||
// ...would also be helpful in this case to call all the
|
||||
// constructors in the chain
|
||||
// XXX Q: should the context in .__new__(..) be _constructor or .prototype???
|
||||
// ...currently it's .prototype...
|
||||
// XXX Q: should we add a wrapper to .makeRawInstance(..) as a class method here???
|
||||
var Constructor =
|
||||
module.Constructor =
|
||||
// shorthand...
|
||||
@ -272,61 +334,19 @@ function Constructor(name, a, b){
|
||||
var cls_proto = b == null ? b : a
|
||||
proto = proto || {}
|
||||
|
||||
// mirror doc from target to func...
|
||||
var _mirror = function(func, target){
|
||||
Object.defineProperty(func, 'toString', {
|
||||
value: function(...args){
|
||||
return target.toString(...args) },
|
||||
enumerable: false,
|
||||
})
|
||||
return func }
|
||||
|
||||
// the actual constructor...
|
||||
var _constructor = function Constructor(){
|
||||
// NOTE: the following does the job of the 'new' operator but
|
||||
// with one advantage, we can now pass arbitrary args
|
||||
// in...
|
||||
// This is equivalent to:
|
||||
// return new _constructor(json)
|
||||
var obj =
|
||||
// prototype defines .__new__(..)...
|
||||
// XXX should the context here he _constructor or .prototype (now)???
|
||||
_constructor.prototype.__new__ instanceof Function ?
|
||||
_constructor.prototype.__new__(this, ...arguments)
|
||||
// prototype is a function...
|
||||
// NOTE: we need to isolate the .prototype from instances...
|
||||
: _constructor.prototype instanceof Function ?
|
||||
_mirror(
|
||||
function(){
|
||||
return _constructor.prototype.call(obj, this, ...arguments) },
|
||||
_constructor.prototype)
|
||||
// prototype defines .__call__(..)...
|
||||
// NOTE: we need to isolate the .__call__ from instances...
|
||||
// XXX should this be instanceof Function???
|
||||
: _constructor.prototype.__call__ instanceof Function ?
|
||||
_mirror(
|
||||
function(){
|
||||
return _constructor.prototype.__call__.call(obj, this, ...arguments) },
|
||||
_constructor.prototype.__call__)
|
||||
// default object base...
|
||||
: {}
|
||||
|
||||
// XXX should this be done when .__new__(..) is called???
|
||||
obj.__proto__ = _constructor.prototype
|
||||
Object.defineProperty(obj, 'constructor', {
|
||||
value: _constructor,
|
||||
enumerable: false,
|
||||
})
|
||||
|
||||
// load initial state...
|
||||
var obj = makeRawInstance(this, _constructor, ...arguments)
|
||||
obj.__init__ instanceof Function
|
||||
&& obj.__init__(...arguments)
|
||||
return obj }
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
// just in case the browser refuses to change the name, we'll make it
|
||||
// a different offer ;)
|
||||
_constructor.name = name
|
||||
// just in case the browser refuses to change the name, we'll make
|
||||
// it a different offer ;)
|
||||
_constructor.name == 'Constructor'
|
||||
// NOTE: this eval(..) should not be a risk as its inputs are
|
||||
// static and never infuenced by external inputs...
|
||||
&& eval('_constructor = '+ _constructor
|
||||
.toString()
|
||||
.replace(/Constructor/g, name))
|
||||
@ -347,14 +367,20 @@ function Constructor(name, a, b){
|
||||
.toString()
|
||||
.replace(/[^{]*{/, '{')
|
||||
: '{ .. }'
|
||||
|
||||
return `${this.name}(${args})${normalizeIndent(code)}`
|
||||
},
|
||||
return `${this.name}(${args})${normalizeIndent(code)}` },
|
||||
enumerable: false,
|
||||
})
|
||||
|
||||
_constructor.__proto__ = cls_proto
|
||||
_constructor.prototype = proto
|
||||
// XXX EXPERIMENTAL...
|
||||
// wrapper to makeRawInstance(..)...
|
||||
_constructor.__rawinstance__ = function(...args){
|
||||
return (_constructor.__proto__ || {}).__rawinstance__ ?
|
||||
// XXX revise / test...
|
||||
// XXX should we hardcode cls_proto here???
|
||||
_constructor.__proto__.__rawinstance__.call(this, ...args)
|
||||
: makeRawInstance(this, _constructor, ...args) }
|
||||
Object.defineProperty(_constructor.prototype, 'constructor', {
|
||||
value: _constructor,
|
||||
enumerable: false,
|
||||
@ -365,6 +391,5 @@ function Constructor(name, a, b){
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* vim:set ts=4 sw=4 : */ return module })
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ig-object",
|
||||
"version": "2.2.2",
|
||||
"version": "2.3.0",
|
||||
"description": "",
|
||||
"main": "object.js",
|
||||
"scripts": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user