updated docs...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-11-19 03:51:39 +03:00
parent 8e63fe3577
commit 30e8197e0f
3 changed files with 173 additions and 58 deletions

227
README.md
View File

@ -137,13 +137,18 @@ class B extends A {
- [`parentProperty(..)`](#parentproperty) - [`parentProperty(..)`](#parentproperty)
- [`parentCall(..)`](#parentcall) - [`parentCall(..)`](#parentcall)
- [`parentOf(..)` / `childOf(..)` / `related(..)`](#parentof--childof--related) - [`parentOf(..)` / `childOf(..)` / `related(..)`](#parentof--childof--related)
- [`RawInstance(..)`](#rawinstance)
- [`Constructor(..)` / `C(..)`](#constructor--c)
- [`mixin(..)`](#mixin) - [`mixin(..)`](#mixin)
- [`mixins(..)`](#mixins) - [`mixins(..)`](#mixins)
- [`hasMixin(..)`](#hasmixin) - [`hasMixin(..)`](#hasmixin)
- [`mixout(..)`](#mixout) - [`mixout(..)`](#mixout)
- [`mixinFlat(..)`](#mixinflat) - [`mixinFlat(..)`](#mixinflat)
- [`RawInstance(..)`](#rawinstance) - [`Mixin(..)`](#mixin-1)
- [`Constructor(..)` / `C(..)`](#constructor--c) - [`<mixin>(..)`](#mixin-2)
- [`<mixin>.mode`](#mixinmode)
- [`<mixin>.mixout(..)`](#mixinmixout)
- [`<mixin>.isMixed(..)`](#mixinismixed)
- [Utilities](#utilities) - [Utilities](#utilities)
- [`normalizeIndent(..)` / `normalizeTextIndent(..)` / `doc` / `text`](#normalizeindent--normalizetextindent--doc--text) - [`normalizeIndent(..)` / `normalizeTextIndent(..)` / `doc` / `text`](#normalizeindent--normalizetextindent--doc--text)
- [`deepKeys(..)`](#deepkeys) - [`deepKeys(..)`](#deepkeys)
@ -319,6 +324,8 @@ case.
### Mix-ins ### Mix-ins
<!-- XXX do an example using Mixin(..) -->
Prototype-based mixin... Prototype-based mixin...
```javascript ```javascript
var utilityMixin = { var utilityMixin = {
@ -735,6 +742,77 @@ related(<a>, <b>)
These are similar to `instanceof` but will test if the two objects are in the These are similar to `instanceof` but will test if the two objects are in the
same prototype chain and in case of `parentOf(..)`/`childOf(..)` in what order. same prototype chain and in case of `parentOf(..)`/`childOf(..)` in what order.
### `RawInstance(..)`
Make a raw (un-initialized) instance
```
RawInstance(<context>, <constructor>, ..)
-> <object>
```
`RawInstance(..)` will do the following:
- Create an instance object
- get result of `.__new__(..)` if defined, or
- if prototype is a function or `.__call__(..)` is defined, create a
wrapper function, or
- if constructor's `.__proto__` has a `.__rawinstance__(..)` use it
to create an instance, or
- if constructor's `.__proto__` is a function (constructor) use it
to create an instance, or
- use `{}`.
- Link the object into the prototype chain
_Un-initialized_ means this will not call `.__init__(..)`
`RawInstance(..)` can be called with and without `new`.
### `Constructor(..)` / `C(..)`
Define an object constructor
```
Constructor(<name>)
Constructor(<name>, <prototype>)
Constructor(<name>, <parent-constructor>, <prototype>)
Constructor(<name>, <parent-constructor>, <constructor-mixin>, <prototype>)
Constructor(<name>, <constructor-mixin>, <prototype>)
-> <constructor>
```
`Constructor(..)` essentially does the following:
- Creates a _constructor_ function,
- Sets constructor `.name` and `.toString(..)` for introspection,
- Creates `.__rawinstance__(..)` wrapper to `RawInstance(..)`
- Sets constructor `.__proto__`, `.prototype` and `.prototype.constructor`,
- Mixes in _constructor-mixin_ if given.
The resulting _constructor_ function when called will:
- call constructor's `.__rawinstance__(..)` if defined or `RawInstance(..)`
to create an instance,
- call instance's `.__init__(..)` if present.
Note that `Constructor(<name>, <prototype>)` is intentionally set as default
instead of having the _parent-constructor_ as the last argument, this is
done for two reasons:
- The main cause to inherit from a constructor is to extend it,
- In real code the `Constructor(<name>, <prototype>)` is more common than
empty inheritance.
Shorthand to `Constructor(..)`
```
C(<name>, ..)
-> <constructor>
```
`Constructor(..)` / `C(..)` can be called with and without `new`.
### `mixin(..)` ### `mixin(..)`
_Mixin_ objects into a prototype chain _Mixin_ objects into a prototype chain
@ -816,76 +894,113 @@ Also like `Object.assign(..)` this _will_ overwrite attribute values in
`<base>`. `<base>`.
### `RawInstance(..)` ### `Mixin(..)`
Make a raw (un-initialized) instance Create a mixin wrapper.
``` ```
RawInstance(<context>, <constructor>, ..) Mixin(<name>, <obj>, ..)
-> <object> -> <mixin>
``` ```
`RawInstance(..)` will do the following: This will create a more convenient `<mixin>` object.
- Create an instance object
- get result of `.__new__(..)` if defined, or
- if prototype is a function or `.__call__(..)` is defined, create a
wrapper function, or
- if constructor's `.__proto__` has a `.__rawinstance__(..)` use it
to create an instance, or
- if constructor's `.__proto__` is a function (constructor) use it
to create an instance, or
- use `{}`.
- Link the object into the prototype chain
The following two are the same
```javascript
var mixin = {
// ...
}
_Un-initialized_ means this will not call `.__init__(..)` var obj = mixinFlat({
// ...
}, mixin)
`RawInstance(..)` can be called with and without `new`.
### `Constructor(..)` / `C(..)`
Define an object constructor
``` ```
Constructor(<name>) and
Constructor(<name>, <prototype>) ```javascript
Constructor(<name>, <parent-constructor>, <prototype>) var mixin = Mixin('mixin', {
Constructor(<name>, <parent-constructor>, <constructor-mixin>, <prototype>) // ...
Constructor(<name>, <constructor-mixin>, <prototype>) })
-> <constructor>
var obj = mixin('flat', {
// ...
})
``` ```
`Constructor(..)` essentially does the following: The former approach is better suited for inline mixing in, where one could
- Creates a _constructor_ function, use `Object.assign(..)` while the later is more convenient for working with
- Sets constructor `.name` and `.toString(..)` for introspection, library and reusable _mixin_ object as it is more readable and more centralized.
- Creates `.__rawinstance__(..)` wrapper to `RawInstance(..)`
- Sets constructor `.__proto__`, `.prototype` and `.prototype.constructor`,
- Mixes in _constructor-mixin_ if given.
The resulting _constructor_ function when called will: This also makes combining mixins simpler
- call constructor's `.__rawinstance__(..)` if defined or `RawInstance(..)` ```javascript
to create an instance, var A = Mixin('A', {
- call instance's `.__init__(..)` if present. // ...
})
var B = Mixin('B', {
// ...
})
Note that `Constructor(<name>, <prototype>)` is intentionally set as default // this is a combination of A and B...
instead of having the _parent-constructor_ as the last argument, this is var C = Mixin('C', A, B, {
done for two reasons: // NOTE: this "block" is optional...
- The main cause to inherit from a constructor is to extend it, // ...
- In real code the `Constructor(<name>, <prototype>)` is more common than })
empty inheritance.
Shorthand to `Constructor(..)`
```
C(<name>, ..)
-> <constructor>
``` ```
Note that for multiple mixins used in `Mixin(..)` as well as in
`Constructor(..)` / `C(..)` can be called with and without `new`. [`mixin(..)`](#mixin)/[`mixinFlat(..)`](#mixinflat), mixins from right to
left, e.g. in the above example `B` will overwrite intersecting data in `A`,
... etc.
### `<mixin>(..)`
Mixin into `<target>` as a prototype
```
<mixin>(<target>)
<mixin>('proto', <target>)
-> <target>
```
Mixin into `<target>` as directly (flatly)
```
<mixin>('flat', <target>)
-> <target>
```
These are similar to using [`mixin(..)`](#mixin) or [`mixinFlat(..)`](#mixin)
respectively.
### `<mixin>.mode`
Sets the default mode for `<mixin>(..)`.
Can be:
- `proto`
mix into prototype objects, like [`mixin(..)`](#mixin)
- `flat`
mix into object directly, like [`mixinFlat(..)`](#mixinflat)
### `<mixin>.mixout(..)`
Remove `<mixin>` from `<target>`
```
<mixin>.mixout(<target>)
-> <target>
```
This is the same as [`mixout(..)`](#mixout)
### `<mixin>.isMixed(..)`
Check if `<mixin>` is mixed into `<target>`
```
<mixin>.isMixed(<target>)
-> <bool>
```
This is the same as [`hasMixin(..)`](#hasmixin)
## Utilities ## Utilities

View File

@ -1195,7 +1195,7 @@ Constructor('Mixin', {
__init__: function(name, ...data){ __init__: function(name, ...data){
// NOTE: .defineProperty(..) is used because this is a function // NOTE: .defineProperty(..) is used because this is a function
// and function's .name is not too configurable... // and function's .name is not too configurable...
// XXX do we need to configure this better??? // XXX do we need to configure this prop better???
Object.defineProperty(this, 'name', { value: name }) Object.defineProperty(this, 'name', { value: name })
this.data = mixinFlat({}, this.data = mixinFlat({},
...data.map(function(e){ ...data.map(function(e){

View File

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