mirror of
https://github.com/flynx/object.js.git
synced 2025-12-20 02:11:39 +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
|
This is like `Object.assign(..)` but copies property objects rather than
|
||||||
property values.
|
property values.
|
||||||
|
|
||||||
|
Make a raw instance
|
||||||
|
```
|
||||||
|
makeRawInstance(<context>, <constructor>, ...)
|
||||||
|
-> <object>
|
||||||
|
```
|
||||||
|
|
||||||
Define an object constructor
|
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...
|
// Make a constructor with an object prototype...
|
||||||
// Constructor(<name>, <proto>)
|
// Constructor(<name>, <proto>)
|
||||||
@ -258,11 +322,9 @@ function(root, ...objects){
|
|||||||
// not reusable, to use the same prototype for multiple objects clone
|
// not reusable, to use the same prototype for multiple objects clone
|
||||||
// it via. Object.create(..) or copy it...
|
// it via. Object.create(..) or copy it...
|
||||||
//
|
//
|
||||||
// XXX might be a good idea to be able to make an instance without
|
// XXX Q: should the context in .__new__(..) be _constructor or .prototype???
|
||||||
// initializing it...
|
// ...currently it's .prototype...
|
||||||
// ...mainly for inheritance.
|
// XXX Q: should we add a wrapper to .makeRawInstance(..) as a class method here???
|
||||||
// ...would also be helpful in this case to call all the
|
|
||||||
// constructors in the chain
|
|
||||||
var Constructor =
|
var Constructor =
|
||||||
module.Constructor =
|
module.Constructor =
|
||||||
// shorthand...
|
// shorthand...
|
||||||
@ -272,61 +334,19 @@ function Constructor(name, a, b){
|
|||||||
var cls_proto = b == null ? b : a
|
var cls_proto = b == null ? b : a
|
||||||
proto = proto || {}
|
proto = proto || {}
|
||||||
|
|
||||||
// mirror doc from target to func...
|
// the actual constructor...
|
||||||
var _mirror = function(func, target){
|
|
||||||
Object.defineProperty(func, 'toString', {
|
|
||||||
value: function(...args){
|
|
||||||
return target.toString(...args) },
|
|
||||||
enumerable: false,
|
|
||||||
})
|
|
||||||
return func }
|
|
||||||
|
|
||||||
var _constructor = function Constructor(){
|
var _constructor = function Constructor(){
|
||||||
// NOTE: the following does the job of the 'new' operator but
|
var obj = makeRawInstance(this, _constructor, ...arguments)
|
||||||
// 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...
|
|
||||||
obj.__init__ instanceof Function
|
obj.__init__ instanceof Function
|
||||||
&& obj.__init__(...arguments)
|
&& obj.__init__(...arguments)
|
||||||
|
return obj }
|
||||||
|
|
||||||
return obj
|
_constructor.name = name
|
||||||
}
|
// just in case the browser refuses to change the name, we'll make
|
||||||
|
// it a different offer ;)
|
||||||
// just in case the browser refuses to change the name, we'll make it
|
|
||||||
// a different offer ;)
|
|
||||||
_constructor.name == 'Constructor'
|
_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
|
&& eval('_constructor = '+ _constructor
|
||||||
.toString()
|
.toString()
|
||||||
.replace(/Constructor/g, name))
|
.replace(/Constructor/g, name))
|
||||||
@ -347,14 +367,20 @@ function Constructor(name, a, b){
|
|||||||
.toString()
|
.toString()
|
||||||
.replace(/[^{]*{/, '{')
|
.replace(/[^{]*{/, '{')
|
||||||
: '{ .. }'
|
: '{ .. }'
|
||||||
|
return `${this.name}(${args})${normalizeIndent(code)}` },
|
||||||
return `${this.name}(${args})${normalizeIndent(code)}`
|
|
||||||
},
|
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
_constructor.__proto__ = cls_proto
|
_constructor.__proto__ = cls_proto
|
||||||
_constructor.prototype = 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', {
|
Object.defineProperty(_constructor.prototype, 'constructor', {
|
||||||
value: _constructor,
|
value: _constructor,
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
@ -365,6 +391,5 @@ function Constructor(name, a, b){
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* vim:set ts=4 sw=4 : */ return module })
|
* vim:set ts=4 sw=4 : */ return module })
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ig-object",
|
"name": "ig-object",
|
||||||
"version": "2.2.2",
|
"version": "2.3.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "object.js",
|
"main": "object.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user